Skip to content

CrewAI

Available · pip install "agent-adapter[crewai]" · crewai>=1.15,<2 · own environment

Every registry tool becomes a CrewAI BaseTool with args_schema=spec.args_model. _arun runs through the executor; _run (what CrewAI agents call) goes through run_sync, so it works inside a running event loop too. CrewAI is imported only when you export a tool.

Install CrewAI in its own environment

crewai 1.15 pins pydantic<2.13, mcp<2 and openai<3, so it cannot share an environment with the mcp or openai-agents extras. It needs Python < 3.14.

Functions

Function (agent_adapter.integrations.crewai) Returns
crewai_tool(spec, *, executor=None) one BaseTool
crewai_tools(registry, *, executor=None) one per tool whose targets include crewai
INTEGRATION the integration object

executor=None uses the default executor.

Run

from agent_adapter.integrations.crewai import crewai_tools

tools = crewai_tools(registry, executor=Executor())  # Agent(role=..., tools=tools)
tool = tools[0]
value = await tool.arun(item="book")  # async path
sync_value = tool.run(item="book", region="eu")  # sync path, even inside a running loop
flowchart LR
  REG[("Registry")] --> BT["BaseTool<br/>args_schema = args_model"]
  BT -- "run(**kw): validates, then _run" --> RS["run_sync"] --> EX["Executor.run_spec"]
  BT -- "arun(**kw): validates, then _arun" --> EX

Behaviour

Topic Rule
Description the tool's own; CrewAI builds its prompt text in formatted_description
Arguments CrewAI validates against args_schema first and passes the dumped model; the executor validates again
Result cache off (cache_function always False), so hooks, guards and approval run on every call
Approval CrewAI has no gate of its own: the executor's approval port decides and applies a decision's edited_args
Ports use one that answers in the call (CallbackApproval, AutoApprove, AutoDeny); DeferredApproval cannot resume here (no native call id, and ApprovalPending does not pause the crew)
Ids no native call id: ctx.call_id is a fresh call_… id

Errors to expect

Case What you get
arguments fail args_schema ValueError("Tool '<name>' arguments validation failed: …") from CrewAI
ToolError, ApprovalDenied, GuardrailBlocked, RunLimitExceeded the result {"error": {"kind", "message"}}
any other error (ToolTimeout, ToolFailed, ...) raised from run / arun
asyncio.CancelledError propagates from arun

Inside a crew, CrewAI's tool runner catches an exception from a tool (including ApprovalPending, ToolTimeout, ToolFailed), counts it as a tool error on the task and gives the agent the error text; the task goes on (its tool_failure_policy decides whether a reported failure aborts).