Every AI feature eventually hits the same wall: the model is smart, but it cannot see your tickets, query your database or open a pull request. The usual fix has been one-off plugins and hand-written function-calling glue, often rebuilt for each model vendor. The Model Context Protocol, usually shortened to MCP, is an open standard designed to end that duplication, and it is now one of the most widely adopted ways for AI applications to reach tools and data.
This guide explains what MCP is, how the architecture works, what changed in the stateless 2026-07-28 specification, and what you need to get right before you put an MCP server in front of real users.
Key takeaways
- MCP is an open, JSON-RPC 2.0 based protocol that lets an AI application (the host) connect to tools and data (servers) through one standard interface instead of custom integrations.
- Servers expose three core primitives: tools the model can call, resources that provide context, and prompts that package reusable workflows.
- The 2026-07-28 specification made the protocol core stateless: no initialize handshake, no session IDs, and every request carries its own version and capabilities.
- Treat every MCP server as untrusted code with real privileges: least privilege, human approval for risky actions and validation of every input and output are not optional.
What is MCP in simple terms?
MCP is an open protocol for connecting LLM applications to external data sources and tools. Anthropic introduced it in November 2024, and in December 2025 donated it to the Agentic AI Foundation, a directed fund under the Linux Foundation co-founded by Anthropic, Block and OpenAI. The official specification describes it as a standardized way to give LLMs the context they need, and openly credits the Language Server Protocol as an inspiration.
That comparison is the best mental model. Before LSP, every editor needed its own plugin for every programming language. LSP turned an M times N integration problem into M plus N: each editor implements the client once, each language implements the server once. MCP does the same for AI. Write a GitHub, Postgres or Jira server once, and any MCP-compatible application that supports the same protocol version and features can use it, whether that is an IDE agent, a desktop chat app or your own internal assistant.
If you have built integrations before, MCP will feel familiar. It is an API contract with discovery built in, much like the patterns covered in our complete guide to APIs in software engineering. The difference is the consumer: instead of a developer reading docs, a model reads tool descriptions and decides what to call.
Why has MCP been adopted so widely?
Standards win when they remove repeated work, and MCP removed a lot of it. Some concrete signals from official sources:
- By December 2025, Anthropic reported more than 10,000 active public MCP servers and adoption in ChatGPT, Cursor, Gemini, Microsoft Copilot and Visual Studio Code.
- The 2026-07-28 release announcement reports Tier 1 SDK downloads close to half a billion per month, with the TypeScript and Python SDKs each past one billion total downloads.
- Cloud platforms including AWS, Cloudflare, Google Cloud and Microsoft Azure support deploying MCP servers, and vendor-neutral governance under the Linux Foundation lowered the risk of betting on it.
For engineering teams the practical payoff is simple: you build one integration surface for your product, and every agent your customers use can reach it.
How does MCP architecture work: hosts, clients and servers?
MCP has three roles. Getting them straight prevents most early confusion.
| Role | What it is | Examples |
|---|---|---|
| Host | The AI application the user interacts with. It coordinates one or more clients, owns the model, and enforces user consent. | Claude Desktop, Claude Code, Visual Studio Code, your own agent app |
| Client | A connector inside the host. The host creates one client per server, and each client keeps a dedicated connection to that server. | The MCP client object an SDK gives you |
| Server | A program that exposes context and capabilities over MCP, running locally or remotely. | A filesystem server, the Sentry MCP server, an internal billing server |
The protocol itself has two layers. The data layer defines the JSON-RPC 2.0 messages: discovery, primitives and notifications. The transport layer defines how those messages move, including framing and authorization. Because the layers are separate, the same message works whether the server is a local process or a remote HTTP service.
Which transports does MCP support?
- stdio: the host launches the server as a local process and exchanges messages over standard input and output. No network overhead, typically one client per server. Ideal for filesystem, git or local developer tools.
- Streamable HTTP: the client sends HTTP POST requests to a single endpoint, and the server can optionally stream responses with Server-Sent Events. It is the supported transport for remote servers, often shared by many users, and it supports standard HTTP authentication, with OAuth recommended.
- HTTP+SSE (legacy): the original remote transport, deprecated since protocol version 2025-03-26 and now on a formal deprecation path. Do not build new servers on it.
What are MCP tools, resources and prompts?
Servers expose three primitives. Each one answers a different question for the host.
| Primitive | Who controls it | Typical use | Key methods |
|---|---|---|---|
| Tools | The model decides when to call them | Actions: query a database, create a ticket, call an API | tools/list, tools/call |
| Resources | The application decides what to attach | Context: file contents, schemas, records, API responses | resources/list, resources/read |
| Prompts | The user picks them, often as slash commands | Reusable templates and workflows | prompts/list, prompts/get |
A database server is a good example of all three working together: a query tool, a resource containing the schema, and a prompt with few-shot examples showing how to use the tool well.
On the client side, elicitation lets a server ask the user for missing information or confirmation mid-task, and it is the client feature the spec continues to build on. Sampling (asking the host’s model for a completion), roots and logging still work but were deprecated in 2026-07-28; the spec now recommends calling LLM provider APIs directly instead of sampling, and logging to stderr or OpenTelemetry instead of protocol logging.
What does an MCP request actually look like?
Everything is JSON-RPC 2.0. Under the current spec, a remote tool call is a single HTTP POST. Two new required headers, Mcp-Method and Mcp-Name, let gateways, rate limiters and web application firewalls route and meter traffic without parsing the body.
POST /mcp HTTP/1.1
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: get_weather
Content-Type: application/json
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": { "location": "New York" },
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientCapabilities": {},
"io.modelcontextprotocol/clientInfo": { "name": "my-app", "version": "1.0" }
}
}
}
A successful result returns a content array plus a resultType. Note the isError flag: business failures such as an invalid date come back as a normal result with isError set to true, so the model can read the message and retry with better arguments. Protocol problems such as an unknown tool name come back as standard JSON-RPC errors instead.
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"resultType": "complete",
"content": [
{ "type": "text", "text": "Current weather in New York: 72F, partly cloudy" }
],
"isError": false
}
}
What changed in the 2026-07-28 MCP specification?
The July 2026 release is a major architectural change. According to the official release post, MCP moved from a bidirectional, stateful protocol to a stateless request and response core. The headline changes:
- No more handshake or sessions. The initialize exchange and the Mcp-Session-Id header are gone. Each request carries protocol version and client capabilities in _meta, so any request can hit any server instance behind a plain round-robin load balancer.
- Optional discovery. Servers must implement server/discover to advertise versions and capabilities. Clients may call it first or simply send a request and handle an UnsupportedProtocolVersionError.
- Multi Round-Trip Requests (MRTR). When a tool needs user input mid-call, the server returns resultType input_required with its questions, and the client retries the original call with inputResponses attached. No held-open stream required.
- Cacheable lists. Results from tools/list, prompts/list, resources/list and resources/read carry ttlMs and cacheScope, and tools should be listed in deterministic order so LLM prompt caches stay warm.
- Opt-in change notifications. A single subscriptions/listen stream replaces the old HTTP GET endpoint and resource subscribe calls.
- Extensions framework. Tasks for long-running work, MCP Apps for interactive UI and Enterprise-Managed Authorization now live as official extensions.
- Authorization hardening. Clients must validate the iss parameter before redeeming an authorization code, credentials are bound to the issuing authorization server, and Client ID Metadata Documents replace Dynamic Client Registration as the preferred registration path.
Removing protocol sessions does not mean your application must be stateless. If a workflow needs state across calls, the server mints an explicit handle, returns it from a tool, and the model passes it back as an ordinary argument. State becomes visible and testable instead of hiding in the transport.
Deprecated features keep working for at least twelve months under the new deprecation policy, but if you maintain a server that relied on session IDs, plan the migration now. The TypeScript, Python, Go and C# SDKs support the new version, with Rust in beta.
How do you build a minimal MCP server?
The official Python SDK (version 2.0 or later) keeps the happy path short. Install it, decorate a function, and run over stdio:
# pip install "mcp[cli]"
from mcp.server import MCPServer
mcp = MCPServer("orders")
@mcp.tool()
def order_status(order_id: str) -> str:
"""Return the shipping status for an order ID such as ORD-1042."""
# Replace with a real, read-only lookup against your order service
return f"Order {order_id}: shipped, arriving Thursday"
@mcp.resource("orders://schema")
def order_schema() -> str:
"""Describe the fields available on an order record."""
return "id, customer_id, status, total, created_at"
if __name__ == "__main__":
mcp.run(transport="stdio")
The SDK turns the type hints into the tool’s JSON Schema and the docstring into its description, which is what the model reads when deciding whether to call it. That makes the docstring a piece of product copy: precise, specific and honest about side effects. A practical workflow:
- Start with two or three read-only tools that answer real user questions.
- Test them with the MCP Inspector before connecting a model.
- Connect a host such as Claude Desktop or VS Code over stdio and watch which tools the model picks.
- Only then add write actions, each with a confirmation step via elicitation.
- Move to Streamable HTTP with OAuth when other people or services need access.
How does MCP compare to plain function calling and REST APIs?
MCP does not replace your APIs; it gives AI consumers an interface that can expose existing APIs or implement capabilities directly. If you are already weighing interface styles, our REST vs GraphQL comparison covers the layer underneath.
| Approach | Best for | Discovery | Portability across AI apps |
|---|---|---|---|
| REST or GraphQL API | Programmatic clients written by developers | Docs, OpenAPI | Not AI-aware on its own |
| Vendor function calling | A single app talking to a single model provider | Defined in your code per request | Low: tied to one vendor’s format |
| MCP server | Any AI host that should reach your tools and data | Built in: tools/list, resources/list | High: one server can serve many compatible hosts |
Is MCP secure? The risks engineers must handle
MCP itself cannot enforce security; the spec says so plainly and puts the burden on implementers. Tools represent arbitrary code execution, and hosts must obtain explicit user consent before invoking them. The OWASP MCP Security Cheat Sheet lists the attacks you should design against:
- Tool poisoning: hidden instructions in tool descriptions, schemas or results that steer the model.
- Rug pulls: a server changes its tool definitions after the user approved it.
- Tool shadowing: one server’s descriptions manipulate how the agent uses another server’s tools.
- Confused deputy: a server acts with its own broad privileges instead of the caller’s.
- Classic injection: SQL, command or path traversal through arguments the model generated from untrusted context.
Defences follow familiar engineering principles: least privilege per server and per tool, sandboxing local servers, validating the audience of OAuth tokens and the Origin header on HTTP requests, never forwarding an MCP access token to an upstream API, pinning tool definitions, and logging every invocation with its parameters, user and timestamp while redacting secrets and personal data. Once you run several agents against many servers, governance becomes an organisational problem too, which we explored in debugging and governing multi-agent systems.
Common mistakes when adopting MCP
- Exposing your whole API as tools. The MCP roadmap notes that a server with a hundred tools makes the model pay for that surface before the user asks anything, and tool selection gets worse as lists grow. Design a small set of task-shaped tools.
- Vague tool descriptions. The model only knows what the description tells it. State inputs, outputs and side effects explicitly.
- Auto-approving write actions. Destructive, financial or data-sharing calls need explicit confirmation showing the full parameters.
- Throwing exceptions for business errors. Return isError results with actionable messages so the model can self-correct.
- Building new work on deprecated features. Avoid HTTP+SSE, session IDs, sampling and protocol logging in new servers.
- Storing tokens in config files. Use the operating system’s secure credential store, never plaintext settings.
FAQ
Who created MCP and who owns it now?
MCP was created at Anthropic by David Soria Parra and Justin Spahr-Summers and announced in November 2024. Since December 2025 it has been a project of the Agentic AI Foundation under the Linux Foundation, with open, community-driven governance.
Is MCP only for Claude?
No. MCP is vendor-neutral and has been adopted by ChatGPT, Cursor, Gemini, Microsoft Copilot, Visual Studio Code and many other hosts. Any application that implements an MCP client can use any compliant server.
What is the difference between an MCP tool and a resource?
A tool is an action the model chooses to execute, such as running a query. A resource is data the application attaches as context, such as a file or a schema. Tools are model-controlled; resources are application-controlled.
Do I need to rewrite my MCP server for the 2026-07-28 spec?
Simple servers built on an official SDK may need little more than an SDK upgrade and a test pass, but check the migration guide. Servers that depended on session IDs, server-initiated sampling or the legacy SSE transport need real migration work, and deprecated features remain supported for at least twelve months.
Should I use stdio or Streamable HTTP?
Use stdio for local, single-user tools that run on the developer’s machine. Use Streamable HTTP with OAuth for remote servers shared by many users or services, where you also get standard load balancing and gateways.
Conclusion
MCP turned AI integration from a per-vendor craft into a standard engineering surface. The 2026-07-28 specification made that surface look like any other HTTP workload: stateless, cacheable and easy to put behind your existing infrastructure. The hard parts that remain are the ones good engineers already know: clear interface design, least privilege, and honest error handling. If you are planning where agents fit into your systems, pair this with our guide to AI-native software architecture and our look at AI agents as the next operating system of software engineering.
Want practical system design and AI engineering guides like this in your inbox? Subscribe for free, and if you are new here, the Start Here page is the fastest way to find the best articles on the site.


Leave a Reply