Guide · Agentic Frameworks
MCP server CrewAI integration
CrewAI organizes LLM capabilities into teams of agents with defined roles, backstories, and tool sets, then orchestrates them through tasks with a sequential or hierarchical process. MCP servers fit naturally as the tool layer: each MCP server provides a domain-specific set of tools that gets assigned to the agent role best suited to use them — a research agent gets a web search MCP server, a database agent gets a query MCP server. CrewAI's MCPServerAdapter handles the MCP connection and tool translation. The main integration considerations are connection lifecycle management, mapping tools to roles correctly, and monitoring the MCP servers that power your crews — especially for scheduled batch jobs where nobody is watching when the server goes down.
TL;DR
Use MCPServerAdapter (CrewAI v0.105+) to connect to MCP servers. Initialize it as an async context manager, call adapter.tools to get the LangChain-compatible tool list, and pass those to the Agent constructor. Assign tools to agents by role — don't give every agent all tools. Use Process.hierarchical when you need a manager agent to delegate MCP tool-equipped agents. Pre-check MCP server health before scheduled kickoff with AliveMCP so batch jobs fail fast instead of silently wasting your LLM budget.
CrewAI architecture and where MCP fits
A CrewAI application has four core building blocks:
| Building block | Description | MCP role |
|---|---|---|
Agent | An LLM with a role, goal, backstory, and tool set | Receives MCP tools via MCPServerAdapter |
Task | A unit of work assigned to an agent with expected output | Triggers agent tool use including MCP calls |
Crew | A team of agents with tasks and a process type | Orchestrates agents; MCP connections span the crew kickoff |
Process | Sequential or hierarchical execution flow | Determines which agent calls which MCP tools when |
MCP servers are external infrastructure — they sit behind the tool interface and implement the actual work. The MCP server doesn't know it's being called by CrewAI; CrewAI doesn't know (or care) how the tool is implemented. This separation lets you update, replace, or scale MCP servers independently of your crew configuration.
Installing and connecting with MCPServerAdapter
CrewAI's MCP integration requires crewai[tools] >= 0.105:
pip install "crewai[tools]>=0.105" langchain-anthropic
# or with uv:
uv add "crewai[tools]>=0.105" langchain-anthropic
Connect to an MCP server using MCPServerAdapter:
import asyncio
import os
from crewai import Agent, Task, Crew, Process
from crewai_tools import MCPServerAdapter
from mcp import StdioServerParameters
async def run_research_crew():
# HTTP/SSE MCP server
search_params = {
"url": "https://search.internal/mcp",
"transport": "streamable_http",
"headers": {"Authorization": f"Bearer {os.environ['SEARCH_TOKEN']}"},
}
# Stdio MCP server (local package)
calculator_params = StdioServerParameters(
command="npx",
args=["-y", "@acme/calculator-mcp"],
)
async with MCPServerAdapter(search_params) as search_adapter, \
MCPServerAdapter(calculator_params) as calc_adapter:
researcher = Agent(
role="Research Analyst",
goal="Find and summarise the most relevant information on the given topic",
backstory="Expert at web research and source evaluation",
tools=search_adapter.tools, # only search tools
llm="claude-sonnet-4-6",
verbose=False,
)
analyst = Agent(
role="Data Analyst",
goal="Compute metrics and validate numbers from research output",
backstory="Expert at quantitative analysis and statistical validation",
tools=calc_adapter.tools, # only calculator tools
llm="claude-sonnet-4-6",
verbose=False,
)
research_task = Task(
description="Research the current state of MCP server adoption in enterprise environments",
expected_output="A structured summary with key statistics and adoption trends",
agent=researcher,
)
analysis_task = Task(
description="Validate the statistics from the research and compute year-over-year growth rates",
expected_output="A validated metrics table with growth calculations",
agent=analyst,
context=[research_task], # receives researcher output
)
crew = Crew(
agents=[researcher, analyst],
tasks=[research_task, analysis_task],
process=Process.sequential,
)
result = await crew.kickoff_async()
return result.raw
asyncio.run(run_research_crew())
Role-based tool assignment
The most common mistake in CrewAI + MCP integration is giving every agent all available tools. An agent given 20 tools performs worse than one given the 3–5 tools it actually needs: LLMs degrade in tool selection accuracy as the tool count grows, and unrelated tools introduce noise in the agent's reasoning about which tool to call next.
Assign tools by role — each MCP server provides tools for one domain, and those tools go to the agent whose role is in that domain:
| Agent role | MCP server(s) | Example tools |
|---|---|---|
| Researcher | Web search, arXiv | search_web, fetch_paper, get_citations |
| Database Analyst | Analytics DB | run_query, list_tables, get_schema |
| Code Writer | Code execution, GitHub | execute_code, create_file, run_tests |
| Report Writer | Document storage | create_document, upload_file |
In a Process.hierarchical crew, the manager agent coordinates without executing tasks directly. Give the manager no tools or a minimal set (e.g., a delegate tool) and concentrate capabilities in the worker agents.
Sequential vs hierarchical process
CrewAI's Process.sequential runs tasks one after another — each task's output becomes available as context to subsequent tasks. Process.hierarchical adds a manager LLM that dynamically assigns tasks to agents based on the crew's progress. Both patterns work with MCP tools:
# Sequential: tasks run in order, researcher output feeds analyst
crew_sequential = Crew(
agents=[researcher, analyst],
tasks=[research_task, analysis_task],
process=Process.sequential,
)
# Hierarchical: manager decides which agent to use next
crew_hierarchical = Crew(
agents=[researcher, analyst, writer],
tasks=[project_task], # single high-level task; manager decomposes it
process=Process.hierarchical,
manager_llm="claude-opus-4-7", # use a stronger model as manager
)
In hierarchical mode, the manager LLM's context grows with each subtask delegation. Keep individual task descriptions concise so the manager prompt stays within the model's context window over a long-running crew execution.
Batch scheduling and pre-flight health checks
CrewAI is often used for scheduled batch workflows: nightly research reports, weekly competitive analysis, daily data summaries. These run unattended, which means a dead MCP server at job startup fails silently — the crew kickoff raises a connection error that lands in a log file nobody checks until the morning report is missing.
import httpx
from datetime import datetime
async def preflight_check(servers: list[dict]) -> None:
"""Verify all MCP servers are reachable before starting an expensive crew run."""
async with httpx.AsyncClient(timeout=5.0) as http:
for server in servers:
try:
resp = await http.post(
server["url"],
json={"jsonrpc": "2.0", "method": "initialize",
"params": {"protocolVersion": "2025-03-26", "capabilities": {},
"clientInfo": {"name": "preflight", "version": "1"}}, "id": 1},
headers=server.get("headers", {}),
)
if resp.status_code != 200:
raise RuntimeError(
f"MCP server {server['url']} returned HTTP {resp.status_code} — aborting crew run"
)
except httpx.ConnectError as exc:
raise RuntimeError(f"Cannot reach MCP server {server['url']}: {exc}") from exc
async def run_nightly_crew():
await preflight_check([
{"url": "https://search.internal/mcp", "headers": {"Authorization": f"Bearer {os.environ['SEARCH_TOKEN']}"}},
{"url": "https://db.internal/mcp", "headers": {"Authorization": f"Bearer {os.environ['DB_TOKEN']}"}},
])
# only proceed if all servers passed
async with MCPServerAdapter(...) as adapter:
...
For production deployments, delegate the pre-flight monitoring to AliveMCP — it runs continuous probes every minute and alerts when any server goes down, not just at job start time. Your batch job can then check AliveMCP's status API instead of running raw MCP probes inline.
Error handling in CrewAI with MCP tools
When an MCP tool returns isError: true, MCPServerAdapter raises a ToolException. CrewAI's agent executor injects the error message back into the conversation. The agent's LLM sees the error and typically retries with different arguments or uses a different approach.
Configure max_iter on the agent to cap retry loops:
researcher = Agent(
role="Research Analyst",
goal="...",
backstory="...",
tools=search_adapter.tools,
llm="claude-sonnet-4-6",
max_iter=5, # stop after 5 tool call iterations
max_retry_limit=2, # retry failed tool calls up to 2 times
)
Without max_iter, an agent that gets consistent MCP errors can loop indefinitely, consuming tokens until the context window fills. Five iterations is a reasonable ceiling for most research tasks; reduce to 3 for tools with high per-call cost.
Monitoring MCP servers that power CrewAI
CrewAI is particularly vulnerable to MCP server failures in two scenarios. First, scheduled batch jobs: the crew runs at a fixed time, the MCP server is down, the job logs an error and exits — no alert fires, no human notices, the morning report is missing. Second, long-running crews: a crew running for 20 minutes completes 15 of 20 tasks successfully, then fails at task 16 because the MCP server restarted — all prior work is discarded unless the crew supports partial output recovery.
AliveMCP monitors each MCP server endpoint independently, 24/7, and sends alerts the moment a server fails — not when the next scheduled job discovers the failure. Configure one AliveMCP monitor per MCP server with a webhook alert that fires to your on-call channel. Your crew's reliability is now bounded by the reliability of its MCP servers; AliveMCP makes that boundary visible.
Frequently asked questions
What version of CrewAI added MCPServerAdapter?
MCPServerAdapter was added in CrewAI v0.105. Earlier versions require manual wiring: implement a BaseTool subclass that calls your MCP server via httpx and pass instances to the agent. This manual approach works but requires you to re-implement schema loading and error propagation that MCPServerAdapter handles automatically.
Can I use the same MCPServerAdapter instance for multiple agents?
Yes. One MCPServerAdapter instance represents one MCP server connection, and its .tools list can be passed to multiple agents. All agents sharing the adapter use the same underlying connection — this is efficient for servers that support concurrent requests. If you need agent-level connection isolation (e.g., different auth per agent), create separate adapter instances with different headers.
How do I pass user identity from CrewAI to MCP tool handlers?
Pass user identity in the MCP server connection headers ("X-User-Id": user_id), not in tool arguments. Tool arguments flow through the LLM and cannot be trusted as auth — a prompt injection attack could override an userId argument. Connection-level headers are set at adapter initialization time and cannot be overridden by the LLM. In the MCP server, extract the identity from request headers in the initialize handler and propagate it via AsyncLocalStorage context propagation.
Does CrewAI support async MCP servers?
Yes. Use crew.kickoff_async() for fully async execution. MCPServerAdapter is async-native. Sync execution via crew.kickoff() wraps the async calls in asyncio.run() internally. For production services (FastAPI, async worker), always use kickoff_async() to avoid blocking the event loop.
My CrewAI crew runs for 30 minutes. How do I handle MCP server reconnection if it restarts mid-run?
Configure retry logic in your MCP server HTTP client, or use a connection wrapper that automatically reconnects on transport errors. In the MCP adapter, set reasonable timeouts ("timeout": 30 in the server config) so transient network hiccups don't permanently fail the connection. For MCP server restarts, the cleanest approach is to ensure MCP servers perform zero-downtime deployments so mid-crew restarts don't happen at all. AliveMCP probes catch unexpected restarts before your crew discovers them.
Further reading
- MCP server LangChain integration — using MCP tools in LangChain agents
- MCP server LangGraph integration — stateful agents with MCP tools
- MCP server AutoGen integration — Microsoft AutoGen with MCP tools
- MCP server authentication — OAuth, JWT, and API key patterns
- MCP server alerting — notifications when your server goes down
- AliveMCP — continuous protocol monitoring for MCP servers