MCP
The MCP plugin enables Daita agents to connect to any Model Context Protocol server and autonomously use their tools via LLM function calling. MCP is Anthropic's open standard for connecting AI systems to external data sources and tools.
#Overview
The MCP integration allows agents to discover and use tools from external MCP servers without manual configuration. When you attach an MCP server to an agent, the agent automatically:
- Connects to the MCP server via stdio transport
- Discovers all available tools from the server
- Converts MCP tools to the agent's unified tool format
- Routes tool calls to the appropriate MCP server
- Manages connection lifecycle and error handling
Key Features:
- Zero-configuration tool discovery from MCP servers
- Multiple simultaneous MCP server connections
- Automatic tool registration in agent tool registry
- Thread-safe concurrent tool execution
- Built-in connection pooling and lifecycle management
- Compatible with all official MCP servers
#Quick Start
from daita import Agent
from daita.plugins import mcp
# Agent with filesystem MCP server
agent = Agent(
name="file_analyzer",
mcp=mcp.server(
command="uvx",
args=["mcp-server-filesystem", "/data"]
)
)
await agent.start()
# Agent autonomously discovers and uses filesystem tools
result = await agent.run("Read report.csv and calculate totals")#MCP Server Configuration
#Single Server
Connect to a single MCP server using the mcp.server() factory function:
from daita import Agent
from daita.plugins import mcp
# Filesystem server
agent = Agent(
name="file_agent",
mcp=mcp.server(
command="uvx",
args=["mcp-server-filesystem", "/data"]
)
)
# GitHub server with authentication
agent = Agent(
name="github_agent",
mcp=mcp.server(
command="npx",
args=["-y", "@modelcontextprotocol/server-github"],
env={"GITHUB_TOKEN": "ghp_your_token"}
)
)#Multiple Servers
Connect to multiple MCP servers simultaneously:
from daita import Agent
from daita.plugins import mcp
import os
agent = Agent(
name="multi_tool_agent",
mcp=[
# Filesystem access
mcp.server(
command="uvx",
args=["mcp-server-filesystem", "/data"],
name="filesystem"
),
# GitHub integration
mcp.server(
command="npx",
args=["-y", "@modelcontextprotocol/server-github"],
env={"GITHUB_TOKEN": os.getenv("GITHUB_TOKEN")},
name="github"
),
# Database access
mcp.server(
command="python",
args=["-m", "mcp_server_postgres"],
env={"DATABASE_URL": os.getenv("DATABASE_URL")},
name="postgres"
)
]
)
# Agent has access to tools from all three servers#Server Configuration Function
The mcp.server() function creates an MCP server configuration:
mcp.server(
command: str,
args: Optional[List[str]] = None,
env: Optional[Dict[str, str]] = None,
name: Optional[str] = None
) -> Dict[str, Any]#Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
command | str | Yes | Command to run MCP server (e.g., "uvx", "npx", "python") |
args | List[str] | No | Arguments for the command |
env | Dict[str, str] | No | Environment variables for the server process |
name | str | No | Optional name for the server (for logging/debugging) |
#Returns
Server configuration dictionary used internally by the agent.
#Agent Integration
When you attach MCP servers to an agent, tools are automatically discovered and registered:
from daita import Agent
from daita.plugins import mcp
agent = Agent(
name="filesystem_agent",
mcp=mcp.server(command="uvx", args=["mcp-server-filesystem", "/data"])
)
await agent.start()
# Tools are discovered automatically on first run() call
result = await agent.run("Read the file data/report.csv")
# Agent autonomously uses MCP tools as needed#Official MCP Servers
Daita works with all official MCP servers. Here are common examples:
#Filesystem Server
Access local files and directories:
mcp.server(
command="uvx",
args=["mcp-server-filesystem", "/data"]
)Available Tools:
read_file- Read file contentswrite_file- Write to fileslist_directory- List directory contentssearch_files- Search for files
#GitHub Server
Interact with GitHub repositories:
mcp.server(
command="npx",
args=["-y", "@modelcontextprotocol/server-github"],
env={"GITHUB_TOKEN": os.getenv("GITHUB_TOKEN")}
)Available Tools:
create_issue- Create GitHub issuesget_repository- Get repository informationlist_issues- List repository issuescreate_pull_request- Create PRs
#PostgreSQL Server
Query PostgreSQL databases:
mcp.server(
command="python",
args=["-m", "mcp_server_postgres"],
env={"DATABASE_URL": "postgresql://user:pass@localhost/db"}
)Available Tools:
execute_query- Run SQL querieslist_tables- List database tablesdescribe_table- Get table schema
#Slack Server
Send messages and interact with Slack:
mcp.server(
command="npx",
args=["-y", "@modelcontextprotocol/server-slack"],
env={"SLACK_TOKEN": os.getenv("SLACK_TOKEN")}
)Available Tools:
post_message- Send messages to channelslist_channels- List workspace channelsget_channel_history- Get message history
#Custom MCP Servers
#Creating a Custom Server
You can create custom MCP servers in Python:
# custom_mcp_server.py
from mcp.server import Server
from mcp.types import Tool
server = Server("custom-tools")
@server.list_tools()
async def list_tools():
return [
Tool(
name="calculate_sum",
description="Add two numbers",
inputSchema={
"type": "object",
"properties": {
"a": {"type": "number"},
"b": {"type": "number"}
},
"required": ["a", "b"]
}
)
]
@server.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "calculate_sum":
return {"result": arguments["a"] + arguments["b"]}
raise ValueError(f"Unknown tool: {name}")
if __name__ == "__main__":
server.run()#Using Custom Server
from daita import Agent
from daita.plugins import mcp
agent = Agent(
name="custom_agent",
mcp=mcp.server(
command="python",
args=["custom_mcp_server.py"]
)
)
await agent.start()
# Use custom tools
result = await agent.run("Calculate the sum of 42 and 58")#Error Handling
MCP connections handle errors gracefully. Wrap agent operations in try-except:
from daita import Agent
from daita.plugins import mcp
try:
agent = Agent(
name="agent",
mcp=mcp.server(command="uvx", args=["mcp-server-filesystem", "/data"])
)
await agent.start()
result = await agent.run("Read /data/file.txt")
except ConnectionError as e:
print(f"MCP server connection failed: {e}")
except RuntimeError as e:
print(f"Tool execution failed: {e}")
finally:
await agent.stop()#Best Practices
Server Configuration:
- Use environment variables for API keys and tokens, never hardcode
- Name your servers with the
nameparameter for easier debugging - Test MCP server commands manually before using with agents
- Handle connection failures with try-except blocks
Performance:
- Reuse agents instead of creating new ones for each request
- Connections are maintained automatically - no manual pooling needed
- Always call
agent.stop()or use async context managers for cleanup - MCP tools are discovered lazily on first
run()call
Debugging:
- Enable debug logging:
logging.basicConfig(level=logging.DEBUG) - Use
display_reasoning=Trueto see agent decisions - Check
agent.tool_namesto verify tools were discovered - Test server commands manually:
uvx mcp-server-filesystem /data
Tool Name Conflicts:
- If multiple servers provide the same tool name, last server wins
- A warning is logged when tool name collisions occur
- Use unique tool names in custom MCP servers
#Integration with Plugins
MCP tools work alongside Daita's native plugins:
from daita import Agent
from daita.plugins import mcp, PostgreSQLPlugin
from daita.core.tools import tool
# Combine MCP tools with native plugins
db_plugin = PostgreSQLPlugin(host="localhost", database="mydb")
agent = Agent(
name="hybrid_agent",
tools=[db_plugin], # Native plugin tools
mcp=mcp.server( # MCP tools
command="uvx",
args=["mcp-server-filesystem", "/data"]
)
)
await agent.start()
# Agent autonomously uses both database plugin tools and MCP filesystem tools
result = await agent.run(
"Query all users from the database and save the results to /data/users.json"
)
# Or create custom tools that combine both
@tool
async def hybrid_data_operation(user_count: int) -> dict:
"""Fetch users and save to file."""
# Use native plugin
db_results = await db_plugin.query(f"SELECT * FROM users LIMIT {user_count}")
# Use MCP tool
file_content = await agent.call_mcp_tool("write_file", {
"path": "/data/users.json",
"content": str(db_results)
})
return {"db_results": len(db_results), "file_written": True}
agent.register_tool(hybrid_data_operation)
result = await agent.run("Fetch 100 users and save them")#Requirements
Install the MCP SDK to use MCP servers:
pip install mcpOfficial MCP SDK: https://github.com/modelcontextprotocol/python-sdk
#Troubleshooting
Connection Timeout:
- Test the MCP server command manually:
uvx mcp-server-filesystem /data - Verify the server process starts and doesn't error immediately
- Check that the command path is correct in your environment
Tools Not Discovered:
- MCP tools are loaded lazily on first
run()call - Check logs with
logging.basicConfig(level=logging.DEBUG) - Verify the server provides tools by running it manually
Import Errors:
- Install MCP SDK:
pip install mcp - Ensure the MCP server package is installed (e.g.,
uvx mcp-server-filesystem)
#Next Steps
- Tools - Understanding the unified tool system
- Agent - Learn about agent capabilities
- Plugins - Native plugin integrations
- Workflows - Building multi-agent systems
#Resources
- Model Context Protocol - Official MCP documentation
- MCP Python SDK - Python SDK for MCP
- Official MCP Servers - Collection of official servers
- MCP Specification - Protocol specification