Building MCP Tooling
Create your own MCP servers with FastMCP and integrate them into meinGPT
Overview
With the Model Context Protocol (MCP), you can create your own tools and data sources for meinGPT. This guide shows you how to quickly and efficiently develop MCP servers using FastMCP and integrate them via HTTP Streamable Transport into meinGPT.
What is MCP?
The Model Context Protocol (MCP) is a standardized protocol for communication between LLMs and external tools. MCP servers can:
- Provide Tools - functions that the LLM can execute
- Offer Resources - data sources that the LLM can read
- Define Prompts - reusable templates for interactions
FastMCP Installation
pip install fastmcp uvicorn
Minimal Example
Create a simple MCP server with a tool:
from fastmcp import FastMCP
mcp = FastMCP("My MCP Server")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers"""
return a + b
# Start with: uvicorn main:mcp --port 8000
FastAPI Integration
FastMCP integrates seamlessly with FastAPI applications:
from fastmcp import FastMCP
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
# Create FastAPI app
app = FastAPI()
# Add CORS middleware for browser clients
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
# Create MCP server
mcp = FastMCP("My MCP Server")
@mcp.tool()
async def multiply(a: float, b: float) -> float:
"""Multiply two numbers"""
return a * b
# Mount MCP as ASGI app
mcp_app = mcp.http_app(path='/mcp')
app.mount("/", mcp_app)
# Add health check
@app.get("/health")
async def health():
return {"status": "healthy"}
# Start: uvicorn main:app --reload
# MCP URL: http://localhost:8000/mcp
Authentication
FastMCP offers flexible authentication options:
from fastmcp import FastMCP
from fastmcp.server.dependencies import get_http_request
from fastapi import HTTPException, status
mcp = FastMCP("Protected Server")
# API key management
API_KEYS = {"secret-key-1": "Production API Key"}
@mcp.tool()
async def protected_function(data: str) -> dict:
"""Protected function requiring authentication"""
request = get_http_request()
# Check API key from header
api_key = request.headers.get("X-API-Key")
if api_key not in API_KEYS:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid API key"
)
return {"status": "success", "data": data}
Resources
Resources provide structured data for the LLM:
@mcp.resource("config://settings")
async def get_settings():
"""Get current application settings"""
return {
"version": "1.0.0",
"environment": "production",
"features": ["api", "auth", "logging"]
}
@mcp.resource("data://{category}/{id}")
async def get_data(category: str, id: str):
"""Get data by category and ID"""
# Fetch from database
data = await fetch_from_db(category, id)
return data
Error Handling
Robust error handling is essential:
import httpx
from typing import Optional, Dict, Any
@mcp.tool()
async def api_call(
endpoint: str,
method: str = "GET",
data: Optional[Dict[str, Any]] = None
) -> dict:
"""Make HTTP request with error handling"""
async with httpx.AsyncClient(timeout=30.0) as client:
try:
response = await client.request(
method=method,
url=endpoint,
json=data
)
response.raise_for_status()
return {
"success": True,
"data": response.json(),
"status_code": response.status_code
}
except httpx.HTTPStatusError as e:
return {
"success": False,
"error": f"HTTP {e.response.status_code}",
"status_code": e.response.status_code
}
except httpx.TimeoutException:
return {
"success": False,
"error": "Request timeout"
}
except Exception as e:
return {
"success": False,
"error": str(e)
}
Context and Progress
Use Context for detailed logging:
from fastmcp import Context
@mcp.tool()
async def process_data(file_path: str, ctx: Context) -> dict:
"""Process file with progress reporting"""
# Log information
await ctx.info(f"Processing file: {file_path}")
# Read file
data = await read_file(file_path)
# Report progress
await ctx.report_progress(50, f"Processing {len(data)} items")
# Process data
results = await process_items(data)
await ctx.report_progress(100, "Processing complete")
return {"processed": len(results), "results": results}
Best Practices
1. Clear Tool Documentation
@mcp.tool()
async def send_email(to: str, subject: str, body: str) -> dict:
"""
Send an email notification.
Use this when:
- User explicitly requests to send an email
- System needs to send notifications
- Alerts need to be triggered
Args:
to: Recipient email address
subject: Email subject line
body: Email content (plain text)
Returns:
Dict with status and message_id
"""
# Implementation
2. Structured Responses
from pydantic import BaseModel
from datetime import datetime
class APIResponse(BaseModel):
success: bool
data: Any = None
error: str = None
timestamp: datetime
@mcp.tool()
async def fetch_data(query: str) -> APIResponse:
"""Fetch data with structured response"""
try:
result = await database.query(query)
return APIResponse(
success=True,
data=result,
timestamp=datetime.now()
)
except Exception as e:
return APIResponse(
success=False,
error=str(e),
timestamp=datetime.now()
)
3. Dependency Injection
from fastmcp.server.dependencies import get_http_request
from typing import Annotated
from fastapi import Header
@mcp.tool()
async def database_query(
query: str,
db_url: Annotated[str, Header(alias="X-Database-URL")]
) -> list:
"""Execute database query with injected connection"""
# Use db_url from header
conn = await get_connection(db_url)
return await conn.fetch(query)
Integration with meinGPT
- Start your MCP server
- Open meinGPT settings
- Navigate to "MCP Server"
- Add a new server:
- Name: Your server name
- URL:
http://localhost:8000/mcp
- Transport: HTTP Streamable
- Optional: Headers for authentication
Deployment
For production, containerization is recommended:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Further Resources
- FastMCP Documentation - Complete reference
- MCP Specification - Protocol details
- FastMCP GitHub - Examples and code
Example Projects
Find more examples of MCP servers in the FastMCP example collection.