Skip to main content

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:

code
┌──────────────────────────────────────────────────────┐
│ 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

ConceptDescription
HostThe application that connects to MCP servers (e.g., Claude Desktop)
ClientA protocol client within the host that maintains a 1:1 connection with a server
ServerA lightweight program that exposes capabilities (tools, resources, prompts)
TransportThe 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.

json
{
"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.

json
{
"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.

json
{
"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:

code
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.

json
{
"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.

json
{
"mcpServers": {
"remote-api": {
"url": "https://api.example.com/mcp/sse",
"headers": {
"Authorization": "Bearer sk-xxx"
}
}
}
}

The modern transport for remote servers. Supports both HTTP requests and SSE for streaming.

json
{
"mcpServers": {
"my-server": {
"url": "https://api.example.com/mcp",
"transport": "streamable-http"
}
}
}
Transport Selection
  • 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:

json
// 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:

ServerDescription
@modelcontextprotocol/server-filesystemRead/write files on the local filesystem
@modelcontextprotocol/server-githubGitHub API — issues, PRs, repos
@modelcontextprotocol/server-postgresPostgreSQL database queries
@modelcontextprotocol/server-brave-searchWeb search via Brave Search API
@modelcontextprotocol/server-google-mapsGoogle Maps directions and places
@modelcontextprotocol/server-slackSlack messaging integration
Security Considerations

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