CrewAI integration for the Model Context Protocol (MCP)
Project description
crewai-mcp-toolbox: Seamless MCP Integration for CrewAI Agents
Unlock the power of the Model Context Protocol (MCP) directly within your CrewAI agents.
crewai-mcp-toolbox provides a robust and developer-friendly bridge between the CrewAI framework and any compliant MCP server communicating via stdio. It automatically discovers tools exposed by an MCP server, converts them into type-safe CrewAI BaseTool instances, and reliably manages the underlying server process lifecycle for you.
The Problem: Integrating MCP Servers Can Be Tricky
The Model Context Protocol standardizes how AI models interact with external tools and data sources. While powerful, integrating an MCP server into an agent framework like CrewAI often involves repetitive and error-prone tasks:
- Manual Process Management: Starting and stopping the MCP server process reliably alongside your agent application.
- Boilerplate Communication: Writing code to handle the
stdiocommunication, request/response cycles, and error handling defined by the MCP specification. - Tool Discovery & Wrapping: Manually fetching the list of tools from the server and writing wrapper classes for each one to make them compatible with CrewAI's
BaseTool. - Argument Handling: Ensuring arguments passed from the agent are correctly formatted and validated against the MCP tool's schema.
- Reliability: Monitoring the MCP server process and handling potential crashes or hangs gracefully.
Why crewai-mcp-toolbox? Robustness and Developer Experience
crewai-mcp-toolbox tackles these challenges head-on, offering more than just a simple wrapper:
- Reliable Lifecycle via Dedicated Worker: At its core,
crewai-mcp-toolboxuses a dedicated background worker thread (MCPWorkerThread) to isolate and manage the MCP server's lifecycle and communication. This ensures the server starts correctly, runs reliably in the background, and is terminated cleanly when your application exits or the context manager scope is left. - Proven STDIO Process Control: For
stdio-based servers, the worker thread currently utilizes Python's robustasyncio.create_subprocess_execto directly manage the server process. While leveraging native library clients likemcp.client.stdio.stdio_clientwas explored, this direct management approach proved more reliable across different server types during testing (likeuvx-based servers), ensuring compatibility and preventing hangs observed with the library client in specific scenarios. - Dynamic & Typed Tools: Automatically generates Pydantic models from the MCP server's
inputSchemafor each tool. This provides type hinting, validation, and seamless integration with CrewAI's argument handling, significantly reducing runtime errors. - Effortless Integration: The
MCPToolSetacts as a simple context manager (async with), abstracting away the complexities of process management, threading, and protocol handling. Get a list of ready-to-use CrewAI tools with just a few lines of code. - Production-Ready Design: Built with explicit error handling, configurable timeouts, concurrent request management via futures, and basic health checking in mind.
Key Features
- Dynamic Tool Creation: Automatically discovers tools from any MCP server via
stdio. - Managed Server Lifecycle: Starts and reliably stops the configured MCP server process using
MCPToolSetas a context manager, managed by the background worker. - Direct STDIO Process Management: Reliably starts/stops
stdioservers usingasyncioprimitives within the worker thread for proven compatibility. - Protocol Layer via
mcpLibrary: Uses the coremcp.ClientSessionfor handling MCP protocol message details once the stdio streams are established. - Robust Background Worker: Manages communication with the MCP server in a separate thread, handling requests, responses, and errors asynchronously.
- Health Monitoring: Includes basic health checking of the underlying MCP server connection status.
- Typed Arguments: Generates Pydantic models for tool arguments based on the server's schema, providing validation and type safety.
- Simple
async withInterface: Easily integrate MCP tools into your async CrewAI applications. - Flexible Configuration: Supports launching MCP servers via
npxfor common types (likeserver-filesystem) or by specifying a custom command and arguments. - Configurable Timeouts: Control timeouts for server startup, tool execution, and individual MCP calls.
- STDIO Focus: Current implementation is focused on and tested with
stdio-based MCP servers. (SSE support is planned for future versions.)
Installation
# Create and activate a virtual environment (recommended)
python -m venv .venv
source .venv/bin/activate # or .\.venv\Scripts\activate on Windows
# Install the toolbox
pip install crewai-mcp-toolbox
# Ensure you have necessary MCP server dependencies installed
# e.g., for server-filesystem or other Node.js servers:
# npm install -g npx
# e.g., for uvx based servers:
# pip install uvx build # or equivalent uv/pip install build uvx
Quick Start
Integrate MCP tools into your CrewAI agent with minimal setup:
import asyncio
from crewai import Agent, Task, Crew
from crewai_mcp_toolbox import MCPToolSet
async def main():
# Example 1: Using a filesystem server (requires Node.js/npx)
# This will start 'npx @modelcontextprotocol/server-filesystem ./my_mcp_data'
# The directory will be created if it doesn't exist.
print("Starting Filesystem MCP Server...")
async with MCPToolSet(directory_path="./my_mcp_data") as filesystem_tools:
print(f"Filesystem Tools Found: {[tool.name for tool in filesystem_tools]}")
if not filesystem_tools:
print("Warning: No filesystem tools discovered. Ensure server started correctly.")
return # Exit if no tools found
# Example Agent using these tools (add your LLM details)
# fs_agent = Agent(...)
# task = Task(...)
# crew = Crew(...)
# result = await crew.kickoff_async()
# print("Filesystem Crew Result:", result)
print("-" * 20)
print("Filesystem MCP Server Stopped.")
# Example 2: Using a custom command (e.g., a Python-based MCP server)
# Assumes 'uvx my-custom-mcp-server' starts an MCP server
print("Starting Custom MCP Server...")
# Ensure 'my-custom-mcp-server' is runnable via 'uvx' in your environment
try:
async with MCPToolSet(command="uvx", args=["my-custom-mcp-server"]) as custom_tools:
print(f"Custom Tools Found: {[tool.name for tool in custom_tools]}")
if not custom_tools:
print("Warning: No custom tools discovered. Ensure server command is correct and functional.")
return # Exit if no tools found
# Example Agent using these tools (add your LLM details)
# custom_agent = Agent(...)
# task = Task(...)
# crew = Crew(...)
# result = await crew.kickoff_async()
# print("Custom Crew Result:", result)
except FileNotFoundError:
print("Error: 'uvx' command not found. Make sure uvx is installed and in your PATH.")
except Exception as e:
print(f"Error running custom server: {e}") # Catch other potential errors
print("-" * 20)
print("Custom MCP Server Stopped (or failed to start).")
if __name__ == "__main__":
# Basic check if main can run
try:
asyncio.run(main())
except Exception as e:
print(f"An error occurred: {e}")
How It Works
- MCPToolSet: The main entry point. Acts as an async context manager. Takes configuration (directory_path or command/args) for the STDIO MCP server.
- MCPWorkerThread: A background thread started by MCPToolSet.
- For STDIO, it uses asyncio.create_subprocess_exec to launch the MCP server subprocess directly.
- It captures the stdin, stdout, and stderr streams of the subprocess.
- It establishes an mcp.ClientSession using the captured stdout (as reader) and stdin (as writer).
- It handles the MCP protocol communication (initialize, list_tools, call_tool) via the ClientSession.
- It monitors connection health via list_tools.
- It ensures the subprocess is terminated when the context manager exits or cleanup() is called.
- MCPToolFactory: Used internally by MCPToolSet. When the worker connects and lists tools, the factory dynamically creates CrewAI BaseTool subclasses for each MCP tool, generating a Pydantic args_schema from the server's inputSchema. Each created tool holds a reference to the worker for execution.
- Execution: When an agent calls a tool's _run method, the call is validated against the Pydantic schema, submitted to the MCPWorkerThread, executed over the MCP connection via ClientSession.call_tool, and the processed result is returned.
Configuration
You can customize timeouts by passing a config dictionary during MCPToolSet initialization:
config = {
"worker_startup_timeout": 60.0, # Default: 60s
"tool_execution_timeout": 120.0, # Default: 90s (for the CrewAI tool call wrapper)
"batch_execution_timeout": 180.0, # Default: 180s (for batch_execute method)
"per_call_timeout": 45.0, # Default: 60s (for the underlying MCP ClientSession.call_tool)
"health_check_interval": 15.0 # Default: 10s
}
`health_check_interval` controls how frequently the worker verifies the MCP
server connection. Lower values detect failures sooner but may increase
overhead.
# Make sure the directory exists or the command is valid
try:
async with MCPToolSet(directory_path="./data", config=config) as tools:
print("Tools with custom config:", [t.name for t in tools])
# ... use tools ...
except Exception as e:
print(f"Failed to initialize MCPToolSet with custom config: {e}")
Testing
Tests are located in the tests directory and use pytest. Fixtures in tests/conftest.py handle setting up different MCP server types (Docker, Chroma, Everything Server) via STDIO.
To run tests:
# Install testing requirements (ensure you have pytest, pytest-asyncio etc.)
# Example: pip install -e .[dev] or pip install -r requirements-dev.txt
# Run tests from the project root directory
pytest tests/
Note: Some tests may require external dependencies like Docker, Node.js (npx), or specific Python packages (uvx, chroma-mcp). The 'everything' server test fixture clones and builds an external repository.
Contributing
Contributions are welcome! Please fork the repository, create a feature branch, make your changes, add tests, and submit a pull request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file crewai_mcp_toolbox-0.1.0.tar.gz.
File metadata
- Download URL: crewai_mcp_toolbox-0.1.0.tar.gz
- Upload date:
- Size: 33.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9996fdd084c5ff5b81b5070b7d1d80697a66ea49d59cbe47392b592b86286c01
|
|
| MD5 |
06b4ec09bac10a99fbf084721cc22c11
|
|
| BLAKE2b-256 |
253e2ff161185d38600d2d49cc96964952922f90b16eb12eeed0ba714f709a92
|
File details
Details for the file crewai_mcp_toolbox-0.1.0-py3-none-any.whl.
File metadata
- Download URL: crewai_mcp_toolbox-0.1.0-py3-none-any.whl
- Upload date:
- Size: 27.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
11e2173771ef14e4668abc662a2edbcea9b92acd7464efd1152d1e16dad6ca81
|
|
| MD5 |
b06d84dcbc068d502634b129ba5a57ed
|
|
| BLAKE2b-256 |
cc5dd22d4da62629e726da47cda8f482e5ed5a43428cec85288eebe4e6e9f84a
|