Model Context Protocol (MCP)
Every time someone builds an AI agent that connects to Slack, reads from a database, or controls a browser, they reinvent the same plumbing. MCP is Anthropic’s answer to this redundancy: a standardized, open protocol for connecting AI models to any tool or data source.
Think of MCP as the USB-C of AI integrations. Before USB-C, every device had its own proprietary charger. MCP aims to standardize how AI models connect to the world.
The Problem MCP Solves
Without a standard, every AI application builds custom integrations:
Before MCP: Claude app → custom code → Slack API Claude app → custom code → GitHub API Claude app → custom code → Database GPT app → different custom code → Slack API GPT app → different custom code → GitHub API
N models × M tools = N×M integration effortsWith MCP:
After MCP: Claude, GPT, Gemini, etc. ↓ (standard MCP client) MCP Server layer ↓ (built once) Slack, GitHub, Database, Browser...
N models + M tools = N + M implementationsBuild a tool once as an MCP server. Any MCP-compatible client (Claude, Cursor, your custom AI app) can use it immediately.
MCP Architecture
MCP follows a client-server model with three components:
┌─────────────────────────────────────────────────────┐│ MCP Host ││ (Claude Desktop, Cursor, your application) ││ ││ ┌─────────────┐ ││ │ MCP Client │←─── manages connections ││ └──────┬──────┘ │└─────────│───────────────────────────────────────────┘ │ MCP Protocol (JSON-RPC over stdio/SSE) │ ┌───────▼──────────────────────────────────────────┐ │ MCP Server │ │ │ │ Tools: callable functions │ │ Resources: readable data (files, DB results) │ │ Prompts: reusable prompt templates │ └──────────────────────────────────────────────────┘ │ ┌───────▼──────────────────────────────────────────┐ │ External Service / Data Source │ │ (GitHub API, Filesystem, Database, Browser...) │ └──────────────────────────────────────────────────┘Host: The application running the AI model and managing connections (Claude Desktop, Cursor, your custom app).
Client: The MCP client inside the host that speaks the MCP protocol.
Server: A process that exposes tools, resources, and prompts via MCP. Can be local (same machine) or remote.
The Three Primitives
Tools
Functions the model can call to take actions. Equivalent to function calling.
@server.tool("create_github_issue")async def create_github_issue( repo: str, title: str, body: str, labels: list[str] = []) -> dict: """Create a new GitHub issue in the specified repository.""" result = await github_client.create_issue(repo, title, body, labels) return {"issue_number": result.number, "url": result.html_url}Resources
Data sources the model can read — like a more flexible version of context injection.
@server.resource("file://{path}")async def read_file(path: str) -> str: """Read a file from the filesystem.""" return Path(path).read_text()
@server.resource("db://customers/{customer_id}")async def get_customer(customer_id: str) -> dict: """Retrieve customer record.""" return await db.customers.find_one({"id": customer_id})Prompts
Reusable prompt templates that can be parameterized. Users or models can invoke them to get context-appropriate prompts.
@server.prompt("code_review")async def code_review_prompt(language: str, focus: str = "all") -> list[dict]: """Generate a code review prompt for the given language.""" return [ {"role": "user", "content": f"Review this {language} code focusing on {focus}:"} ]Building an MCP Server: Complete Example
from mcp.server import Serverfrom mcp.server.models import InitializationOptionsfrom mcp.server.stdio import stdio_serverimport mcp.types as typesimport asyncioimport httpx
server = Server("my-weather-server")
@server.list_tools()async def list_tools() -> list[types.Tool]: return [ types.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) -> list[types.TextContent]: if name == "get_weather": city = arguments["city"] async with httpx.AsyncClient() as client: resp = await client.get(f"https://wttr.in/{city}?format=j1") data = resp.json() temp = data["current_condition"][0]["temp_C"] desc = data["current_condition"][0]["weatherDesc"][0]["value"] return [types.TextContent(type="text", text=f"{city}: {temp}°C, {desc}")]
async def main(): async with stdio_server() as streams: await server.run(streams[0], streams[1], InitializationOptions( server_name="my-weather-server", server_version="1.0.0" ))
asyncio.run(main())Configuring MCP in Claude Desktop
Once you’ve built an MCP server, add it to Claude Desktop’s config:
// ~/Library/Application Support/Claude/claude_desktop_config.json{ "mcpServers": { "weather": { "command": "python", "args": ["/path/to/my_mcp_server.py"] }, "filesystem": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/Documents"] }, "github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"], "env": {"GITHUB_TOKEN": "your_token_here"} } }}Claude Desktop will start these servers at launch and make their tools available in every conversation.
Official MCP Servers (2025–2026)
Anthropic and the community maintain a growing ecosystem:
| Server | What It Does |
|---|---|
| filesystem | Read/write local files |
| github | Search repos, create issues/PRs, read code |
| google-drive | Access Google Drive files |
| slack | Post messages, read channels |
| postgres / sqlite | Query databases |
| puppeteer / playwright | Control browsers |
| memory | Persistent knowledge graph |
| brave-search | Web search |
| AWS / GCP | Cloud resource management |
The full list is at modelcontextprotocol.io/servers — hundreds of community servers as of 2026.
Remote MCP Servers
MCP originally used local stdio transport (server process on the same machine). The protocol now supports remote MCP servers over HTTP/SSE — servers deployed as web services that any client can connect to.
This enables:
- SaaS products exposing their capabilities as MCP servers
- Shared organizational tools accessible to all team members
- MCP servers in the cloud for mobile clients
Cloudflare Workers, Vercel, and Railway all support deploying MCP servers in 2025.
MCP vs. Function Calling
| Aspect | Function Calling | MCP |
|---|---|---|
| Scope | Single API call | Full protocol |
| Portability | Provider-specific | Any MCP client |
| Resources | No | Yes |
| Prompts | No | Yes |
| Discovery | Static (in prompt) | Dynamic (server advertises) |
| Ecosystem | Per-provider | Shared |
Function calling is the mechanism inside MCP. MCP adds standardization, discovery, and a full client-server protocol on top of that mechanism. Think of MCP as function calling with a standard contract around it.
Why MCP Matters
MCP is becoming the de facto standard for AI-to-system integration because:
- It’s open (MIT license, not Anthropic-proprietary)
- Cursor, Zed, Cline, and many IDEs have adopted it
- The ecosystem of ready-made servers is growing fast
- It separates tool implementation from model-specific code
For AI developers in 2026: building tools as MCP servers means those tools work with any compatible AI host, multiplying your investment. It’s the same bet the industry made with REST APIs — standardize the interface, let the ecosystem grow.