Model Context Protocol (MCP)
The Model Context Protocol (MCP) is an open standard developed by Anthropic (2024) that defines a universal interface for connecting AI language models to external tools, data sources, and services — acting as a "USB-C port" for AI applications. It matters because it replaces the chaotic landscape of one-off tool integrations with a single, composable protocol that any LLM-powered application can adopt. The counterintuitive fact: MCP does not make the AI smarter — it makes the AI's environment smarter, shifting capability from the model itself to the surrounding infrastructure.
Before MCP, connecting an AI assistant to a database, a file system, or an API required custom glue code for every single combination — N models × M tools = N×M integrations. MCP collapses this to N+M: each model speaks MCP, each tool speaks MCP, and they interoperate automatically. The "aha moment" is realizing that MCP is not about AI at all — it is a communication protocol, like HTTP for the web, that happens to be designed with LLM interaction patterns in mind. Once a tool is wrapped as an MCP server, every MCP-compatible AI client can use it without any additional work.
How It Works
MCP defines three primitive types that a server can expose to a client (the AI application):
| Primitive | What It Is | Example |
|---|---|---|
| Tool | A callable function with side effects | `run_sql_query`, `send_email` |
| Resource | A readable data source (like a file or URL) | `file:///project/README.md` |
| Prompt | A reusable, parameterized prompt template | `summarize_document(doc_id)` |
The protocol lifecycle follows a simple handshake-then-operate pattern:
Explanation: This ratio measures how well a given MCP server satisfies an agent's tool requirements — a score of 1.0 means full coverage, 0 means the server provides nothing useful.
Explanation: End-to-end response time in an MCP system is the sum of model inference time, the protocol round-trip overhead, and the actual tool execution time — the last term often dominates for database or API calls.
The Message Flow
Every MCP interaction uses JSON-RPC 2.0 as its wire format. Here is a minimal real exchange: ```python
# What the MCP client sends to the server (JSON-RPC request) request = { "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "read_file", "arguments": {"path": "/data/report.txt"} } }
# What the MCP server sends back response = { "jsonrpc": "2.0", "id": 1, "result": { "content": [ {"type": "text", "text": "Q3 revenue was $4.2M..."} ] } } ```
Building a Minimal MCP Server in Python
```python
# pip install mcp from mcp.server import Server from mcp.server.stdio import stdio_server from mcp import types
# 1. Create the server app = Server("my-first-mcp-server")
# 2. Declare a tool @app.list_tools() async def list_tools() -> list[types.Tool]: return [ types.Tool( name="add_numbers", description="Adds two integers and returns the result.", inputSchema={ "type": "object", "properties": { "a": {"type": "number"}, "b": {"type": "number"} }, "required": ["a", "b"] } ) ]
# 3. Implement the tool @app.call_tool() async def call_tool(name: str, arguments: dict): if name == "add_numbers": result = arguments["a"] + arguments["b"] return [types.TextContent(type="text", text=str(result))] raise ValueError(f"Unknown tool: {name}")
# 4. Run over stdio transport (Claude Desktop uses this) async def main(): async with stdio_server() as (read_stream, write_stream): await app.run(read_stream, write_stream, app.create_initialization_options()) import asyncio asyncio.run(main()) ```
Connecting a Client (e.g., with the Python SDK)
```python import asyncio from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client async def run(): server_params = StdioServerParameters( command="python", args=["my_server.py"] ) async with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session:
# Initialize handshake await session.initialize()
# Discover what tools are available tools = await session.list_tools() print("Available tools:", [t.name for t in tools.tools])
# Call a tool result = await session.call_tool("add_numbers", {"a": 3, "b": 4}) print("Result:", result.content[0].text) # "7" asyncio.run(run()) ```
Transport Layers
MCP supports two transports, each suited to different deployment scenarios: ``` stdio → Local servers (same machine, subprocess) Claude Desktop, local dev tools HTTP/SSE → Remote servers (networked services) Cloud APIs, shared enterprise tools ```
Anthropic, the AI safety company founded by former OpenAI researchers including Dario and Daniela Amodei, published the Model Context Protocol specification in November 2024 as a fully open standard with Apache 2.0 licensing. The protocol was designed by Anthropic's developer experience team to solve integration fragmentation they observed across Claude deployments in enterprise settings. Remarkably, Anthropic chose not to make MCP proprietary — competitors including OpenAI and Google DeepMind quickly announced support, making it a genuine industry standard within weeks of release.
Intuition
Imagine you are a contractor who installs appliances. Before electrical standards existed, every appliance maker used a different plug shape — installing a refrigerator meant custom-wiring it to the wall, and it would only work in that exact house. MCP is like standardizing on a single plug format. Once a tool (appliance) supports MCP, any AI agent (house) can plug it in and use it immediately — no custom wiring required. A more technical analogy: MCP is to AI agents what REST APIs were to web services in the 2000s. Before REST, every web service had its own bespoke communication protocol. REST gave developers a shared vocabulary (GET, POST, PUT, DELETE) that worked everywhere, exploding the ecosystem of web applications. MCP gives AI agents a shared vocabulary (list_tools, call_tool, read_resource) that works across any model and any tool. The key mental shift: stop thinking of tools as part of your AI application, and start thinking of them as services your AI application discovers and connects to at runtime. The AI does not know in advance what tools exist — it asks the MCP server "what can you do?" and the server tells it. This is dynamic capability discovery, not hardcoded function definitions.
Historical Development
Origins · 1 minhow this was discovered
Why It Matters
Prerequisites
What This Leads To
See Also
Function Calling and Tool Use · Retrieval-Augmented Generation · AI Agents and Agentic Systems · LangChain Framework · Multi-Agent Systems