MCP Protocol
The Model Context Protocol (MCP) is an open standard introduced by Anthropic in late 2024 that defines how AI models connect to external data sources and tools. Think of it as "USB-C for AI" — a universal connector that lets any LLM client talk to any tool server.
Why MCP?
Before MCP, every AI application had to implement tool integrations differently:
- OpenAI function calling had its own format
- Anthropic tool use had another format
- Custom agents built bespoke tool interfaces
- No standard way to share tools between applications
MCP solves this by defining a universal protocol that any LLM client can use to discover and invoke tools from any MCP server.
Architecture
MCP follows a client-server architecture:
┌──────────────────────────────────────────────────────┐
│ MCP Host │
│ (Claude Desktop, IDE, Custom App) │
│ │
│ ┌────────────────┐ ┌────────────────┐ │
│ │ MCP Client 1 │ │ MCP Client 2 │ │
│ │ (for Server A) │ │ (for Server B) │ │
│ └───────┬────────┘ └───────┬────────┘ │
└──────────┼──────────────────────┼───────────────────┘
│ │
stdio / SSE / StreamableHTTP │
│ │
┌──────────▼──────────┐ ┌────────▼─────────┐
│ MCP Server A │ │ MCP Server B │
│ ┌──────────────┐ │ │ ┌──────────────┐ │
│ │ Tools │ │ │ │ Tools │ │
│ │ Resources │ │ │ │ Resources │ │
│ │ Prompts │ │ │ │ Prompts │ │
│ └──────────────┘ │ │ └──────────────┘ │
│ │ │ │
│ External: GitHub │ │ External: DB │
│ API, Files, etc. │ │ API, S3, etc. │
└──────────────────────┘ └──────────────────┘
Key Concepts
| Concept | Description |
|---|---|
| Host | The application that connects to MCP servers (e.g., Claude Desktop) |
| Client | A protocol client within the host that maintains a 1:1 connection with a server |
| Server | A lightweight program that exposes capabilities (tools, resources, prompts) |
| Transport | The communication channel: stdio (local), SSE (remote), or StreamableHTTP |
MCP Capabilities
MCP servers can expose three types of capabilities:
1. Tools
Model-controlled — The LLM decides when to invoke these. Tools are functions the AI can call.
{
"name": "search_files",
"description": "Search for files matching a pattern",
"inputSchema": {
"type": "object",
"properties": {
"pattern": {
"type": "string",
"description": "Glob pattern to search for"
},
"directory": {
"type": "string",
"description": "Base directory to search in"
}
},
"required": ["pattern"]
}
}
2. Resources
Application-controlled — The host application decides when to read these. Resources are data sources the user can attach to conversations.
{
"uri": "file:///project/README.md",
"name": "Project README",
"description": "The main project documentation",
"mimeType": "text/markdown"
}
3. Prompts
User-controlled — The user explicitly selects these. Prompts are reusable templates.
{
"name": "code_review",
"description": "Prompt template for code review",
"arguments": [
{
"name": "language",
"description": "Programming language",
"required": true
}
]
}
Protocol Lifecycle
Every MCP connection follows this lifecycle:
1. Initialize
Client ──── initialize ────► Server
Client ◄─── initialize ───── Server
Client ──── initialized ───► Server
2. Operation (exchange messages)
Client ──── tools/list ─────► Server (discover tools)
Client ◄─── tool list ────── Server
Client ──── tools/call ─────► Server (invoke a tool)
Client ◄─── tool result ──── Server
Client ──── resources/read ─► Server (read a resource)
Client ◄─── resource data ── Server
3. Shutdown
Client ──── close ──────────► Server
Transport Options
Stdio Transport (Local)
Best for local development. The server runs as a child process.
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"]
}
}
}
SSE Transport (Remote)
Best for remote servers. Uses Server-Sent Events for server-to-client messages.
{
"mcpServers": {
"remote-api": {
"url": "https://api.example.com/mcp/sse",
"headers": {
"Authorization": "Bearer sk-xxx"
}
}
}
}
StreamableHTTP Transport (Remote, Recommended)
The modern transport for remote servers. Supports both HTTP requests and SSE for streaming.
{
"mcpServers": {
"my-server": {
"url": "https://api.example.com/mcp",
"transport": "streamable-http"
}
}
}
- Use stdio for local tools and development
- Use SSE for legacy remote servers
- Use StreamableHTTP for new remote deployments (more efficient, better error handling)
JSON-RPC Message Format
All MCP messages use JSON-RPC 2.0:
// Request
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search_files",
"arguments": {
"pattern": "*.py",
"directory": "/project/src"
}
}
}
// Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "Found 12 files:\n- /project/src/main.py\n- /project/src/utils.py\n..."
}
]
}
}
Official MCP Servers
Anthropic and the community maintain several reference servers:
| Server | Description |
|---|---|
@modelcontextprotocol/server-filesystem | Read/write files on the local filesystem |
@modelcontextprotocol/server-github | GitHub API — issues, PRs, repos |
@modelcontextprotocol/server-postgres | PostgreSQL database queries |
@modelcontextprotocol/server-brave-search | Web search via Brave Search API |
@modelcontextprotocol/server-google-maps | Google Maps directions and places |
@modelcontextprotocol/server-slack | Slack messaging integration |
MCP servers can access local files, databases, and APIs. Always:
- Review server code before installing
- Use least-privilege API keys
- Audit tool calls in production
- Validate all inputs on the server side