MCP Went Stateless: What the 2026-07-28 Spec Breaks, What It Unlocks, and What To Do About It
On July 28, 2026, the Model Context Protocol working group published the 2026-07-28 specification and Anthropic announced support rolling out across Claude products. It is the fifth spec revision since MCP launched, and it is the first one where the headline is not a new capability. The headline is a removal. MCP no longer has sessions.
That sounds like plumbing. It is not. Every previous revision added surface area to a protocol whose shape stayed the same: a client opens a connection, negotiates with a server, and both sides talk over a stateful link. The 2026-07-28 revision deletes that shape and replaces it with plain request and response. David Soria Parra, one of MCP's co-inventors, called it MCP's most important release since remote MCP first shipped. He is right, and the reason is worth understanding before you decide how urgently it affects you.
We wrote a practitioner's guide to MCP in the enterprise in February. Most of the architectural advice in it survives this release. The deployment advice does not, and that is the point.
What Actually Changed
The stateless core is the whole story, and everything else follows from it.
The initialize and notifications/initialized handshake is gone. So is the Mcp-Session-Id header on the Streamable HTTP transport. Every request now carries what it needs to be understood on its own: the protocol version, the client capabilities, and the client identity travel in _meta on each call, under keys like io.modelcontextprotocol/protocolVersion and io.modelcontextprotocol/clientCapabilities. Servers identify themselves the same way in each result. A version mismatch returns UnsupportedProtocolVersionError instead of failing a handshake that no longer exists. For clients that want capabilities up front, servers must implement a new server/discover RPC, which doubles as a backwards compatibility probe over stdio.
The practical consequence is that any request can land on any instance. No sticky routing, no shared session store, no reconnect dance. A round-robin load balancer in front of a stateless pool is now a correct MCP deployment.
Server-to-client communication was rebuilt to match. The HTTP GET endpoint and the resources/subscribe and resources/unsubscribe pair are replaced by subscriptions/listen, a single long-lived POST response stream that clients opt into per notification type. Request-scoped notifications such as notifications/progress still flow on the response stream of the request they belong to. SSE stream resumability is gone: no Last-Event-ID, no event IDs, no redelivery. If a response stream breaks, the client re-issues the request with a new ID. ping, logging/setLevel, and notifications/roots/list_changed were removed outright, with log level now set per request through io.modelcontextprotocol/logLevel.
The most interesting redesign is Multi Round-Trip Requests, or MRTR. Previously, when a server needed something back from the client mid-call (a sampling request, an elicitation, the list of roots) it issued a server-initiated request over the held-open stream. That required the stream, and the stream is what just went away. Under MRTR, a server returns an interim result with resultType: "input_required" and an inputRequests field describing what it needs. The client answers by retrying the original request with inputResponses attached. Every result now carries a required resultType, either "complete" or "input_required", and clients must treat results from older servers that omit the field as complete.
Alongside that, Roots, Sampling, and Logging are formally deprecated, with suggested migrations: pass files and directories as tool parameters or resource URIs, call your LLM provider directly instead of asking the client to sample, and log to stderr or OpenTelemetry. The old HTTP+SSE transport, deprecated in prose since March 2025, is now deprecated under an actual policy.
Two changes that read as minor will matter more than they look. First, list and read results (tools/list, prompts/list, resources/list, resources/read, resources/templates/list) now carry required ttlMs and cacheScope fields, and servers should return tools in a deterministic order specifically so client-side caches and upstream LLM prompt caches stay warm. Second, Streamable HTTP POSTs must include Mcp-Method and Mcp-Name headers, so gateways, rate limiters, and WAFs can route and meter traffic without parsing JSON bodies.
Authorization got the enterprise treatment. Authorization servers should return the iss parameter per RFC 9207 and clients must validate it before redeeming a code, which closes the authorization server mix-up class of attack. Clients must declare an application_type during registration so desktop and CLI localhost redirects stop colliding with OIDC rules. Credentials are now explicitly bound to the issuer that minted them, with no cross-server reuse. And Dynamic Client Registration is deprecated in favor of Client ID Metadata Documents, though DCR keeps working for authorization servers that have not caught up.
Finally, the governance change that makes all of the above tolerable: a feature lifecycle policy with Active, Deprecated, and Removed states, a minimum twelve month deprecation window, and a public registry of deprecated features. Tasks moved out of experimental core into a versioned official extension (io.modelcontextprotocol/tasks), joining MCP Apps and Enterprise Managed Authorization under a real extensions framework with extensions fields on both client and server capabilities.
Why This Is a Major Change and Not a Point Release
Three reasons, in ascending order of importance.
The first is operational. Sessions were the reason an MCP server was a stateful web application rather than an HTTP endpoint. Sticky sessions, session stores, reconnect handling, and orphaned state cleanup are the tax you paid to run one at scale, and they were the source of a disproportionate share of production bugs. Sean Roberts, VP of Applied AI at Netlify, summarized the shift as making MCP a first-class HTTP workload. Serverless and edge deployment go from awkward to default. AWS shipped the stateless core in Bedrock AgentCore on the same cycle, and Microsoft published guidance on what it changes for scaling MCP on App Service. Infrastructure vendors moved fast here because this release solves their problem.
The second is that it removes features rather than adding them. Sampling, Roots, and Logging were the parts of MCP with the weakest client support and the most inconsistent behavior across implementations. Server authors could not rely on them, so most did not use them, so clients had little reason to implement them well. Deprecating them and replacing the server-initiated pattern with MRTR is a protocol conceding that it borrowed too heavily from the stdio and language-server world and not heavily enough from HTTP, where retry with more information is a thirty year old idea that works.
The third reason is the one that matters for planning. The deprecation policy and the extensions framework are an explicit promise that this is the last rewrite of transport and lifecycle for a while. The working group's stated expectation is that implementers targeting 2026-07-28 will adopt future revisions without rewriting their transport or lifecycle code again. New capabilities are supposed to arrive as opt-in extensions and prove themselves before touching the core. That is the difference between a protocol you experiment with and a protocol you build a five year integration strategy on.
The adoption numbers explain why the working group could afford to break things once and then commit to stability. Anthropic puts MCP SDK downloads at 400 million a month, roughly four times a year ago, with the TypeScript and Python SDKs each past a billion cumulative downloads. Claude's connector directory lists more than 950 MCP servers. A protocol at that scale gets exactly one window to fix its foundations, and the working group used it.
How the Market Is Reading It
The reception has been positive on the architecture and openly nervous about the migration, which is roughly the correct reaction.
On Hacker News, the strongest praise came from people who operate MCP infrastructure. One commenter running a server gateway and registry wrote that they could not tell what portion of their issues and bugs came down to the need to persist server state. Another put the design argument plainly: the server is there to serve requests, not to do the remembering, which is how HTTP worked from the beginning. Developers deploying into ephemeral environments treated the change as the removal of a blocker rather than a feature.
The criticism clusters in three places. The first is wire incompatibility in both directions, which means this is not an SDK version bump for anyone who used sessions. The same gateway operator estimated that only around thirty percent of indexed MCP servers are actively maintained, which implies a long tail of servers that will simply never migrate and an ecosystem that needs version-bridging proxies for a while. The second is versioning: date-based revision strings make it hard to reason about compatibility at a glance, and several developers asked for semver. The third is a broader impatience with churn, best captured by the commenter who described the original protocol as a pile of anti-patterns being slowly undone one at a time. That is unkind but not entirely wrong, and it is also what a healthy correction looks like.
Vendors voted with their release notes. GitHub shipped support for the new spec on July 23, five days ahead of the final publication, removing Redis-backed sessions from their server and moving logging and security scanning off deep packet inspection and onto the new headers. Their guidance to users was that all Tier 1 SDKs preserved backwards compatibility, so most people need to do nothing to keep working. The spec announcement carried endorsements from AWS, Cloudflare, Figma, Google Cloud, Microsoft, Netlify, PostHog, Stripe, Supabase, Xero, and others. All four Tier 1 SDKs (TypeScript, Python, Go, C#) supported the revision on day one, with Rust in beta. The release candidate was locked on May 21, giving implementers a ten week validation window before the final text, which is why the vendor response looks unusually coordinated.
The dissenting voice worth listening to is the security community. Akamai's threat research team, writing after the release, argued that the burden of enforcement has moved. Maxim Zavodchik, their senior director of threat research, put it as critical security boundaries now depending entirely on how developers implement them. Their specific concerns are worth quoting because they are concrete: without protocol sessions, the identifiers and handles that replace them become the attack surface, opening the door to hijacking an active workflow, reading data belonging to a different agent, or triggering cross-tenant actions. The new headers create their own risk, since custom header support via x-mcp-header means that if developers accidentally map sensitive inputs like API keys, tokens, or PII, those secrets are pushed straight into the headers where logs and intermediaries will happily record them. And long-running tasks are a denial of service vector, because task creation is cheap for the client and expensive for the server.
None of that is an argument against the spec. It is an argument that the spec moved work from the protocol to the implementer, and the implementer has to actually do it.
What It Means If You Build MCP Servers
Start by accepting that the migration is real work if your server used sessions for anything. The SDKs shipped compatibility wrappers, so a server that never depended on session identity will mostly come along for free. A server that stored a connection scoped cursor, an authenticated context, an open transaction, or a per-connection cache will not.
The replacement pattern is server-minted handles passed as ordinary tool arguments. A tool returns an opaque identifier, the model carries it into subsequent calls, and your server resolves it against durable storage. This is better than it sounds. Hidden session state was invisible to the model, which meant the model could not reason about it, could not thread it deliberately between tools, and could not recover when it went stale. An explicit handle is a value the model can hold and reuse. The catch, and the reason the Akamai warning lands, is that a handle is now a bearer token in everything but name. It needs to be unguessable, scoped to a tenant and a principal, validated on every single call, and expirable. The check the session used to do implicitly is now yours to do explicitly, on every request, with no exceptions.
Beyond that, the work sorts into four buckets. Rip out anything built on Roots, Sampling, or Logging, because the twelve month clock started on July 28, 2026, and new implementations should not adopt them. Migrate any held-open, server-initiated interaction to MRTR, which usually means restructuring a tool that asked for confirmation mid-call into one that can return input_required and be retried. Fill in ttlMs and cacheScope on your list and read results and return tools in a stable order, because that is the difference between clients re-fetching your tool list constantly and clients keeping their prompt caches warm, and it shows up directly in latency and token cost. And do the authorization work: validate iss, key persisted credentials by issuer, declare application_type, and plan the move from Dynamic Client Registration to Client ID Metadata Documents.
If you maintain a public MCP server, run the conformance suite, and support both revisions during the transition rather than cutting over. The client population will be mixed for at least a year.
What It Means for Companies Adopting MCP
If you consume MCP rather than build it, the release changes your cost structure, your governance options, and your rollout mechanics.
On cost, stateless servers are cheaper to run and easier to scale, and the caching hints reduce redundant traffic between clients and servers. The deterministic tool ordering requirement is a quiet but real token saving, since an unstable tool list invalidates the prompt cache on every reconnect and you pay to re-send the same definitions.
On governance, the header requirement is the underrated change. Because Mcp-Method and Mcp-Name are on the request, a gateway can route, rate limit, meter, and audit MCP traffic without parsing or logging request bodies. That is the difference between an MCP policy layer you can actually deploy in a regulated environment and one that requires inspecting payloads containing customer data. Combined with the authorization hardening, the protocol now fits the identity and network controls an enterprise security team already runs, instead of asking for exceptions.
On rollout, the Claude-side product work is aimed squarely at the two things that stall internal adoption. Enterprise Managed Authorization lets an administrator provision connectors across the organization through the existing identity provider, so access follows Entra or Okta group membership and end users get zero-touch setup instead of each person running an OAuth flow. MCP tunnels, currently a research preview, connect Claude to MCP servers on private networks with no public internet exposure, no inbound firewall rules, and no IP allowlisting, which removes the most common blocker for internal tools. Developers publishing connectors also get an observability dashboard covering adoption, errors, latency, and usage by product surface, and MCP Apps let a connector render interactive UI inline in the conversation rather than sending users to another tab.
The strategic read is simpler than any of that. The twelve month deprecation policy is the first time MCP has offered a planning horizon. If your reason for holding back on an internal MCP program was that the protocol kept moving under you, that objection just expired.
What We Would Do In The Next Sixty Days
First, inventory. List every MCP server you run or depend on, and mark each one by transport, by whether it holds per-connection state, and by whether it is actively maintained. The unmaintained third-party servers are your real risk, not your own code.
Second, pin and test. Target 2026-07-28 explicitly in new work, upgrade to the Tier 1 SDK release that supports it, and run the conformance suite against your servers before you change any application logic. Most of the transport work is already done for you inside the SDK.
Third, convert state to handles, and threat-model the handles the same day you introduce them. Tenant scoping and per-request validation are not follow-up tickets.
Fourth, do the cheap wins that pay immediately: deterministic tool ordering, ttlMs and cacheScope, and header hygiene so nothing sensitive gets mapped into x-mcp-header.
Fifth, leave the community servers alone for now. Adopt a bridging gateway if you need mixed-version interoperability, and revisit in a quarter when the long tail has caught up or visibly stalled.
The thing to avoid is treating this as a version bump because the SDKs made the easy part easy. The protocol handed a set of guarantees back to implementers. Whoever writes the server now owns them.
Working with Vindler
Vindler builds and operates production MCP deployments for companies that need agents connected to real internal systems, which means designing the tool surface, the authorization model, the tenancy boundaries, and the gateway policy as one thing rather than four separate afternoons of work. We covered our approach in MCP for Enterprises, and this release changes the deployment half of that guidance substantially.
If you are running MCP servers in production and want a migration plan that separates the SDK upgrade from the parts that actually need engineering, or you are evaluating an internal MCP program and want to know what the new authorization and tunneling options change about your rollout, book a call.
For more on how we build and run agent infrastructure, see our case studies or contact us directly.
Sources
Anthropic's announcement, MCP 2026-07-28 spec: stateless core, coming to Claude, July 28, 2026. The working group's release post, The 2026-07-28 Specification, and the earlier release candidate announcement from May 21, 2026. The full specification changelog, which is the authoritative list of every change quoted above. GitHub's changelog entry on shipping support ahead of the final spec, July 23, 2026. SecurityWeek's coverage of the security implications, including the Akamai threat research commentary. Community reaction from the Hacker News discussion thread.
Published July 29, 2026.




