The MCP spec is dropping session state and that breaks real deployments

The release candidate for MCP 2026-07-28 removes the initialize handshake and the Mcp-Session-Id header. If you run remote MCP servers today, you have work to do before July 28.

Picture a pair of ASP.NET Core pods sitting behind a round-robin load balancer. Pod A handles the initialize request and mints a session ID. The client's follow-up SSE stream lands on pod B, which has never heard of that session, and returns a 404. The client throws a timeout. The standard fix is sticky sessions - a load-balancer annotation that pins a client to one pod for the life of a connection. It works, but it is an infrastructure workaround stapled over a protocol that was designed for local use and then deployed at scale before it was ready for it.

The MCP 2026-07-28 release candidate, published by lead maintainers David Soria Parra and Den Delimarsky on May 21, removes that problem at the source. The headline change is that MCP is now stateless at the protocol layer, with six Specification Enhancement Proposals working together to get there. The final specification is due July 28.

What actually changed

In previous MCP versions, a Streamable HTTP client established a session first. The server returned an Mcp-Session-Id, and the client carried that ID into later requests. That meant deployments had to care about sticky sessions, shared session stores, and gateway behavior that understood enough about MCP to route traffic correctly.

With the release candidate, a request like tools/call can be self-contained. The protocol version, client info, and capabilities travel with the request. Headers like Mcp-Method and Mcp-Name let infrastructure route traffic without inspecting the body.

That last point is understated in most of the coverage. The routing headers are arguably the most underrated change in this release. Every gateway vendor at the AAIF MCP Dev Summit in April 2026 - Kong, Docker, Solo.io, Uber's internal platform - was reverse-engineering tool names out of request bodies. That goes away on July 28.

The practical effect: a remote MCP server that previously needed sticky sessions, a shared session store, and deep packet inspection at the gateway can now run behind a plain round-robin load balancer.

The Tasks extension migration is the other breaking change

Tasks shipped as an experimental core feature in the 2025-11-25 spec. Production use surfaced enough redesign that the right home for it is an extension rather than the specification. The Tasks extension reshapes the lifecycle around the stateless model: a server can answer tools/call with a task handle, and the client drives it with tasks/get, tasks/update, and tasks/cancel. Task creation is server-directed - the client advertises the extension and the server decides when a call should run as a task.

Anyone who shipped against the experimental Tasks API in the 2025-11-25 spec needs a migration. The wire format changed.

What is genuinely new versus incremental

The stateless core is genuinely new. The protocol has offered optional statelessness in some SDK transports for a while, but many SDKs already offered a stateless option in their server transport configuration, though the behavior varied across implementations - as part of this roadmap, the maintainers are standardizing what "stateless" means across all official SDKs to ensure consistent behavior. Standardization is the work. The ambiguity is what made the sticky-session workaround so common.

The extensions framework is also genuinely new in governance terms. MCP gains a real extension system in this release: extensions are identified by reverse-DNS IDs, live in their own ext-* repositories with their own maintainers, and are negotiated through an extensions map on the client and server capability advertisements. They version independently of the core spec. Previously, every new capability had to fight for space in the core. That bottleneck is what slowed down Tasks and MCP Apps.

The RC also brings authorization hardening, deprecations for Roots, Sampling, and Logging, and full JSON Schema 2020-12 for tools. Those matter, but they are refinements, not architecture changes.

What the hype gets wrong

Most write-ups frame this as MCP becoming production-ready. That framing is too clean. Over the past year MCP has moved well past its origins as a way to wire up local tools - it now runs in production at companies large and small and powers agent workflows. Production use is already happening; this release just makes it less expensive to operate. The difference is meaningful but it is not a gate.

The hype also skips the migration cost. The 2026-07-28 RC is a real breaking migration for infrastructure-heavy MCP deployments. Local toy servers may barely notice. Remote multi-tenant servers will. If your team built an MCP server over the last year and it runs remotely over HTTP, you have session assumptions in it that need to surface before July.

What to do now

The honest split is:

  • Local stdio servers only: Track the RC, but the current 2025-11-25 spec is probably enough for the next few weeks.

  • Remote HTTP servers with Mcp-Session-Id dependencies: Start a migration branch now. The explicit-handle pattern works today and survives the upgrade - nothing in SDK 1.3.0 stops you from writing tools that mint a handle and require it on every later call. When 2026-07-28 ships, delete one ingress annotation and the same code keeps running.

  • Servers using experimental Tasks: The lifecycle changed. Plan for migration to the extension-based lifecycle.

  • Custom OAuth/OIDC auth: Check your auth implementation against the tightened OAuth and OIDC guidance before the final spec lands.

This release gives MCP the foundation it expects to grow on for a long time: a protocol that runs statelessly on commodity HTTP infrastructure, an extensions framework where capabilities like Tasks and MCP Apps can ship on their own timeline, and a lifecycle policy that lets implementers build on 2026-07-28 knowing what they ship will keep working.

The session-state problem was always going to have to be solved. It just took enough production deployments to make the pain visible.