If you've deployed an MCP server behind a load balancer in the last two years, you've probably built some version of the same thing: a sticky-routing rule keyed on Mcp-Session-Id, a Redis instance to hold session state so a pod restart doesn't strand a client mid-conversation, and — if your cloud load balancer doesn't support header-based affinity, which the AWS ALB and Google Cloud Load Balancer both don't out of the box — a reverse proxy layer just to make sticky routing possible at all.
The MCP specification finalizing on July 28, 2026 deletes the thing all of that infrastructure exists to route around. The Mcp-Session-Id header is gone. There is no more handshake. Every request carries its own protocol version, client identity, and capabilities. Any server instance can answer any request. That's not a tuning knob — it's the headline change in what the MCP maintainers are calling the largest revision to the protocol since it launched.
What You Used To Have To Build
MCP's original transport design treated a client-server exchange like a phone call: a client opened a session, the server issued an Mcp-Session-Id, and every subsequent request on that session had to land on the same server process — because that process, and only that process, held the negotiated capabilities and connection state in memory.
That requirement is exactly what session affinity in Kubernetes is bad at solving. IP-based affinity breaks down under NAT and mobile proxies. When the pod holding a session restarts — which is routine, not exceptional, in a Kubernetes cluster — the session is gone and the client has to restart its workflow from scratch. And because affinity ties a client's entire request stream to one pod, sticky routing creates exactly the load imbalance you'd expect: newly scaled-up pods sit idle while established sessions keep hammering the pods that already hold them, undermining the point of scaling out in the first place.
The production-grade fix teams converged on was a shared session store — typically Redis — where a server serializes negotiated capabilities and auth context on session creation, and any pod that receives a request can look the session up, act on it, and write state back. That works, but it's a second stateful system a team now owns just to keep a protocol-level handshake alive: another thing to provision, monitor, and fail over, sitting entirely upstream of whatever the MCP server actually does.
The Architecture Change, Concretely
Here's the same deployment, before and after the 2026-07-28 spec:
| Before (session-based) | After (stateless core) | |
|---|---|---|
| Routing | Sticky, keyed on Mcp-Session-Id; needs nginx/HAProxy/Envoy or a proxy layer in front of an ALB/GCLB that can't do header affinity natively | Plain round-robin — any instance can serve any request |
| Session state | Held in-process, or in a shared Redis store your team runs | None — protocol version, client identity, and capabilities travel in _meta on every request |
| Pod restart | Client's session is lost, workflow restarts | No effect — the next request just lands wherever the load balancer sends it |
| Gateway routing | Requires deep packet inspection of the JSON-RPC body to route by operation | Mcp-Method and Mcp-Name headers on every Streamable HTTP request — a gateway routes and rate-limits without opening the payload |
Repeated tools/list calls | No freshness contract — clients either re-fetch every time or cache blind | Each list/read result carries a ttlMs and a cacheScope (public or private), so a client knows exactly how long a response is good for and whether it's safe to share across users |
The mechanism behind the top row is a new server/discover method: a client fetches server capabilities on demand instead of negotiating them once at connection time and hoping the process it negotiated with is still the one handling its next request. Combine that with _meta riding on every call, and the server literally cannot tell whether two requests came from the same TCP connection, the same pod, or the same day — which is exactly the property that makes round-robin routing correct instead of merely convenient.
The Migration Checklist
The release candidate locked May 21, 2026, giving a ten-week conformance window before the spec ratifies July 28. If you're running an MCP server in production, six changes are load-bearing:
- Drop
Mcp-Session-Idassumptions. Any in-process state your server keyed off the session header needs an explicit handle passed by the client instead — there is no more implicit session to lean on. - Emit
Mcp-MethodandMcp-Nameon every Streamable HTTP request. These aren't optional metadata; omitting them causes requests to fail outright once the final spec lands. - Migrate long-lived SSE
GETstreams to the Multi Round-Trip Request pattern — a server returnsInputRequiredResultwith an opaquerequestState, and the client echoes it back on the follow-up call instead of holding a connection open. - Move Tasks off the deprecated core path. Tasks is now a separate extension with its own polling lifecycle (
tasks/get,/update,/cancel); the oldtasks/listmethod is gone. - Add
ttlMsandcacheScopeto list and resource-read responses so clients can cache correctly instead of guessing. - Harden OAuth 2.1 flows against the new SEPs — clients must validate the
issparameter on every authorization response per RFC 9207 (mitigating mix-up attacks where one authorization server's response gets replayed against another), and declare an OpenID Connectapplication_typeduring dynamic client registration.
Everything marked deprecated — Roots, Sampling, Logging as of this release — still works, and the spec's formal deprecation policy guarantees a minimum twelve-month window before anything is actually removed. This isn't a flag day; it's a runway.
It's also not an isolated fix. The same release bundles MCP Apps (server-rendered UI components a client can render inline, rather than a wall of text describing what a tool did) and a formalized Extensions framework for shipping capabilities like Tasks outside the core spec's own change cadence. Read together, the pattern is a protocol maturing past its original single-process, single-connection assumptions toward something that behaves like ordinary HTTP infrastructure — cacheable, statelessly routable, versioned with a real deprecation contract. Statelessness is the piece that happens to be a straight infrastructure removal; the rest is more product surface than plumbing.
What This Actually Buys a Fleet-Managed Platform's Own MCP Server
For a platform whose whole pitch is that an AI agent should be able to deploy, roll back, or check the status of a running service through the same conversational interface a developer already uses, this change lands directly on the control plane's own MCP surface. Deploy, rollback, and status tools that used to need a pinned instance — because that instance held the session — can now sit behind a plain round-robin load balancer across every node in the fleet. A "what's the status of this deploy" call doesn't care which control-plane pod answers it anymore, and neither does the client asking.
That's a real simplification, not a marginal one: it deletes a Redis dependency and a sticky-routing layer that existed purely to serve a protocol requirement, not a product requirement. But it's worth being precise about what it doesn't touch. Auth propagation — proving that the agent calling deploy is scoped to the tenant it claims to be operating on — is a harder problem today than it was before this release, because the new OAuth SEPs raise the bar on what correct token validation looks like, not lower it. And an audit trail for an agent-triggered production mutation was never a protocol-session concern in the first place; the spec change doesn't create one, and it doesn't excuse a platform from building one. Removing the session ID makes an MCP server's plumbing boring. It says nothing about whether the actions that plumbing carries are ones you'd be comfortable explaining to an auditor after the fact.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own, with a deploy/rollback/status MCP surface built for exactly the fleet-wide, no-pinned-instance model this spec change makes the default. Star the repo on GitHub or deploy your first app today.
Sources
- The 2026-07-28 MCP Specification Release Candidate — Model Context Protocol Blog
- MCP 2026-07-28: The Stateless Release Candidate, Explained — MCP.Directory
- MCP Spec 2026-07-28 Release Candidate: Six Breaking Changes and What Every Production Server Must Do Before July 28 — ChatForest
- The Biggest MCP Spec Update Ships July 28: What Changes for AI Agent Authentication — WorkOS
- MCP Just Went Stateless — What the 2026 Spec Changes About Scaling on App Service — Microsoft Community Hub
- Scaling HTTP Streamable MCP Servers on Kubernetes: Handling Sticky Sessions — Zhimin Wen