Contents

Linux Services & Systems
Domains, hosting, PEC, email infrastructure, network services and Linux systems. Open Source infrastructure support and management.
Discover →
Cybersecurity
CISO-as-a-service consulting: posture, remediation roadmap, ongoing support.
Discover →On 28 July the Model Context Protocol published revision 2026-07-28, the first since 2025-11-25 and the first with the project under the Linux Foundation’s Agentic AI Foundation. One change gives the release its headline: the protocol becomes stateless.
For anyone running an MCP server in production this is not a version bump, it is a migration.
What stateless means in practice
Two long-standing things disappear. The initialize handshake with its notifications/initialized notification, and the Mcp-Session-Id header of the Streamable HTTP transport.
In their place every request now carries what it needs inside _meta: the protocol version, the client capabilities and the identity of the caller. Servers declare their own identity in the _meta of every result, and an incompatible version comes back as UnsupportedProtocolVersionError. That is SEP-2575, alongside SEP-2567 which removes sessions from the transport.
Servers that need to remember something between calls now do it with server-minted handles passed as ordinary tool arguments. State does not go away, it changes place: from implicit in the transport to explicit in the function signature.
The operational consequence is the one the project names as the most requested feature from developers: any request can land on any instance, so an MCP server sits behind a round-robin load balancer like any other HTTP service, with no sticky sessions and no affinity.
server/discover arrives, and servers must implement it to advertise supported versions, capabilities and identity. A client may call it before anything else to pick a version, or use it as a compatibility probe over stdio.
Streamable HTTP POST requests must carry the Mcp-Method and Mcp-Name headers (SEP-2243). Gateways use them to route and meter without opening the JSON body, which is the difference between a proxy that reads a header and one that deserialises every call.
Results from tools/list, prompts/list, resources/list, resources/read and resources/templates/list must carry ttlMs and cacheScope (SEP-2549). The first says how long the data stays fresh, the second whether a shared intermediary may cache it. The recommendation to return tools in a deterministic order points the same way, since it is what makes prompt caches work on the model side.
The resource-not-found error code changes too, from -32002 to -32602, the value JSON-RPC uses for invalid parameters.
MRTR, when it is the server that needs something
Until now, when a server needed something from the client (directories through roots/list, an inference through sampling/createMessage, a value from the user through elicitation/create) it opened a request in the opposite direction, and that required a persistent stream.
The new pattern is called Multi Round-Trip Requests (SEP-2322) and it reverses the direction. The server returns an InputRequiredResult with resultType: "input_required", and puts what it is missing in the inputRequests field. The client reissues the same request with inputResponses attached. No open channel, just a question travelling back inside an answer.
Hence the consequence that touches every result: each one now carries a required resultType field, either "complete" or "input_required". Clients must treat results from earlier-protocol servers that omit the field as complete, which is how the revision stays backward compatible.
Roots, Sampling and Logging deprecated
Three features move to the deprecated state with SEP-2577. They remain fully functional for the whole window, but new implementations should not adopt them. The migrations the project suggests:
| Deprecated | In its place |
|---|---|
| Roots | directories and files passed as tool parameters, resource URIs or server configuration |
| Sampling | integrating directly with the LLM provider APIs |
| Logging | writing to stderr over stdio, or OpenTelemetry |
The heaviest line is Sampling, and it is the least visible in the changelog. It was the primitive through which a server asked the client to run an inference with the model the client had already configured: an MCP server could use an LLM without holding a key, without a contract with a provider and without paying for tokens. Removing it moves that responsibility, and that cost, onto whoever builds the server.
Also deprecated is Dynamic Client Registration from RFC 7591 as a registration mechanism, in favour of Client ID Metadata Documents. It stays available for compatibility with authorization servers that do not support CIMD.
Three tightenings on authorization
They are classed as minor changes in the changelog, and rather less minor for anyone exposing an MCP server on the internet.
The authorization server should include the iss parameter in authorization responses, per RFC 9207, and the client must validate it against the recorded issuer before redeeming the authorization code (SEP-2468).
Clients must specify an appropriate application_type during dynamic registration, to avoid OpenID Connect redirect URI conflicts (SEP-837).
Credentials are bound to the authorization server that issued them: they must be keyed by issuer identifier, must not be reused with a different authorization server, and re-registration is required when the authorization server changes (SEP-2352).
What gets lost along the way
Stream resumability disappears: the Last-Event-ID header and SSE event IDs are gone. A broken stream loses the in-flight request, and the client must reissue it from scratch with a new ID. On long calls, and on mobile networks, that is paid for in repeated work.
The HTTP GET endpoint and the resources/subscribe and resources/unsubscribe pair give way to subscriptions/listen, a single POST-response stream the client opts into by declaring which notifications it wants.
ping, logging/setLevel and notifications/roots/list_changed are removed. Log level is now set per request through io.modelcontextprotocol/logLevel inside _meta, and servers must not emit notifications/message for requests that did not include the field.
Tasks leave the core and become the official io.modelcontextprotocol/tasks extension (SEP-2663). The blocking tasks/result gives way to polling through tasks/get, tasks/update arrives for client-to-server input, and tasks/list is removed.
The HTTP+SSE transport, deprecated since 2025-03-26, is reclassified as deprecated under the new policy.
A deprecation policy, not just a release
Along with the revision the project adopted a feature lifecycle policy (SEP-2596): three declared states (Active, Deprecated, Removed), a minimum twelve-month window before a deprecated feature can be removed and a public registry tracking everything currently deprecated. In parallel the SEP process becomes markdown files in a seps/ directory, with numbering derived from the pull request and explicit sponsor responsibilities (SEP-1850).
For anyone fitting MCP into a two-year plan this is the part with the longest reach. Knowing that a deprecated feature stands for at least twelve months, and that the list of what is deprecated lives in a public registry rather than in a thread, changes the kind of decision you can make.
On adoption, the announcement post states that the four Tier 1 SDKs (TypeScript, Python, Go, C#) already support the revision, that the Rust one supports it in beta, and that the Tier 1 SDKs together approach half a billion downloads a month, with TypeScript and Python each past a billion downloads in total. Those are the project’s own figures, with no third-party verification.
What changes for a server already in production
If a gateway routes or meters on Mcp-Session-Id, that logic has to be rewritten on the Mcp-Method and Mcp-Name headers. If the server expects initialize as the first message, updated clients no longer send it. If state lived in the session, it moves into explicit handles passed as arguments. If the server uses Sampling, it needs a plan for direct integration with a provider, with the key and the cost that follow. If anything relied on resuming interrupted streams, it has to be handled with retries.
The previous revision is not switched off, and the changelog explicitly covers servers on older versions: server/discover doubles as a compatibility probe and results without resultType are read as complete.
What we think
MCP was born in late November 2024 as a stateful bidirectional protocol, designed for an agent talking to a server on the same machine. Revision 2026-07-28 turns it into a request/response protocol that sits behind a balancer, with routing headers, declared caches and credentials bound to an issuer. It is the path a piece of software takes when it stops running on a laptop and starts running in production on someone else’s behalf.
The price is stated and it is payable: a real migration, resumability gone and three primitives from the original design leaving the stage. The twelve-month window is what makes deprecating Sampling something for a backlog rather than an emergency.
What remains is the point that holds for every open protocol at this stage, A2A included: the hard part is not the specification, it is everything around it. Declared governance, deprecation windows, public registries. It is the same question that runs through agent governance, and the one that decides whether a project can be adopted by a company that has to answer for what it puts into production.
