Model Context Protocol (MCP) is an open standard created by Anthropic that enables AI applications to securely connect to external data sources and tools. Think of it as a universal plugin system for LLMs.
- MCP Server: A service that exposes capabilities (tools and resources) via the MCP protocol
- MCP Client: Your application (the LlamaLearn agent) that connects to MCP servers
- Tools: Functions the agent can call (e.g., "read_file", "search_github")
- Resources: Data sources the agent can access (e.g., file contents, API data)
Instead of hardcoding integrations, MCP provides:
- Standardized interface to many services
- Security through controlled access
- Modularity - add/remove capabilities dynamically
- Reusability - same servers work with any MCP client
┌─────────────────────────────────────────────────────────┐
│ Your LlamaLearn Agent │
│ ┌────────────────────────────────────────────────────┐ │
│ │ LlamaIndex ReAct Agent │ │
│ │ (with tools from MCP servers) │ │
│ └─────────────────┬──────────────────────────────────┘ │
└────────────────────┼────────────────────────────────────┘
│
│ MCP Protocol
│
┌────────────────┼────────────────┐
│ │ │
│ │ │
┌───▼────┐ ┌───▼────┐ ┌───▼────┐
│ MCP │ │ MCP │ │ MCP │
│ Server │ │ Server │ │ Server │
│(Files) │ │(GitHub)│ │(Custom)│
└────────┘ └────────┘ └────────┘
-
Filesystem - File operations
npx -y @modelcontextprotocol/server-filesystem /path/to/directory
-
GitHub - Repository access
export GITHUB_TOKEN=your_token npx -y @modelcontextprotocol/server-github -
PostgreSQL - Database queries
npx -y @modelcontextprotocol/server-postgres postgresql://user:pass@localhost/db
-
Brave Search - Web search
export BRAVE_API_KEY=your_key npx -y @modelcontextprotocol/server-brave-search -
Google Drive - Document access
npx -y @modelcontextprotocol/server-google-drive
See the full list at: https://github.com/modelcontextprotocol/servers
# Install MCP Python SDK
pip install mcp
# Install Node.js/npx (for many MCP servers)
# Ubuntu/Debian:
sudo apt install nodejs npm
# Or use nvm for latest versionfrom src.mcp_tools import MCPToolProvider
from src.agent import LlamaLearnAgent
from src.config import Settings
async def create_agent_with_filesystem_access():
settings = Settings()
# Create MCP tool provider
mcp_provider = MCPToolProvider()
# Connect to filesystem MCP server
await mcp_provider.connect_server(
name="filesystem",
command="npx",
args=["-y", "@modelcontextprotocol/server-filesystem", "/home/user/documents"]
)
# Get tools from MCP server
mcp_tools = mcp_provider.get_tools()
# Create agent with MCP tools
agent = LlamaLearnAgent(settings, tools=mcp_tools)
return agent, mcp_provider
# Use it
agent, mcp_provider = await create_agent_with_filesystem_access()
response = await agent.chat("List all Python files in the documents folder")# Make sure your API is running
./scripts/start-api.sh
# Run the MCP example
source venv/bin/activate
python examples/example_mcp_integration.pyYou can modify src/api.py to support MCP tools:
from fastapi import FastAPI, HTTPException
from src.mcp_tools import MCPToolProvider
import asyncio
app = FastAPI()
# Global MCP provider
mcp_provider = None
@app.on_event("startup")
async def startup_event():
"""Initialize MCP servers on startup."""
global mcp_provider
mcp_provider = MCPToolProvider()
# Connect to desired MCP servers
await mcp_provider.connect_server(
name="filesystem",
command="npx",
args=["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
)
# Get MCP tools and add to agent
mcp_tools = mcp_provider.get_tools()
agent.tools.extend(mcp_tools)
agent.agent = agent._create_agent() # Recreate with new tools
@app.on_event("shutdown")
async def shutdown_event():
"""Cleanup MCP connections."""
if mcp_provider:
await mcp_provider.disconnect_all()You can build your own MCP server in Python:
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
app = Server("calculator-server")
@app.list_tools()
async def list_tools():
"""List available tools."""
return [
Tool(
name="advanced_calculate",
description="Perform complex mathematical calculations",
inputSchema={
"type": "object",
"properties": {
"expression": {
"type": "string",
"description": "Mathematical expression to evaluate"
}
},
"required": ["expression"]
}
)
]
@app.call_tool()
async def call_tool(name: str, arguments: dict):
"""Execute a tool."""
if name == "advanced_calculate":
expression = arguments["expression"]
try:
# Be careful with eval in production!
result = eval(expression)
return [TextContent(type="text", text=str(result))]
except Exception as e:
return [TextContent(type="text", text=f"Error: {str(e)}")]
if __name__ == "__main__":
# Run the server
import asyncio
asyncio.run(stdio_server(app))Save as my_calculator_mcp.py and connect:
await mcp_provider.connect_server(
name="calculator",
command="python",
args=["my_calculator_mcp.py"]
)Instead of pre-indexing documents, let the agent search files dynamically:
# Agent can now:
response = await agent.chat(
"Search all Python files for functions that use asyncio, "
"then summarize their purpose"
)# Connect to GitHub
await mcp_provider.connect_server(
name="github",
command="npx",
args=["-y", "@modelcontextprotocol/server-github"],
env={"GITHUB_TOKEN": os.getenv("GITHUB_TOKEN")}
)
# Agent can now:
response = await agent.chat(
"Search my repositories for issues labeled 'bug' "
"and create a summary report"
)# Connect multiple sources
await mcp_provider.connect_server(name="filesystem", ...)
await mcp_provider.connect_server(name="brave_search", ...)
await mcp_provider.connect_server(name="postgres", ...)
# Agent can now:
response = await agent.chat(
"Search the web for latest Python best practices, "
"compare with our codebase in /src, "
"and store findings in the database"
)Add to your .env file:
# MCP Configuration
MCP_ENABLED=true
MCP_FILESYSTEM_PATH=/home/user/documents
MCP_GITHUB_TOKEN=ghp_xxxxxxxxxxxx
MCP_BRAVE_API_KEY=BSA_xxxxxxxxxxxxUpdate src/config.py:
class Settings(BaseSettings):
# ... existing settings ...
# MCP settings
mcp_enabled: bool = False
mcp_filesystem_path: str = "/tmp"
mcp_github_token: Optional[str] = None
mcp_brave_api_key: Optional[str] = None-
Filesystem Access: Only grant access to specific directories
# Good: Limited scope args=[..., "/home/user/safe-directory"] # Bad: Too permissive args=[..., "/"]
-
API Keys: Use environment variables, never hardcode
env={"GITHUB_TOKEN": os.getenv("GITHUB_TOKEN")}
-
Validation: Always validate MCP tool outputs before using them
-
Sandboxing: Consider running MCP servers in containers for isolation
# Check if npx is installed
npx --version
# Try running server manually
npx -y @modelcontextprotocol/server-filesystem /tmp
# Check Node.js version (need 18+)
node --version# Add timeout to server connection
server_params = StdioServerParameters(
command=command,
args=args,
env=env,
timeout=30 # seconds
)# Debug: List tools from session
tools_list = await session.list_tools()
print(f"Available tools: {[t.name for t in tools_list.tools]}")- MCP Documentation: https://modelcontextprotocol.io
- Official Servers: https://github.com/modelcontextprotocol/servers
- Python SDK: https://github.com/modelcontextprotocol/python-sdk
- Specification: https://spec.modelcontextprotocol.io
- Try the example: Run
python examples/example_mcp_integration.py - Pick a server: Choose an MCP server that fits your use case
- Integrate: Add MCP to your API startup in
src/api.py - Build custom: Create your own MCP server for domain-specific tools