Model Context
Protocol
in Python
A comprehensive, production-grade guide to Anthropic's Model Context Protocol (MCP). Master server primitives, transport layers, and orchestrate custom AI memory architectures.
from mcp.server.fastmcp import FastMCP
# Instantiate named server
mcp = FastMCP("weather")
@mcp.tool()
def get_weather(location: str) -> str:
"""Get current weather details."""
return f"Weather in {location}: 28°C, Sunny"
if __name__ == "__main__":
mcp.run() # Runs STDIO transport by default|
The Problem MCP Solves
Before the Model Context Protocol emerged, the AI ecosystem suffered from extreme fragmentation. Every framework created its own tool-calling interface, forcing engineers to rewrite identical APIs.
Integration Bloat
Developers wanting to expose tools to LangChain, LlamaIndex, CrewAI, and AutoGen had to author four distinct wrappers. This led to fragmented codebases, diverging arguments parsing logic, and major maintenance overheads.
Decoupled Contracts
MCP separates what a tool does (managed by the server) from how the AI reasons about it (managed by the host). This cleanly mirrors the USB hardware interface, establishing a universal plug-and-play standard.
Ecosystem Adoption
Announced by Anthropic in late 2024, MCP has become a community standard. The official SDKs support Python, Kotlin, and TypeScript. In 2025, remote Streamable HTTP transports extended local servers to cloud subnets.
The Journey of MCP
From a personal developer utility solving context transfer limitations to a standard infrastructure integrated by major industry players.
Origins at Anthropic
Conceived by core engineers David Soria Parra and Justin Spahr-Summers. The protocol was born out of Soria Parra's personal frustration with copy-pasting code snippets, shell logs, and workspace file details back and forth into Claude.
Manual buffer exchanges between the developer's shell and conversational models represented a key latency bottleneck.
Public release of Python & TypeScript SDKs, establishing STDIO subprocess patterns for agent host links.
Official Public Launch
Anthropic officially open-sources the Model Context Protocol. By publishing the core specifications alongside open libraries, the community began decoupling LLM orchestrators from custom API integration wrappers.
Modular Extensions v1.1
One year following launch, the maintainers released the first major update to the MCP spec. This added structured progress tracking patterns, dynamic resources subscriptions, and critical security handshake guidelines.
Introduction of structured task updates and client-approved command validations to reduce model execution risks.
Cross-industry integration with unified client implementations from Anthropic, OpenAI, AWS, and Google.
Enterprise Scale Milestone
MCP records over 97 million monthly SDK downloads. The community catalog of open-source servers expands beyond 5,800 verified packages. MCP becomes standard infrastructure for agentic AI orchestration.
Visualizing the MCP Architectures
MCP deployments span local subprocess execution, streaming cloud architectures, and orchestrators routing to multiple client nodes. Switch tabs below to view each topology with two-way continuous data packet flows.
Local STDIO Subprocess Flow
Choose an architecture style above, and click "Start Particle Flow" to simulate continuous two-way communications. Watch green request particles flow Upstream and cyan response packets stream Downstream.
No active request logs.
The Three Core Primitives
The Model Context Protocol establishes exactly three standard resource representations. Use the tabs below to explore how they behave and look in code.
Tools: Execution Endpoints
Tools enable LLMs to run operations on your local system or query external REST APIs. The server registers functions with JSON Schema parameters, and the LLM decides when to execute them.
- • Auto-translated to OpenAI tool definitions.
- • Parameter schemas are auto-inferred from Python type hints.
- • Supports structured validation using Pydantic models.
Always supply clear docstrings for tool functions. The LLM relies on them to select and execute tools.
from pydantic import BaseModel, Field
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("member-db")
class Person(BaseModel):
first_name: str = Field(..., description="First name of worker")
years_xp: int = Field(..., description="Years of experience")
@mcp.tool()
def add_member(person: Person) -> str:
"""Registers a new developer into internal databases."""
return f"Registered {person.first_name} ({person.years_xp} YOE)"
Local Development vs Cloud Services
Switching from local subprocess pipes to multi-client remote cloud servers is as simple as adding a parameter flag.
Local Process Pipe
Host runs the server script as a child subprocess, sending JSON-RPC queries over system input/output pipes. Best choice for personal development, security containment, and custom desktop tool integrations.
Connecting servers directly to Claude Desktop config file locally.
Remote HTTP Server
Runs as a standalone web app using Server-Sent Events (SSE) for persistent server-to-client streaming, handling tool routing. Scalable to multiple hosts on cloud services.
Deploying central resource services to teams across developer subnets.
Streamable HTTP (SSE) Protocol Details
Unlike local child pipes, SSE networks split downstream data streaming and upstream client commands. Downstream events route via a continuous Server-Sent Events stream, while upstream client updates transmit via HTTP POST requests to `/message?session_id=...`.
HTTP/1.1 200 OK Content-Type: text/event-stream Cache-Control: no-cache Connection: keep-alive event: endpoint data: https://mcp.yourdomain.com/message?session_id=9a2b...
POST /message?session_id=9a2b... HTTP/1.1
Content-Type: application/json
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": { "name": "add_note", "arguments": {...} },
"id": 1
}
server {
listen 443 ssl;
server_name mcp.yourdomain.com;
ssl_certificate /etc/letsencrypt/.../fullchain.pem;
ssl_certificate_key /etc/letsencrypt/.../privkey.pem;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# SSE Streaming optimization settings
proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;
proxy_buffering off;
proxy_cache off;
read_timeout 24h;
}
}
module.exports = {
apps: [{
name: "mcp-server-production",
script: "python3",
args: "-m mcpserver.deployment",
env: {
PORT: "8000",
PYTHONPATH: "src",
OPENAI_API_KEY: "sk-proj-..."
},
restart_delay: 3000,
max_restarts: 10,
watch: false
}]
}
Production-Grade Implementations
Step beyond basic print functions. Explore two complete project structures drawn straight from the repository codebase.
Chess.com Stats Server
Connects an LLM to the Chess.com public profile API. Let the model compare player ratings, analyze historical win records, or find specific profile names via simple user dialogue. Includes standard requests headers to satisfy user-agent authorization limits.
@mcp.tool()
def get_chess_player_stats(username: str):
"""Get stats for a Chess.com player."""
url = f"https://api.chess.com/pub/player/{username}/stats"
res = requests.get(url, headers=headers)
return res.json()
Semantic Memory Tracker
Empowers autonomous AI agents with cross-session long-term memory. Stores plain-text inputs as embeddings inside OpenAI Vector Stores, retrieving relevant records dynamically via cosine search. Fixes the temporary file descriptor leakage present in naive implementations by strictly wrapping descriptors inside contextual handlers.
@mcp.tool()
def save_memory(memory: str):
"""Uploads data chunk, polling Vector Store."""
vector_store = get_or_create_vector_store()
# Leak-proof contextual wrapper fixes fd leaks
with tempfile.NamedTemporaryFile(mode="w+", delete=False, suffix=".txt") as f:
f.write(memory)
f.flush()
temp_file_name = f.name
with open(temp_file_name, "rb") as file_handle:
client.vector_stores.files.upload_and_poll(
vector_store_id=vector_store.id,
file=file_handle
)
return {"status": "saved", "store_id": vector_store.id}
Multi-Server Session Orchestration
How do you scale multiple tools concurrently? The client initiates parallel `stdio_client` context loops and routes the LLM's requests dynamically depending on the active server signatures.
Community MCP Server Registry Catalog
Expose databases, system browsers, developer APIs, or cloud platforms directly to your AI clients using
pre-built community packages launched via the uvx tool runner.
PostgreSQL Server
Inspect table schemas, query structures, and select data tables directly via natural dialogue.
GitHub Integration
Review branches, fetch diff files, inspect issues, and open pull requests programmatically.
Puppeteer Browser
Expose a headless chromium browser to take screenshots, scrape articles, and click buttons.
Local File System
Securely bind directory folders, allowing agents to read file listings and edit path lines.
Packaging MCP Servers
Ensure users can install your tool suite cleanly. By formatting your project using a modern
src/ layout and standardizing dependency bounds, anyone can call it on demand.
GitHub Distribution via UVX
Users don't need manual environments or virtualenvs. The package manager uvx retrieves
resources on request, launching isolated executors.
🚀 Production Server Infrastructure
- • HTTPS Terminals: Always use Nginx as a reverse proxy to manage secure SSL handshakes before redirecting internal SSE loops.
- • Supervisor control: Configure systems using PM2 daemon controllers, preserving state through restarts.
Exposing MCP Tools to LLM Engines
Once host clients discover available server tools via JSON-RPC, they must map tool specifications to the format expected by the LLM provider, then orchestrate a recursive completions execution loop.
-
•
OpenAI Schema Mapping: Map the server's discovered
inputSchemadirectly into theparametersblock of OpenAI's tool function schema. - • Recursive Execution Loop: Run a while-loop feeding completions back to the agent. If the LLM generates a tool execution request, capture it, run it against the target MCP server, append the outcome, and repeat until the model yields a text response.
Implement a "human-in-the-loop" approval step on the client side before resolving sensitive write tools to prevent automated security exploits.
async def agent_loop(user_prompt: str):
messages = [{"role": "user", "content": user_prompt}]
# 1. Fetch tool definitions from MCP Server
mcp_tools = await mcp_session.list_tools()
openai_tools = [{
"type": "function",
"function": {
"name": t.name,
"description": t.description,
"parameters": t.inputSchema
}
} for t in mcp_tools]
while True:
# 2. Query LLM with capabilities exposed
response = await openai_client.chat.completions.create(
model="gpt-4o",
messages=messages,
tools=openai_tools
)
msg = response.choices[0].message
messages.append(msg)
if not msg.tool_calls:
return msg.content # Exit when model returns text
# 3. Resolve tool calls recursively against MCP
for tool_call in msg.tool_calls:
name = tool_call.function.name
args = json.loads(tool_call.function.arguments)
mcp_result = await mcp_session.call_tool(name, args)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": mcp_result.content[0].text
})
Architectural Patterns & Code Gaps
Maximize the quality of your integrations. Avoid common deployment errors and build maintainable servers.
Type Safety Schema Conversion
Use Pydantic input models for complex tools. FastMCP will convert python attributes into valid JSON schemas, avoiding manual typing mistakes.
Contextual Relative Path references
Always anchor local assets relative to script execution zones. Use Path(__file__).parent
instead of hardcoding absolute paths.
Discrete Domains Partitioning
Keep server files modular. Define databases, APIs, and OS processes on individual servers, orchestrating connections at client layers.
AI Agent Security Threat Matrix
Exposing OS tools and database capabilities directly to LLMs presents critical security vectors. Review the protocol threat matrix and mitigation requirements below.
1. Indirect Prompt Injection (Confused Deputy)
An attacker hides instructions in untrusted resources parsed by the agent (e.g., summary of a webpage). The model is unable to segregate data from instructions, triggering local tools (e.g., Slack notifications, file edits) on the attacker's behalf.
2. Tool Poisoning & Shadowing
A compromised or malicious MCP server registers tool signatures matching trusted servers, intercepting execution payloads or parameters from the router.
github_, postgres_).
3. "Rug Pull" Code Execution
A server script passes audit checks during initial mount, but updates dynamically in the background to inject malicious dependencies or execute unauthorized shell scripts.
4. LLM Sampling Feature Abuse
Servers can request completions from the host model. Malicious loops can exhaust token quotas or leak session history variables to external nodes.
Enterprise Roadmap & Specification Extensions (2026+)
A view into the upcoming protocol updates designed to extend MCP scalability, enable server-rendered interfaces, and introduce enterprise authentication layers.
Stateless Core Transport
Migrating from persistent, stateful Server-Sent Events (SSE) channels to stateless HTTP/2 and REST message frames. Resolves load-balancing bottlenecks in distributed cloud clusters (such as AWS ALB or GCP GCLB).
Asynchronous Task Loops
Introduces progress-tracking channels and callback loops for long-running tools. Hosts retrieve
immediate task receipt tokens and query intermediate status updates (e.g., 45% completed)
without thread lockups.
MCP App UI Views
Enables servers to return dynamic JSON layout schemas back to host applications. The client UI renders rich, interactive layouts (forms, graphs, checklists) directly in the user interface, improving human-in-the-loop loops.
Centralized MCP Registry
A curated hub for discovering, installing, and managing servers. Features package signing, sandboxed static analysis, automated vulnerability assessments, and dynamic local runtime installation catalogs.
Cryptographic Identity
Adopting OpenID Connect (OIDC) and OAuth 2.1 authentication standards for remote endpoints. Leverages DPoP (Demonstrating Proof-of-Possession) authorization bindings to prevent session hijacking in zero-trust setups.
Federated Routing Mesh
Establishes standard routing matrices across federated multi-server configurations. Enables AI orchestrators to dynamically resolve tool shadowing, register fallback routes, and execute recursive cross-server calling sequences.
Interactive JSON-RPC Schema Console
Switch tabs below to inspect the standard JSON-RPC 2.0 frames exchanged between host clients and servers during capability discovery and tool invocation.
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-03-26",
"capabilities": {
"roots": { "listChanged": true },
"sampling": {}
},
"clientInfo": {
"name": "example-client",
"version": "1.0.0"
}
}
}
Uditya Narayan Tiwari
Building open-source tooling ecosystems and modern training curricula at the leading edge of generative AI systems. This documentation stems directly from research done compiling the Complete Guide to MCP in Python repository, detailing universal interfaces for context routing.
Receive Python & MCP Updates
Join a community of forward-thinking AI engineers. Get chapters, reviews, and checklists sent directly to your inbox.