Back to AI App Dev Series

CrewAI SDK Track Part 8: MCP Integration

May 24, 2026 Wasil Zafar 40 min read

Integrate Model Context Protocol servers with CrewAI — the simple DSL syntax with the mcps field, Stdio transport for local servers, SSE for real-time streaming, Streamable HTTP for remote servers, connecting to multiple MCP servers, and security best practices.

Table of Contents

  1. MCP in CrewAI
  2. DSL Integration (Recommended)
  3. Transport Mechanisms
  4. Connecting to Multiple Servers
  5. MCP Security Considerations
What You’ll Learn: MCP (Model Context Protocol) lets your CrewAI agents connect to any MCP-compatible server — gaining tools, resources, and prompts without writing custom integration code. CrewAI’s MCP support uses a simple DSL syntax: just add servers to the agent’s mcps field. Think of it like plugging in peripherals: the MCP server advertises its capabilities, and your agent can use them immediately.

1. MCP in CrewAI

The Model Context Protocol (MCP) is an open standard that allows AI agents to connect to external tools and data sources through a unified interface. CrewAI’s MCP integration lets your agents access any MCP-compatible server — from file systems and databases to custom enterprise services — without writing tool-specific code.

Why MCP? Instead of writing a custom CrewAI tool for every service, connect to existing MCP servers. The ecosystem provides 1000+ pre-built servers for common services (GitHub, Slack, PostgreSQL, file systems, etc.), and you can build your own for proprietary systems.

1.1 Architecture Overview

The flow is: Agent → MCPServerAdapter → MCP Server → External Service. CrewAI’s adapter translates MCP tool definitions into native CrewAI tools automatically.

from crewai import Agent, Task, Crew
from crewai.tools import MCPServerAdapter

# Basic MCP connection — connects to a local file system server
mcp_server = MCPServerAdapter(
    server_params={
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-filesystem", "./workspace"]
    }
)

# Agent automatically discovers all tools from the MCP server
file_agent = Agent(
    role="File Manager",
    goal="Manage and organize workspace files efficiently",
    backstory="Expert file system operator",
    tools=mcp_server.tools,  # Auto-discovered tools from MCP
    verbose=True
)

task = Task(
    description="List all Python files in the workspace and summarize their purposes",
    expected_output="A list of .py files with brief descriptions",
    agent=file_agent
)

crew = Crew(agents=[file_agent], tasks=[task])
result = crew.kickoff()
print(result.raw)

1.2 When to Use MCP vs Native Tools

Use MCP WhenUse Native Tools When
Pre-built MCP server exists for the serviceYou need fine-grained control over tool behavior
You want zero-code tool integrationPerformance is critical (no protocol overhead)
Multiple agents need the same external serviceTool requires complex state management
You’re connecting to enterprise/proprietary systemsSimple utility functions (math, formatting)

2. DSL Integration (Recommended)

The simplest way to connect MCP servers is via CrewAI’s DSL — just add an mcps field to your agent definition. This handles connection lifecycle, tool discovery, and cleanup automatically.

2.1 Agent with MCP DSL

from crewai import Agent, Task, Crew

# DSL approach — simplest MCP integration
researcher = Agent(
    role="Research Analyst",
    goal="Gather information from multiple sources",
    backstory="Expert researcher with access to various data sources",
    mcps=[
        {
            "command": "npx",
            "args": ["-y", "@modelcontextprotocol/server-filesystem", "./data"]
        },
        {
            "url": "http://localhost:3001/sse",
            "transport": "sse"
        }
    ],
    verbose=True
)

task = Task(
    description="Read the research brief from ./data/brief.txt and gather supplementary information",
    expected_output="Comprehensive research report combining file data and web sources",
    agent=researcher
)

crew = Crew(agents=[researcher], tasks=[task])
result = crew.kickoff()
print(result.raw)
DSL Benefits: (1) Automatic tool discovery from MCP server manifests. (2) Connection lifecycle managed by CrewAI. (3) Clean syntax that integrates with YAML crew definitions. (4) No manual MCPServerAdapter instantiation needed.

3. Transport Mechanisms

MCP supports three transport protocols. Choose based on your server deployment model:

3.1 Stdio Transport (Local Processes)

Best for local MCP servers that run as child processes. Communication happens via stdin/stdout:

from crewai import Agent, Task, Crew
from crewai.tools import MCPServerAdapter

# Stdio: spawn a local process (e.g., filesystem server)
filesystem_mcp = MCPServerAdapter(
    server_params={
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"]
    }
)

# Stdio: Python-based MCP server
python_mcp = MCPServerAdapter(
    server_params={
        "command": "python",
        "args": ["-m", "my_mcp_server"],
        "env": {"DATABASE_URL": "postgresql://localhost/mydb"}
    }
)

agent = Agent(
    role="Developer Assistant",
    goal="Help manage project files and database operations",
    backstory="Full-stack developer assistant",
    tools=filesystem_mcp.tools + python_mcp.tools,
    verbose=True
)

task = Task(
    description="List the project structure and check database connectivity",
    expected_output="Project file tree and database status",
    agent=agent
)

crew = Crew(agents=[agent], tasks=[task])
result = crew.kickoff()
print(result.raw)

3.2 SSE Transport (Server-Sent Events)

For MCP servers running as persistent HTTP services with real-time streaming:

from crewai import Agent, Task, Crew
from crewai.tools import MCPServerAdapter

# SSE: connect to a running MCP server via Server-Sent Events
sse_mcp = MCPServerAdapter(
    server_params={
        "url": "http://localhost:8080/sse",
        "transport": "sse"
    }
)

# SSE with authentication headers
auth_sse_mcp = MCPServerAdapter(
    server_params={
        "url": "https://mcp.example.com/sse",
        "transport": "sse",
        "headers": {
            "Authorization": "Bearer your-api-token"
        }
    }
)

agent = Agent(
    role="Data Analyst",
    goal="Query real-time data streams for analysis",
    backstory="Real-time data specialist",
    tools=sse_mcp.tools,
    verbose=True
)

task = Task(
    description="Fetch the latest metrics from the streaming data source",
    expected_output="Current metrics summary with trends",
    agent=agent
)

crew = Crew(agents=[agent], tasks=[task])
result = crew.kickoff()
print(result.raw)

3.3 Streamable HTTP Transport

The most flexible transport — supports both request/response and streaming over standard HTTP:

from crewai import Agent, Task, Crew
from crewai.tools import MCPServerAdapter

# Streamable HTTP: modern flexible transport
http_mcp = MCPServerAdapter(
    server_params={
        "url": "https://mcp-api.example.com/mcp",
        "transport": "streamable-http",
        "headers": {
            "Authorization": "Bearer your-api-token",
            "X-Client-ID": "crewai-production"
        }
    }
)

agent = Agent(
    role="Enterprise Agent",
    goal="Interface with enterprise systems via MCP",
    backstory="Enterprise integration specialist",
    tools=http_mcp.tools,
    verbose=True
)

task = Task(
    description="Query the enterprise CRM for top accounts and their recent activities",
    expected_output="Top 5 accounts with recent interaction summary",
    agent=agent
)

crew = Crew(agents=[agent], tasks=[task])
result = crew.kickoff()
print(result.raw)
Real-World Application

Enterprise Integration Hub

A consulting firm built their own MCP servers for internal systems (CRM, project management, time tracking) and connected them to CrewAI agents. Consultants ask “What projects am I assigned to and how many hours have I logged this week?” and the agent queries across all systems via MCP. Result: eliminated 30 minutes/day of context-switching between tools.

MCP ServersEnterprise Integration

4. Connecting to Multiple Servers

Real-world agents often need tools from multiple MCP servers. CrewAI supports aggregating tools from several servers into a single agent.

4.1 Multi-Server Agent

from crewai import Agent, Task, Crew
from crewai.tools import MCPServerAdapter

# Server 1: File system access
fs_server = MCPServerAdapter(
    server_params={
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-filesystem", "./workspace"]
    }
)

# Server 2: GitHub integration
github_server = MCPServerAdapter(
    server_params={
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-github"],
        "env": {"GITHUB_TOKEN": "ghp_your_token_here"}
    }
)

# Server 3: Database access
db_server = MCPServerAdapter(
    server_params={
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-postgres"],
        "env": {"DATABASE_URL": "postgresql://localhost/app"}
    }
)

# Combine tools from all servers
all_tools = fs_server.tools + github_server.tools + db_server.tools

# Agent with access to all three servers
fullstack_agent = Agent(
    role="Full-Stack Developer",
    goal="Manage code, files, and database for the project",
    backstory="""Senior developer who coordinates across file system,
    version control, and database layers.""",
    tools=all_tools,
    verbose=True
)

task = Task(
    description="""Perform a code review workflow:
    1. List open PRs on the repository
    2. Read the changed files from the filesystem
    3. Check if database migrations are needed
    4. Provide a summary with recommendations""",
    expected_output="Code review summary with actionable recommendations",
    agent=fullstack_agent
)

crew = Crew(agents=[fullstack_agent], tasks=[task])
result = crew.kickoff()
print(result.raw)

5. MCP Security Considerations

MCP servers can access sensitive systems. Follow these security practices to protect your infrastructure.

5.1 Secure MCP Configuration

import os
from crewai import Agent, Task, Crew
from crewai.tools import MCPServerAdapter

# NEVER hardcode secrets — use environment variables
github_token = os.environ.get("GITHUB_TOKEN")
db_url = os.environ.get("DATABASE_URL")

if not github_token:
    raise ValueError("GITHUB_TOKEN environment variable required")

# Secure Stdio server with environment-injected secrets
secure_github = MCPServerAdapter(
    server_params={
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-github"],
        "env": {"GITHUB_TOKEN": github_token}
    }
)

# Secure HTTP server with proper auth headers
secure_api = MCPServerAdapter(
    server_params={
        "url": "https://internal-mcp.company.com/mcp",
        "transport": "streamable-http",
        "headers": {
            "Authorization": f"Bearer {os.environ.get('MCP_API_KEY', '')}",
            "X-Request-Source": "crewai-agent"
        }
    }
)

# Agent with security-conscious configuration
secure_agent = Agent(
    role="Security-Aware Developer",
    goal="Perform tasks while following security best practices",
    backstory="Developer with strong security awareness",
    tools=secure_github.tools + secure_api.tools,
    max_iter=10,  # Limit iterations to prevent runaway
    verbose=True
)

task = Task(
    description="Check repository security alerts and summarize critical issues",
    expected_output="Security alert summary with severity levels",
    agent=secure_agent
)

crew = Crew(agents=[secure_agent], tasks=[task])
result = crew.kickoff()
print(result.raw)
Security Checklist: (1) Never hardcode tokens or API keys. (2) Use environment variables or secret managers. (3) Restrict MCP server file system access to specific directories. (4) Set max_iter on agents to prevent infinite loops. (5) Use HTTPS for all remote MCP connections. (6) Audit MCP server tool permissions before granting to agents.
Try It Yourself: Connect a CrewAI agent to 2 MCP servers: (1) a filesystem server (for reading project files), (2) the GitHub MCP server (for searching repos). Build a crew that: reads your local project structure, searches GitHub for similar open-source projects, and writes a comparison report. Verify tools from both servers appear in the agent’s available tools.

Next in the CrewAI SDK Track

In Part 9: Knowledge, Memory & Files, we’ll add knowledge from PDFs, CSVs, and URLs, configure short-term, long-term, and entity memory systems, handle file I/O, and train agents for improved performance.