MCP Servers Explained: What They Are and How to Connect Them
What is an MCP server?
MCP (Model Context Protocol) is an open standard from Anthropic for connecting AI models to external tools, data, and services. An MCP server is a program that implements this protocol and gives an AI assistant access to a specific resource — a database, an API, a filesystem, a service. The analogy: USB is a universal connector for peripherals; MCP is a universal protocol for AI integrations.
TL;DR
- -MCP (Model Context Protocol) is an open standard for connecting AI to external tools. One protocol instead of hundreds of custom integrations. 110M+ SDK installs per month
- -Architecture: Host (Claude Code, Cursor) → Client → Server → Resource. Transport: stdio for local servers, Streamable HTTP for remote ones
- -Three types of capabilities: Tools (actions — API calls, database writes), Resources (data — files, schemas), Prompts (interaction templates)
- -Connecting to Claude Code: the .mcp.json file or the claude mcp add command. For Cursor: the .cursor/mcp.json file or Settings → MCP
- -Writing your own MCP server takes 30-40 lines of code in TypeScript (@modelcontextprotocol/sdk v1.29) or Python (mcp v1.28). FastMCP covers 70% of servers in the ecosystem
- -MCP was handed over to the Linux Foundation (Agentic AI Foundation, Dec 2025). Supported by Claude, Cursor, VS Code, Gemini, ChatGPT, Windsurf, Microsoft Copilot, JetBrains, OpenAI Codex CLI, Xcode, Eclipse, and others — 300+ clients
MCP (Model Context Protocol) is an open standard for connecting AI models to external tools, data, and services. Created by Anthropic in November 2024, handed over to the Linux Foundation in December 2025. In 18 months: 110 million SDK installs per month, 10,000+ servers in the official registry (and over 20,000 counting PulseMCP and Smithery), support from 300+ clients: Claude, Cursor, VS Code, Gemini, ChatGPT, Windsurf, Microsoft Copilot, JetBrains, Xcode, and dozens of others.
This article is a complete guide: from concept to working code. Architecture, connecting ready-made servers to Claude Code and Cursor, writing your own server in TypeScript and Python, production considerations.
What MCP (Model Context Protocol) Is
The problem: every integration built from scratch
An AI assistant can generate text and code. But to work with the real world — databases, APIs, files, services — it needs integrations. Before MCP, every integration was custom-built.
Want to connect Claude to GitHub? Write a wrapper over the GitHub API. To PostgreSQL? Another wrapper. To Slack? A third one. Each with its own format, transport, and auth logic. Cursor does the same thing its own way. VS Code — its own way too.
The result: N AI platforms × M tools = N×M custom integrations. It doesn’t scale.
The solution: one protocol for everything
MCP solves this at the protocol level. One standard for how an AI assistant talks to external tools. Any MCP server works with any MCP client.
The analogy is USB. Before USB, every device had its own connector: keyboard — PS/2, printer — LPT, modem — COM port. USB standardized the connection: one port for everything. MCP does the same thing for AI.
- One MCP server for GitHub works in Claude Code, Cursor, VS Code, and ChatGPT alike
- A tool developer writes the server once — it’s available on every platform
- An AI platform developer implements the client once — gets access to every server
The formula: N + M instead of N × M.
Who supports MCP
As of June 2026, MCP is supported by:
- Claude Code and Claude Desktop (Anthropic) — native support, MCP was originally built for Claude
- Cursor — full support in Agent mode
- VS Code — native support since version 1.99 (early 2026), through GitHub Copilot Chat
- ChatGPT (OpenAI) — integrated via MCP
- Gemini (Google) — supports MCP servers
- Microsoft Copilot — integrated into Copilot, VS Code, and Windows 11
- Windsurf (Codeium) — supported in the IDE
- JetBrains — native support since May 2026 (IntelliJ IDEA 2025.2+, supports both an inbound MCP server in the IDE and an outbound client)
- OpenAI Codex CLI — supports MCP clients and servers (
codex mcp add); since June 2026, Codex Plugins bundle MCP configuration, skills, and app integrations into a single unit - Xcode — supported in Apple Intelligence Developer Mode (early access)
- Eclipse — via the MCP Bridge plugin
- Zed — built-in support through the Agent Panel
MCP isn’t a proprietary protocol owned by one company. It’s an open standard governed by the Linux Foundation through the Agentic AI Foundation (AAIF).
MCP Architecture
Four layers
MCP uses a client-server architecture with clearly separated responsibilities:
Host (Claude Code, Cursor)
└── MCP Client
└── MCP Server
└── Resource (DB, API, files)
Host — the application the AI model runs inside: Claude Code, Cursor, VS Code with Copilot. The Host manages the lifecycle of MCP clients.
MCP Client — a component inside the Host that holds a connection to one MCP server. Three servers mean three clients.
MCP Server — a program implementing the protocol. It accepts requests from the client, translates them into calls against the resource, and returns the result. A local process or a remote HTTP server.
Resource — whatever the server exposes access to: a database, a REST API, a filesystem, a SaaS service, an internal tool.
The protocol: JSON-RPC 2.0
Under the hood, MCP uses JSON-RPC 2.0 — a standard remote procedure call protocol. Every request is a JSON object with a method, parameters, and an identifier:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search_issues",
"arguments": {
"query": "bug in auth module",
"state": "open"
}
}
}
The client sends a request, the server returns a result. The format is standardized — an implementation in any language is compatible with any MCP client.
Transport: stdio and Streamable HTTP
Transport determines how the client and server exchange JSON-RPC messages. MCP supports two mechanisms:
stdio — standard input/output. The server runs as a child process of the Host. The client writes to stdin, reads from stdout. The simplest option for local servers.
Host launches: npx @modelcontextprotocol/server-filesystem /path/to/dir
stdin → JSON-RPC request
stdout ← JSON-RPC response
When to use it: local development, CLI tools, servers that run on the developer’s machine.
Streamable HTTP — an HTTP transport introduced in March 2025. The server runs as an independent HTTP process, accepting POST requests. It uses Server-Sent Events (SSE) for streaming responses when needed.
Client → POST /mcp → MCP Server (remote)
Client ← SSE stream ← MCP Server
When to use it: remote servers, production deployments, servers running in Docker/Kubernetes, multi-tenant architectures.
HTTP+SSE (legacy) — the previous transport for remote servers, deprecated in favor of Streamable HTTP. Existing servers on SSE keep working; new implementations move to Streamable HTTP.
Comparing transports
| Characteristic | stdio | Streamable HTTP |
|---|---|---|
| Deployment | Local process | Remote server |
| Clients | One (the process owner) | Many concurrently |
| Scaling | No | Horizontal (load balancer) |
| Authentication | Via env | OAuth 2.1, bearer tokens |
| Latency | Minimal (IPC) | Network (HTTP) |
| Setup | Simple (command + args) | Needs an HTTP server |
| Typical use | Dev tools, CLI | SaaS, team servers, production |
Start with stdio. Move to Streamable HTTP once the server needs to serve multiple developers or run remotely.
Connection lifecycle
Connecting an MCP client to a server goes through several stages:
- Initialize — the client sends
initializewith information about itself (name, version, supported capabilities) - Server response — the server replies with its own capabilities (which tools, resources, prompts are available)
- Initialized — the client confirms readiness with an
notifications/initializednotification - Working — request exchange:
tools/list,tools/call,resources/read, and so on - Shutdown — the connection closes when the session ends
The entire exchange runs over JSON-RPC 2.0 — requests, responses, and notifications. Client and server can send notifications asynchronously (for instance, the server notifying about a change to the tools list).
Capabilities: Tools, Resources, Prompts
An MCP server can offer three types of capabilities:
| Type | Who calls it | Analogy | Example |
|---|---|---|---|
| Tools | The AI model | POST endpoint | Create a GitHub issue, run a SQL query |
| Resources | The application (Host) | GET endpoint | Database schema, file contents |
| Prompts | The user | Template | ”Review this code for security issues” |
More on each type in the “Resources vs. Tools vs. Prompts” section below.
How to Connect an MCP Server to Claude Code
Method 1: the claude mcp add command
The fastest way is the CLI command:
# Remote (recommended) — uses GitHub's official HTTP endpoint
claude mcp add-json github '{"type":"http","url":"https://api.githubcopilot.com/mcp","headers":{"Authorization":"Bearer YOUR_GITHUB_PAT"}}'
Format: claude mcp add-json <name> '<JSON configuration>'
Examples:
# Filesystem (access to a specific directory)
claude mcp add filesystem -- npx -y @modelcontextprotocol/server-filesystem /home/user/projects
# Brave Search (official package from Brave; the old @modelcontextprotocol/server-brave-search is archived)
claude mcp add brave-search -- npx -y @brave/brave-search-mcp-server
# PostgreSQL (@modelcontextprotocol/server-postgres is archived; use an actively maintained third-party package, e.g. mcp-postgres-server)
claude mcp add postgres -- npx -y mcp-postgres-server postgresql://localhost/mydb
The configuration is saved — the server is available the next time Claude Code starts.
Method 2: the .mcp.json file
For project-level configuration, use a .mcp.json file at the project root:
{
"mcpServers": {
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp",
"headers": {
"Authorization": "Bearer $GITHUB_PERSONAL_ACCESS_TOKEN"
}
},
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"],
"env": {}
},
"postgres": {
"command": "npx",
"args": ["-y", "mcp-postgres-server", "postgresql://localhost/mydb"],
"env": {}
}
}
}
- Environment variables — values in
envsupport$VARand${VAR}syntax. Variables are pulled from the shell environment at launch - No trailing commas in JSON — a common mistake. JSON doesn’t allow a comma after the last element
- File location:
.mcp.jsonat the project root — for project-level servers;~/.claude/.mcp.json— for global (personal) ones
Method 3: a remote HTTP server
For servers running over HTTP:
{
"mcpServers": {
"my-remote-api": {
"type": "http",
"url": "https://mcp.example.com/v1",
"headers": {
"Authorization": "Bearer $MY_API_TOKEN"
}
}
}
}
Three configuration levels
Claude Code supports three scopes for MCP servers:
| Scope | File | Who sees it | When to use |
|---|---|---|---|
| Project (shared) | .mcp.json at project root | The whole team (committed to git) | Servers everyone on the project needs |
| Project (personal) | .claude/.mcp.json | You only | Personal servers for this project |
| Global | ~/.claude/.mcp.json | You only, across all projects | Servers you need everywhere |
Shared project servers (GitHub, Sentry, Supabase) go in .mcp.json. Personal tools (Notion, Slack) go global.
Verifying the connection
For a broader look at setting up and running Claude Code day to day — not just MCP servers — see the complete Claude Code guide.
After setup, restart Claude Code and check:
claude mcp list
Or inside a Claude Code session: /mcp shows the status of every connected server.
Common setup mistakes
The server won’t start. For local servers, check that the package is reachable: npx -y @modelcontextprotocol/server-filesystem --help. Empty output means an npm or Node.js problem. For remote servers (GitHub), check that the token is set: echo $GITHUB_PERSONAL_ACCESS_TOKEN.
Environment variables aren’t substituted. Check echo $GITHUB_TOKEN. If it’s empty, add it to .zshrc / .bashrc or .envrc.
JSON syntax error. A trailing comma after the last element — JSON doesn’t accept that. Validate with: cat .mcp.json | python -m json.tool.
Server connects, but no tools show up. Fully restart Claude Code (exit + new session). Some servers load with a delay — give it a few seconds.
How to Connect an MCP Server to Cursor
Configuration
Cursor uses the same configuration format, just different file locations.
Project level — the .cursor/mcp.json file at the project root:
{
"mcpServers": {
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp",
"headers": {
"Authorization": "Bearer your-token-here"
}
}
}
}
Global level — the ~/.cursor/mcp.json file:
{
"mcpServers": {
"brave-search": {
"command": "npx",
"args": ["-y", "@brave/brave-search-mcp-server"],
"env": {
"BRAVE_API_KEY": "your-key"
}
}
}
}
Cursor specifics
- MCP tools are only available in Agent mode (not in Ask or Edit)
- Server management: Settings → Tools & MCP — shows each server’s status and lets you toggle individual tools on or off
- Cursor supports both stdio and HTTP transport
- The configuration format is identical to Claude Code — the same JSON with
mcpServers
Comparison: Claude Code vs. Cursor
| Parameter | Claude Code | Cursor |
|---|---|---|
| Configuration file | .mcp.json | .cursor/mcp.json |
| Global config | ~/.claude/.mcp.json | ~/.cursor/mcp.json |
| Transport | stdio, HTTP | stdio, HTTP |
| Management | CLI (claude mcp add/list) | GUI (Settings → MCP) |
| Agent mode | Always (the CLI itself is agentic) | Only in Agent mode |
Top 20 MCP Servers
Out of 10,000+ available servers, here are twenty that cover a developer’s core needs. All current as of June 2026. For a deeper ranked breakdown with setup notes, see our best MCP servers for 2026 roundup.
Code and repositories
| Server | Package | Description |
|---|---|---|
| GitHub | Remote: https://api.githubcopilot.com/mcp or Docker: ghcr.io/github/github-mcp-server | Full GitHub access: issues, PRs, code search, files, actions. The most popular MCP server |
| GitLab | gitlab-org/gitlab-mcp (official, from GitLab) | The GitHub server’s counterpart for GitLab: merge requests, issues, pipelines. The old @modelcontextprotocol/server-gitlab is archived |
| Filesystem | @modelcontextprotocol/server-filesystem | Safe filesystem access, restricted to specified directories |
Databases
| Server | Package | Description |
|---|---|---|
| PostgreSQL | mcp-postgres-server (third-party) | Queries against PostgreSQL, schema reading, data analysis. The official @modelcontextprotocol/server-postgres is archived |
| Supabase | MCP built into the Supabase CLI | SQL queries, migration management, edge functions. Respects Row Level Security |
| SQLite | @modelcontextprotocol/server-sqlite (Python, official) | Working with SQLite databases: queries, analysis, table creation |
Search and data
| Server | Package | Description |
|---|---|---|
| Brave Search | brave/brave-search-mcp-server (official, from Brave) | Web search, news search, image and video search via the Brave API. The old @modelcontextprotocol/server-brave-search is archived |
| Exa | exa-mcp-server | Semantic web search. Finds content by meaning, not by keyword |
| Fetch | @modelcontextprotocol/server-fetch | Fetches web pages, converts them to Markdown for AI consumption |
Communication and documentation
| Server | Package | Description |
|---|---|---|
| Slack | zencoder-ai/mcp-server-slack (maintained by Zencoder) | Reading channels, searching messages, sending, working with threads. The old @modelcontextprotocol/server-slack is archived |
| Notion | Official, from Notion | Searching pages, reading and editing content, working with databases |
| Google Drive | Official, from Google | Searching and reading files in Google Drive. The old @modelcontextprotocol/server-gdrive is archived |
Monitoring and DevOps
| Server | Package | Description |
|---|---|---|
| Sentry | Official, from Sentry | Error search, stack trace analysis, correlation with releases |
| Grafana | Official, from Grafana Labs | Dashboards, alerts, Prometheus/Loki queries, incidents |
| Kubernetes | @modelcontextprotocol/server-kubernetes | Cluster management, pod diagnostics, log analysis |
Design and browser
| Server | Package | Description |
|---|---|---|
| Figma | figma-developer-mcp (official, from Figma) | Reading design files: tokens, colors, typography, layout |
| Playwright | @playwright/mcp | Browser automation: navigation, clicks, screenshots, tests |
AI and memory
| Server | Package | Description |
|---|---|---|
| Memory | @modelcontextprotocol/server-memory | Persistent memory for AI: storing facts across sessions in a knowledge graph |
| Sequential Thinking | @modelcontextprotocol/server-sequential-thinking | Structured reasoning: task decomposition, step-by-step analysis |
Automation
| Server | Package | Description |
|---|---|---|
| Zapier | Via the Zapier MCP Bridge | Connects 7,000+ services: email, CRM, spreadsheets, notifications |
Recommendations for picking servers
Three servers is optimal. Five is the ceiling — beyond that, the overhead from tool descriptions starts eating into context.
A minimal setup for a developer:
- GitHub — code, issues, PRs
- Brave Search or Exa — searching documentation and solutions
- Sentry or Grafana — monitoring and debugging
Beyond that: PostgreSQL/Supabase for data, Slack/Notion for communication.
Writing Your Own MCP Server in TypeScript
Setup
mkdir my-mcp-server && cd my-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk zod
Full example: a server with a tool and a resource
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({
name: "weather-server",
version: "1.0.0",
});
// Tool: get weather for a city
server.registerTool(
"get_weather",
{
title: "Get Weather",
description: "Get current weather for a city",
inputSchema: {
city: z.string().describe("City name, e.g. 'Moscow'"),
},
},
async ({ city }) => {
// In a real server, this would call a weather API
const weather = {
city,
temperature: 18,
condition: "cloudy",
humidity: 65,
};
return {
content: [
{
type: "text" as const,
text: JSON.stringify(weather, null, 2),
},
],
};
}
);
// Resource: list of supported cities
server.registerResource(
"supported-cities",
"cities://supported",
{
description: "List of supported cities",
mimeType: "application/json",
},
async () => ({
contents: [
{
uri: "cities://supported",
text: JSON.stringify(["Moscow", "London", "Tokyo", "New York"]),
},
],
})
);
// Start over the stdio transport
const transport = new StdioServerTransport();
await server.connect(transport);
What’s happening here
- McpServer — a server instance with a name and version
- registerTool — registers a tool.
inputSchemauses Zod for validation. The AI model sees the description and schema, and calls the tool with the right parameters - registerResource — registers a resource with the signature
(name, uri, metadata, handler). Unlike a tool, a resource is invoked by the application (the Host), not directly by the AI model. That’s how context gets into the model - StdioServerTransport — connects over stdio. The server runs as a child process of Claude Code or Cursor
Connecting it to Claude Code
{
"mcpServers": {
"weather": {
"command": "npx",
"args": ["tsx", "/path/to/my-mcp-server/index.ts"]
}
}
}
Or via the CLI:
claude mcp add weather -- npx tsx /path/to/my-mcp-server/index.ts
Writing Your Own MCP Server in Python
Setup
mkdir my-mcp-server && cd my-mcp-server
pip install "mcp[cli]" # v1.28.1+
Or with uv (recommended):
uv init my-mcp-server && cd my-mcp-server
uv add "mcp[cli]"
Full example: a server with a tool and a resource
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("weather-server")
@mcp.tool()
def get_weather(city: str) -> dict:
"""Get current weather for a city.
Args:
city: City name, e.g. 'Moscow'
"""
# In a real server, this would call a weather API
return {
"city": city,
"temperature": 18,
"condition": "cloudy",
"humidity": 65,
}
@mcp.resource("cities://supported")
def supported_cities() -> str:
"""List of supported cities."""
import json
return json.dumps(["Moscow", "London", "Tokyo", "New York"])
@mcp.prompt()
def weather_report(city: str) -> str:
"""Generate a weather report prompt for a city."""
return f"Provide a detailed weather analysis for {city}. Include temperature trends, precipitation forecast, and clothing recommendations."
if __name__ == "__main__":
mcp.run()
What’s happening here
- FastMCP — a high-level framework from the official SDK. It generates tool descriptions from docstrings and type hints automatically
- @mcp.tool() — the registration decorator. The
city: strtype becomes theinputSchema, the docstring becomes the description - @mcp.resource() — the decorator for a resource with a URI pattern
- @mcp.prompt() — the decorator for a prompt template
- mcp.run() — starts the server (stdio by default)
FastMCP covers about 70% of servers in the ecosystem. Python type hints plus docstrings add up to a complete tool description — no extra boilerplate.
Connecting it to Claude Code
{
"mcpServers": {
"weather": {
"command": "python",
"args": ["/path/to/my-mcp-server/server.py"]
}
}
}
Or via uv:
{
"mcpServers": {
"weather": {
"command": "uv",
"args": ["run", "--directory", "/path/to/my-mcp-server", "server.py"]
}
}
}
Resources vs. Tools vs. Prompts
MCP defines three types of capabilities. Each fits its own scenario. Confusing them is a common mistake when designing servers.
Tools — actions
Tools are what the AI model calls on its own. The equivalent of POST endpoints in a REST API.
Characteristics:
- Called by the AI model (model-controlled)
- Can have side effects (writing to a database, sending a message, creating a file)
- Accept structured input (JSON Schema / Zod)
- Return the result of execution
Examples:
create_issue— create a GitHub issueexecute_sql— run a SQL querysend_message— send a Slack messagesearch_web— search the internet
The model sees the list of tools with their descriptions and schemas — and decides for itself which one to call and with what parameters.
Resources — data
Resources are data the Host provides to the AI model as context. The equivalent of GET endpoints.
Characteristics:
- Invoked by the application (application-controlled), not directly by the AI model
- Read-only — no side effects
- Use URI patterns (
file:///path,db://schema/table,config://app) - Provide context for decision-making
Examples:
db://schema— a database schemafile:///src/config.ts— the contents of a config filegit://log/recent— recent commitsenv://variables— available environment variables
Resources are a way to give the model context without calling a tool. The Host decides which resources to attach to a request.
Prompts — templates
Prompts are ready-made interaction templates the user chooses from. The equivalent of saved queries.
Characteristics:
- Chosen by the user (user-controlled)
- Define the structure of a conversation: system prompt plus user message
- Can accept arguments for parameterization
- Help standardize routine tasks
Examples:
code_review— a template for reviewing code with a security focussql_optimizer— analyzing and optimizing a SQL querybug_report— a structured bug description
When to use which
| Question | Tools | Resources | Prompts |
|---|---|---|---|
| Does the AI need to do something? | Yes | — | — |
| Does the AI need context to decide? | — | Yes | — |
| Does the user want a standard workflow? | — | — | Yes |
| Are there side effects? | Possibly | No | No |
| Who initiates it? | The AI model | The application | The user |
In practice: most servers provide tools. Resources are useful for database servers (schemas) and filesystem servers. Prompts are for specialized workflows (code review, security audits).
MCP in Production
Security
An MCP server performs actions on behalf of an AI — in production, that’s an attack vector.
Principle of least privilege. Give the server only the permissions it needs. A PostgreSQL MCP doesn’t need SUPERUSER. A GitHub MCP doesn’t need access to private repos if the work is on public ones.
Input validation. The SDK validates against the schema (Zod in TypeScript, type hints in Python), but that’s not enough. Check the business logic too — SQL injection through tool parameters is a real risk.
Secrets through environment variables. Never hardcode tokens in configuration. Use $VAR syntax in .mcp.json:
{
"env": {
"DATABASE_URL": "$DATABASE_URL",
"API_TOKEN": "$MY_SECRET_TOKEN"
}
}
Auditing. Log every tool call — each one is potentially destructive: data deletion, sending messages, infrastructure changes. No log, no forensics. For a full walkthrough of hardening and shipping servers in production, see our guide on building and running production-grade MCP servers.
Authorization
The MCP specification (current revision 2025-11-25; RC 2026-07-28 frozen since May 21, 2026, final publication July 28) describes authorization for the HTTP transport based on OAuth 2.1. For stdio, authorization happens at the environment level: variables and configuration files.
In June 2026, Enterprise-Managed Authorization (EMA) became stable — an extension for enterprise environments. EMA lets organizations manage MCP server authorization centrally through an IdP (Okta, Microsoft Entra ID, and others): the user signs in once via SSO and gets access to every connected server without a separate OAuth flow for each one. Already supported by Anthropic, Microsoft, Okta, Asana, Atlassian, Canva, Figma, Linear, and Supabase.
In production:
- HTTP servers — OAuth 2.1 with PKCE, bearer tokens in headers; in enterprise settings, EMA through an IdP
- Stdio servers — secrets via env, token rotation
- Scope restriction — a server should request only the minimum necessary permissions
Monitoring
What to monitor:
- Latency — the server’s response time adds to the AI response’s overall latency
- Error rate — a broken MCP server takes down the whole workflow
- Token overhead — tool descriptions take up context. 20 tools at 200 tokens each is 4,000 tokens on every request
- Cost — every tool call adds an AI cycle. More servers mean higher token spend
Grafana MCP plus Prometheus for metrics, Sentry MCP for errors. Monitoring MCP through MCP — recursion that actually works.
Scaling
Stdio is one process per client. It doesn’t scale for team servers.
Streamable HTTP solves this: one server for many clients. A stateless architecture — horizontal scaling behind a load balancer.
A pattern for teams:
- Local servers (filesystem, sqlite) — stdio, on the developer’s machine
- Shared servers (GitHub, Sentry, internal APIs) — Streamable HTTP, deployed in Docker/Kubernetes
- Configuration —
.mcp.jsonin the repo for project-level servers,~/.cursor/mcp.json/~/.claude/.mcp.jsonfor personal ones
The Future of MCP
Agentic AI Foundation (AAIF)
In December 2025, Anthropic handed MCP over to the Linux Foundation, where the Agentic AI Foundation (AAIF) formed. This is a governance shift, not a cosmetic one:
- Neutral governance — MCP is no longer controlled by a single company. AAIF platinum members: AWS, Anthropic, Block, Bloomberg, Cloudflare, Google, Microsoft, OpenAI. By April 2026: 170+ members. Governing Board chair — David Nalley (AWS); executive director — Mazin Gilbert
- Open specification — development through the SEP process (Specification Enhancement Proposals) with public discussion
- Interoperability — AAIF is aligning MCP, Goose (Block), and AGENTS.md (OpenAI) into a coherent set of standards
The A2A Protocol
Agent-to-Agent Protocol (A2A) — Google’s standard for communication between AI agents, also handed over to the Linux Foundation. MCP covers the “AI ↔ tool” connection. A2A covers “agent ↔ agent.”
The protocols complement each other:
- MCP: Claude Code calls GitHub through an MCP server
- A2A: Claude Code delegates a task to a specialized agent (say, a security reviewer) that works with its own MCP servers
A2A is its own standalone LF project, not part of AAIF, but it’s positioned as a complementary standard. A2A’s TSC includes AWS, Cisco, Google, IBM Research, Microsoft, Salesforce, SAP, and ServiceNow. MCP plus A2A together are the de facto standard for multi-agent systems — see our multi-agent architecture guide for patterns on coordinating several agents in practice.
2026 roadmap
Key directions from the official roadmap:
- Stateless core — MCP 2026-07-28 (Release Candidate frozen May 21, 2026, final publication July 28) makes the protocol stateless at its core. This is the biggest specification change since launch — the spec no longer assumes server-side session state, which allows horizontal scaling behind any load balancer
- Extensions framework — extensions are identified by reverse-DNS IDs, versioned independently of the core spec, and live in separate
ext-*repositories - Tasks Extension — long-running async operations: polling via
tasks/getinstead of the blockingtasks/result - MCP Apps — interactive UI applications inside MCP hosts
- Enterprise readiness — a formal deprecation policy (12 months between deprecated and removed), OAuth 2.1 hardening, audit logging
The numbers
- 110M+ SDK installs per month (April 2026; 97M+ in March) — both SDKs combined
- 10,000+ servers in the official registry; counting PulseMCP (15,000+) and Smithery (~7,300), the ecosystem is considerably larger
- 4,750% growth over 16 months (from 2M at launch)
- npm SDK:
@modelcontextprotocol/sdk— v1.29.0 (stable, the latest in the v1 series); stable v2 expected Q3 2026 - Python SDK:
mcp— v1.28.1 (stable), v2.0.0-beta published on PyPI; stable v2 due end of July 2026
For comparison: it took the React npm package 3 years to hit 100M installs per month. MCP crossed the same mark in 16 months.
Conclusion
MCP isn’t a buzzword. It’s an infrastructure standard solving a concrete problem: connecting AI to the real world through a single protocol.
What to do now:
- Connect 2-3 MCP servers to Claude Code or Cursor. GitHub plus Brave Search or Exa is the minimum for any developer
- Write your own server — 30 lines of TypeScript or Python. Wrap an internal API or a database
- Follow the specification — the 2026 roadmap is changing both transport and multi-agent scenarios
MCP doesn’t change what AI does — it changes what it has access to. The right tools in the right context are the difference between an AI assistant and an AI partner.