CrewAI
The CrewAI provider turns Composio tools into CrewAI BaseTool objects that execute themselves. You connect an account, fetch the tools, pass them to an Agent, and CrewAI runs the task end to end.
Install
uv add composio composio_crewai crewaiConfigure API Keys
Set COMPOSIO_API_KEY with your API key from Settings and OPENAI_API_KEY with your OpenAI API key.
COMPOSIO_API_KEY=xxxxxxxxx
OPENAI_API_KEY=xxxxxxxxxCreate session and run
from crewai import Agent, Crew, Task
from composio import Composio
from composio_crewai import CrewAIProvider
composio = Composio(provider=CrewAIProvider())
# Create a session for your user
session = composio.create(user_id="user_123")
tools = session.tools()
agent = Agent(
role="Email Agent",
goal="Send emails on behalf of the user",
backstory="You are an AI agent that sends emails using Gmail.",
tools=tools,
llm="gpt-5.2",
)
task = Task(
description="Send an email to john@example.com with the subject 'Hello' and body 'Hello from Composio!'",
agent=agent,
expected_output="Confirmation that the email was sent",
)
crew = Crew(agents=[agent], tasks=[task])
result = crew.kickoff()
print(result)Provider specifics
Each Composio tool becomes a CrewAI BaseTool whose args_schema is built from the tool's input schema, so CrewAI validates arguments before running anything.
Object arguments that declare no properties accept and preserve arbitrary nested keys. For objects that declare named properties, undeclared keys are rejected unless the schema allows them with additionalProperties. Schemas that use patternProperties or schema-valued additionalProperties also validate dynamic keys before execution.
The provider preserves whether an optional argument was omitted or explicitly set to None. By default, declared defaults are included, while optional arguments without defaults stay absent. Set schema_config={"skip_defaults": True} when creating the provider to leave declared defaults absent too.
When validation fails, the tool does not raise. It returns a structured result instead:
{"successful": False, "error": "<validation message>", "data": None}Check successful in your task output rather than wrapping calls in try/except.
Next
What is a session?
How sessions scope users, tools, and auth, and how to reuse them across requests.