Model Context Protocol (MCP)
MCP is the open standard that connects AI agents to tools, data sources, and services — the "USB-C port" for the AI ecosystem.
What is MCP?
The Model Context Protocol (MCP) is an open-source standard introduced by Anthropic in November 2024. It provides a universal protocol for AI applications to connect to external systems, replacing fragmented custom integrations with a single, standardized architecture.
Think of it this way: before USB-C, every device had its own charger. MCP does the same for AI — it's a universal connector between AI agents and the tools they need.
As of 2026, MCP has become an industry standard:
- 97M+ monthly SDK downloads
- 10,000+ active MCP servers
- Adopted by Claude, ChatGPT, Cursor, Gemini, Copilot, VS Code
- Joined the Linux Foundation as a founding project of the Agentic AI Foundation
Architecture
MCP follows a client-server architecture:
┌─────────────────────────────────────────────────────────┐
│ Your AI Application │
│ (MCP Client) │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ MCP Server │ │ MCP Server │ │ MCP Server │ │
│ │ GitHub │ │ Postgres │ │ Slack │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │
│ ↓ ↓ ↓ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ GitHub │ │ Database │ │ Slack │ │
│ │ API │ │ │ │ API │ │
│ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────┘
Key roles:
- MCP Client (Host) — The AI application that needs external capabilities (e.g., Claude Desktop, Cursor)
- MCP Server — Lightweight programs that expose specific capabilities through the standardized protocol
- Transport Layer — Communication channel between client and server (stdio, HTTP/SSE)
Three Core Capabilities
MCP servers can expose three types of capabilities:
1. Tools (Executable Functions)
Actions the agent can invoke, similar to function calling:
// MCP Tool: Create a GitHub issue
{
"name": "create_issue",
"description": "Create a new GitHub issue in a repository",
"inputSchema": {
"type": "object",
"properties": {
"repo": { "type": "string", "description": "owner/repo" },
"title": { "type": "string" },
"body": { "type": "string" },
"labels": { "type": "array", "items": { "type": "string" } }
},
"required": ["repo", "title"]
}
}
2. Resources (Readable Data)
Data sources the agent can read, like files, database records, or API responses:
// MCP Resource: Project README
{
"uri": "github://owner/repo/README.md",
"name": "Project README",
"mimeType": "text/markdown",
"description": "The main README file of the repository"
}
3. Prompts (Reusable Templates)
Pre-built prompt templates that guide specific workflows:
// MCP Prompt: Code Review
{
"name": "code_review",
"description": "Review code changes for quality and issues",
"arguments": [
{ "name": "diff", "description": "The code diff to review", "required": true },
{ "name": "focus", "description": "Areas to focus on (security, performance, style)" }
]
}
Ecosystem Overview
| Category | Examples |
|---|---|
| Clients | Claude Desktop, ChatGPT, Cursor, VS Code, Zed, Replit, Codeium |
| Data Servers | Google Drive, Postgres, SQLite, Filesystem, S3 |
| Dev Tool Servers | GitHub, Git, Docker, Kubernetes, Puppeteer |
| Communication Servers | Slack, Discord, Email, Notion |
| SDKs | Python, TypeScript, Java, Go, Rust, C#, Ruby, Swift |
Building an MCP Server
Here's a minimal MCP server in Python that provides a weather lookup tool:
from mcp.server import Server
from mcp.types import Tool, TextContent
server = Server("weather-server")
@server.list_tools()
async def list_tools():
return [
Tool(
name="get_weather",
description="Get current weather for a city",
inputSchema={
"type": "object",
"properties": {
"city": {"type": "string", "description": "City name"}
},
"required": ["city"]
}
)
]
@server.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "get_weather":
city = arguments["city"]
# Call weather API...
weather = await fetch_weather(city)
return [TextContent(type="text", text=f"{city}: {weather}")]
# Run the server
if __name__ == "__main__":
server.run(transport="stdio")
Configuring MCP in Claude Desktop
// ~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_TOKEN": "ghp_xxx" }
},
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres",
"postgresql://localhost/mydb"]
},
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem",
"/Users/me/projects"]
}
}
}
import { query, createSdkMcpServer, tool } from "@anthropic-ai/claude-agent-sdk";
import { z } from "zod";
// In-process MCP server with custom tools
const weatherServer = createSdkMcpServer({
name: "weather",
tools: [
tool("get_weather", "Get current weather for a city", {
city: z.string().describe("City name")
}, async ({ city }) => ({
content: [{ type: "text", text: `${city}: 22°C, sunny` }]
}))
]
});
// External MCP server (stdio) - type field is required!
const response = query({
prompt: "What's the weather in Tokyo? Also list my GitHub repos.",
options: {
mcpServers: {
"weather": weatherServer,
"github": {
type: "stdio", // Required: "stdio" | "http" | "sse"
command: "npx",
args: ["@modelcontextprotocol/server-github"],
env: { GITHUB_TOKEN: process.env.GITHUB_TOKEN }
}
},
allowedTools: [
"mcp__weather__get_weather", // Double underscore naming
"mcp__github__list_repos"
]
}
});
// Verify server health
const status = await response.mcpServerStatus();
// { weather: { status: "connected" }, github: { status: "connected" } }
Why MCP Matters for Agent Development
- Reusability — Build a tool once, use it across any MCP-compatible agent
- Standardization — No more custom integrations per LLM provider
- Composability — Mix and match servers to create powerful agent capabilities
- Security — Controlled access with clear permission boundaries
- Community — 10,000+ open-source servers to build upon
MCP vs Direct Function Calling
| Aspect | Function Calling | MCP |
|---|---|---|
| Scope | Single LLM provider | Universal, cross-platform |
| Discovery | Predefined in code | Dynamic server discovery |
| Lifecycle | Stateless per request | Persistent server sessions |
| Ecosystem | Build from scratch | 10K+ ready-to-use servers |
2026 Roadmap Highlights
- Async Operations — Support for long-running tasks with progress reporting
- MCP Registry — Centralized discovery and installation of servers
- Server Identity — Verified server authentication and trust chain
- Stateless Mode — Scalable deployment patterns for cloud environments
- MCP Apps — Interactive UI components returned from tool calls
Best Practices
- Start small — Use pre-built servers before building custom ones
- One server, one concern — Keep servers focused on a single domain
- Rich descriptions — Write detailed tool descriptions so the LLM knows when to use them
- Error handling — Return helpful error messages for the agent to recover
- Security first — Validate inputs, limit permissions, audit tool calls
Next Steps
- Agentic RAG — Build intelligent retrieval systems with MCP
- Multi-Agent — MCP in multi-agent architectures
- Claude Code & MCP — Practical MCP usage in Claude Code
Try It: Build a Minimal MCP Server
Create an in-process MCP server and connect it to an agent.
- Create a server with
createSdkMcpServer() - Define 2 tools using
tool()with Zod schemas - Connect via
mcpServersconfig - Verify connection with
mcpServerStatus() - Test: agent calls your
mcp__*__*tools correctly