A protocol revision, not a new protocol
The Model Context Protocol Steering Committee published the 2026-07-28 specification on 28 July 2026, and it is a bigger revision than its predecessors. Earlier MCP revisions (2025-03-26, 2025-06-18, 2025-11-25) mostly added and refined features on top of the same core design: a stateful, bidirectional session between a client and a server, opened with an initialize handshake and held open for the life of the connection. The 2026-07-28 revision changes that core design itself. MCP's own announcement describes the shift as moving the protocol "from a bidirectional stateful protocol into a request/response stateless protocol," and most of what follows in this piece is a consequence of that one architectural decision.
If you build or run MCP servers that Claude Code, Codex CLI or another agent connects to, the practical question isn't whether to adopt this immediately, since the old behaviour keeps working. It's what's actually different, what's now deprecated with a clock running, and what a stateless MCP server buys you that a stateful one didn't.
The core change: no more handshake, no more session
Every MCP connection before this revision started the same way: the client sent initialize, the server replied with its capabilities, the client sent notifications/initialized, and only then did real requests start flowing. That exchange established a session, frequently pinned to one server instance behind an Mcp-Session-Id header, which every subsequent request on that connection implicitly relied on.
The 2026-07-28 spec removes that handshake and the session it created. In its place, every request is self-describing: it carries its own protocol version, client identity and client capabilities inside a _meta object, under keys such as io.modelcontextprotocol/protocolVersion, /clientInfo and /clientCapabilities. Nothing about interpreting the request depends on something that happened earlier in the connection, because nothing is assumed to have happened earlier at all.
Before (stateful):
client → initialize
server → capabilities response
client → notifications/initialized
client → tools/call (relies on session state from above)
After (stateless, 2026-07-28):
client → tools/call, carrying protocol version,
client identity and capabilities in _meta
That's the whole shift in miniature. A request that used to lean on session state now carries what it needs to be understood on its own.
Why statelessness is the point
The practical payoff is deployment, not elegance for its own sake. A stateful MCP server has to remember which client it's mid-conversation with, which in production usually means sticky sessions: a load balancer has to route every request from a given client back to the same server instance, or the server has to replicate session state across instances, both of which add real operational cost. A stateless server has neither problem. Because every request already contains everything needed to handle it, any instance behind a plain round-robin load balancer can answer any request, with no shared session store and no sticky routing to configure.
For a small, single-instance MCP server run locally over stdio, this distinction barely matters. It matters a great deal for a server meant to run behind real infrastructure, serverless functions, autoscaling groups, anything where "which instance handled the last request" isn't a question you want your deployment to have to answer.
An optional server/discover RPC fills the gap the old handshake used to cover for clients that still want to learn a server's supported protocol versions, capabilities and identity up front. Servers are required to implement it, though a client can skip it entirely and just send a request carrying the version and capabilities it wants, since that information travels with every request regardless.
Multi-round requests replace open streams for mid-call input
The old way for a server to ask a client something mid-task, confirm a destructive action, request a missing parameter, meant keeping a stream open and sending a server-initiated request down it. That's awkward in a stateless world with no persistent connection to hold open. The 2026-07-28 spec replaces it with multi-round requests: instead of a server-initiated request over an open stream, a tool call can return a result with resultType: "input_required", listing what it still needs. The client collects that input and retries the same call, this time supplying inputResponses.
The effect for a tool that needs to ask "which environment should I deploy to?" mid-call is functionally similar to before, the user still gets asked and the call still completes once they answer, but the mechanism is now a normal, statelessly-resumable request/response round trip rather than a message pushed down a connection the server has to keep open and the client has to keep listening on.
What else changed
A handful of smaller, genuinely useful changes ship in the same revision:
Header-based routing. Streamable HTTP POST requests now carry Mcp-Method and Mcp-Name headers, so a gateway or a WAF sitting in front of an MCP server can route or rate-limit specific operations without parsing the JSON body of every request to find out what it is.
Cacheable list results. tools/list, prompts/list, resources/list and resources/read responses now include ttlMs and cacheScope fields, plus deterministic ordering. A client can cache a server's tool list for a defined period instead of re-fetching it on every connection, which matters more once connections themselves stop being long-lived.
Authorization hardening. Authorization servers must now return an iss parameter per RFC 9207, and clients must validate it. Clients also set application_type during registration, closing a localhost redirect ambiguity, and client credentials are now bound to the specific authorization server that issued them rather than portable across servers.
Dynamic Client Registration is formally deprecated, in favour of Client ID Metadata Documents (CIMD), which describe a client's identity in a hosted document rather than through a live registration call.
The Tasks extension moves out of the experimental core into a versioned io.modelcontextprotocol/tasks extension, with poll-based tasks/get and a new tasks/update request. Change notifications across the board consolidate into a single subscriptions/listen stream that a client opts into per notification type, replacing the older per-feature notification mechanisms.
What's deprecated, and the clock that started on it
Three long-standing MCP features are now formally deprecated: Roots, Sampling and Logging. All three still work, the spec guarantees backward compatibility for a minimum of twelve months from the 28 July 2026 publication date, but new server development shouldn't build fresh dependencies on them. The legacy HTTP+SSE transport gets the same treatment: still functional, officially deprecated, with a year-long offramp before removal becomes a live possibility.
Practically, that means nothing you've built breaks today. It means the twelve-month window is the realistic point to plan a migration around if your server leans on any of the four, and that a brand-new MCP server started today has no good reason to build against them when the stateless core and its newer extensions are the direction the spec is actually heading.
| Status | Feature | Replacement / direction |
|---|---|---|
| Deprecated (12-month window) | Roots | No direct replacement documented in the announcement; check server-specific guidance |
| Deprecated (12-month window) | Sampling | No direct replacement documented in the announcement; check server-specific guidance |
| Deprecated (12-month window) | Logging | Consolidated subscriptions/listen stream covers change notifications generally |
| Deprecated (12-month offramp) | HTTP+SSE transport | Streamable HTTP with Mcp-Method/Mcp-Name headers |
| Formally deprecated | Dynamic Client Registration | Client ID Metadata Documents (CIMD) |
SDK support, as of publication
Anthropic's own SDK betas confirm Tier 1 language support landed alongside the spec: TypeScript, Python, Go and C# SDKs were updated for 2026-07-28, with the Rust SDK shipping in beta. If you maintain an MCP server or client in one of those languages, the updated SDK is the practical starting point rather than implementing the wire protocol changes by hand.
Who has adopted it so far
The clearest confirmed adopter, ten days after the spec's publication, is OpenAI's Codex CLI, which added opt-in support in version 0.147.0 on 7 August 2026: "paginated discovery, multi-round requests, and non-blocking server startup," alongside an MCP SDK upgrade to 3.0.0 in the same release. That release also shipped Codex CLI's separate Agent Plugins support, covered in detail in Agent Plugins explained, which is a distinct packaging spec built on top of MCP and Agent Skills rather than part of the MCP 2026-07-28 revision itself. Don't conflate the two: one is a protocol-level change to how MCP requests work, the other is a way to bundle a skill with the MCP server it depends on.
Beyond Codex CLI, this article can't independently confirm which other MCP clients or servers have adopted the 2026-07-28 revision as of publication. Anthropic's own SDK betas exist, which is a strong signal Claude-side tooling will follow, but check a given client's own changelog before assuming support, the same caution worth applying to any protocol revision this recent.
What this means if you maintain an MCP server
If your server is stateful today, built around the initialize handshake and session state, nothing forces a rewrite. The old behaviour is guaranteed to keep working for at least twelve months. What's worth doing now is auditing whether your server, or anything it depends on, leans on Roots, Sampling, Logging or the HTTP+SSE transport specifically, since those are the four pieces with a defined, if not yet dated, removal path. A server built cleanly on tool calls, resources and prompts, without those four, has comparatively little to change beyond adopting the newer SDK.
If you're starting a new MCP server today, building against the stateless core directly is the more future-proof choice, especially if you expect to run it behind more than one instance. The operational win, no sticky sessions, no shared session state to keep instances in sync, is real and applies from day one rather than only mattering once your deployment scales.
What this means for a skill that bundles an MCP server
If you've packaged a skill together with the MCP server it depends on using Agent Plugins, the mcp.json file inside that plugin declares the server's transport, stdio, streamable-http or sse, but says nothing about which MCP protocol revision the server itself speaks. That's decided by the server's own implementation, independent of the plugin packaging format around it. A plugin author updating their bundled MCP server to speak 2026-07-28 doesn't need to change plugin.json or the plugin's structure at all; the protocol revision is an implementation detail of the server, invisible to the packaging layer that wraps it. Anyone building or maintaining a plugin with a bundled server is better off tracking the MCP spec and their plugin's own release notes as two separate concerns, since one can change without the other.
Where to go next
For how MCP and Agent Skills divide responsibility regardless of which MCP revision a server implements, see Agent Skills vs MCP. For the separate packaging spec that bundles a skill with the MCP server it depends on, see Agent Plugins explained. Browse platforms with native MCP or Agent Skills support at getclaudeskills.com/platforms.
This article was verified directly against the Model Context Protocol's own 2026-07-28 announcement at blog.modelcontextprotocol.io and the modelcontextprotocol/modelcontextprotocol releases page on GitHub, plus OpenAI's Codex CLI 0.147.0 release notes for the adoption claim. Adoption beyond Codex CLI could not be independently confirmed at time of writing.
