MCP Stateless Protocol: What the July 28 Spec Actually Changes

The MCP 2026-07-28 spec dropped sticky sessions and the initialize handshake. Here is what breaks in production, what gets cheaper, and the one trade-off nobody is talking about.

Cover art for MCP Stateless Protocol: What the July 28 Spec Actually Changes

The previous stable MCP spec was dated 2025-11-25. The current one is 2026-07-28, final since July 28. If you run any remote MCP server in production, two things changed on that date that you cannot ignore. Everything else can wait twelve months. But those two things - the handshake and the session ID - are the reason teams spent days debugging what looked like network errors and turned out to be a protocol assumption baked into their load balancer config.

Why the old MCP spec fought production HTTP

Two failure modes drove the redesign. The stateful handshake was incompatible with the way production HTTP is actually deployed: load balancers had to parse JSON-RPC bodies to route, sticky sessions blocked autoscaling, and a single server restart blew up every in-flight session.

The original MCP spec required a session handshake on every new connection. Servers minted an Mcp-Session-Id that pinned each client to a specific instance. On paper, fine. In practice, a distributed deployment disaster. The failure mode was subtle and nasty: pod A handled initialize and issued the session ID, then the SDK's long-lived SSE GET stream silently hashed to pod B - which knew nothing about that session - and returned a 404. Teams spent days debugging what looked like a network issue. The real culprit was a protocol-level assumption that every connection lands on the same machine. The fix was load balancer stickiness, which is infrastructure duct tape over a spec problem.

The spec had also collected a year of operational debt: no standard caching metadata, no standard tracing format, no formal deprecation policy, and extensions like Tasks lived experimentally inside the core spec with no governance about how they would graduate or evolve.

The 2026-07-28 release fixes both problems in one sweep.

What the MCP stateless protocol actually removes and adds

The headline change is a stateless core: no initialize/initialized handshake (SEP-2575) and no Mcp-Session-Id header (SEP-2567). Every request now carries its own protocol version, client identity, and capabilities on _meta.

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, route traffic on an Mcp-Method header, and let clients cache tools/list responses for as long as the server's ttlMs permits.

Beyond the stateless core, the spec ships four other significant pieces:

  • Extensions framework. Extensions become a first-class capability, with an extensions field added to both ClientCapabilities and ServerCapabilities, so clients and servers negotiate optional extensions beyond the core protocol through that map.

  • MCP Apps. MCP Apps (SEP-1865) lets servers ship interactive HTML interfaces that hosts render in a sandboxed iframe. Tools declare their UI templates ahead of time, so hosts can prefetch, cache, and security-review them before anything runs. UI-initiated actions go through the same JSON-RPC audit and consent path as a direct tool call.

  • Tasks extension. Tasks moved from an experimental feature to an official extension after real-world production use drove a redesign. The new lifecycle is stateless by design: tools/call returns a task handle, and the client drives progress via tasks/get, tasks/update, and tasks/cancel. Notably, tasks/list is gone - without sessions, listing all tasks is not a safe operation to expose. If you built against the experimental Tasks API, you need to migrate to this lifecycle.

  • Auth hardening. The release candidate makes OAuth 2.1 resource-server alignment explicit - auth is no longer optional posture for remote servers.

Area Before 2026-07-28 After 2026-07-28
Session handling Mcp-Session-Id, sticky routing No session; capabilities on _meta every request
Load balancer Sticky sessions or shared store Plain round-robin, route on Mcp-Method header
Long-running work Experimental Tasks in core spec Tasks extension with handle-based lifecycle
Caching None standardized ttlMs on tools/list responses
Deprecated features Roots, Sampling, Logging active Deprecated; 12-month removal window
Transport HTTP+SSE first-class HTTP+SSE reclassified as Deprecated (SEP-2596)
Beagle in action#platform-eng, 10:22am
The ask
'our MCP server keeps dropping sessions after deploys - third time this week'
Beagle drafts
finds the thread, spots the Mcp-Session-Id dependency in the server code, drafts a reply linking the 2026-07-28 migration steps and the specific SEPs to remove
You approve
engineer hits approve; the fix path posts in 25 seconds with source links, not a 45-minute debugging rabbit hole
Do this in your workspace

The trade-off nobody is writing about

The framing around this release is almost entirely infrastructure-positive: cheaper hosting, serverless targets, horizontal scaling without the duct tape. That is all true. But there is a real trade-off buried one layer down.

Against the infrastructure gains, you own the state you used to get for free, and you lose stream resumability.

Application state did not disappear - it moved somewhere more honest. Tools now return explicit opaque handles (think a basket_id or job_id). The model can see these handles, reason about them, and pass them forward on subsequent calls. Your server stores actual state in Redis, PostgreSQL, or wherever makes sense.

This is the right design. Session-scoped state was hidden state - it lived implicitly on the server and the protocol papered over it. Handle-based state is visible state: the model has it, can reason about it, and can pass it forward. For a teammate like Beagle routing through multiple tools in one thread, an explicit handle is strictly better than a session the agent cannot inspect.

But the migration is not free. The most common thing that breaks in an MCP v2 migration is infrastructure built around session affinity - sticky load balancers, SSE-pinned clients, and any code that stored per-session state on the server.

Any server code that scopes state to a session ID - caches, workflow progress, per-conversation configuration - has no session to scope to. The migration pattern is to replace session-scoped state with explicit handles passed as tool arguments: the state moves into the request itself, not a server-side lookup keyed by connection.

MCP recently surpassed 400 million monthly SDK downloads, a 4x increase this year. That number matters here because it tells you the blast radius of this change: tens of thousands of servers written against the stateful spec, each one now carrying technical debt that compiles fine but breaks silently behind a load balancer.

What to actually do this week

The migration has two hard deadlines and one generous one.

Publishing the spec does not switch anything off for implementers still running the 2025-11-25 revision. What does require immediate code is the new stateless behaviour itself: the removal of the initialize and initialized handshake, and the removal of the Mcp-Session-Id header from Streamable HTTP. A server that wants to run behind a plain round-robin load balancer without sticky sessions has to make those two changes. A server that is happy where it is can schedule the rest, including migrations away from Roots, Sampling, Logging, and the legacy HTTP+SSE transport, against the deprecation window rather than against launch day.

Concrete steps, in order:

  1. Audit session-scoped state. Find every place your server reads or writes against an Mcp-Session-Id. That list is your migration scope.

  2. Convert to explicit handles. Anything scoped to a session should become a tool-argument handle, backed by whatever durable store you already run.

  3. Remove sticky routing. Once handles are in place, point the server at a plain round-robin balancer and run the load-balancer test: mint a session on instance A, route follow-up to instance B, confirm nothing breaks.

  4. Migrate tasks/list callers. If you surfaced a UI built on tasks/list, it needs a redesign. The endpoint is gone with no deprecation window.

  5. Plan the slow deprecations. Roots, Sampling, and Logging have a minimum 12-month window. The replacements: tool parameters or resource URIs for roots, direct LLM API integration for sampling, stderr or OpenTelemetry for logging.

  6. Pin the SDK. The 1.x line moves to maintenance mode with security fixes only, so if you're not ready this month, pin mcp>=1.28,<2 and come back to it.

Running an MCP server at scale
Without Beagle
sticky load balancer rules, shared session store in Redis, gateway deep-packet inspection, one server restart kills every in-flight session
With Beagle
plain round-robin balancer, state in explicit handles, Mcp-Method routing header, replicas crash-safe because there is no session to lose

All four Tier 1 SDKs shipped support alongside the spec on publication day.

TypeScript, Python, Go, C#, and Rust in beta, each with migration notes for the breaking changes. The spec itself is linked from the official MCP blog post. The changelog lists every change against 2025-11-25, which is the fastest way to scope exactly what your server needs to touch.

400Mmonthly MCP SDK downloads4x growth this year
22,311servers in the MCP ecosystemas of July 16, 2026 (PulseMCP)
12 monthsminimum deprecation windowfor Roots, Sampling, Logging
2SEPs that break immediatelySEP-2575 (handshake) and SEP-2567 (session ID)

MCP stateless protocol: common questions

What is the MCP 2026-07-28 stateless spec?

It is the largest revision of the Model Context Protocol since launch, published as final on July 28, 2026. The headline change removes the initialize handshake and Mcp-Session-Id header, making every request self-contained. Any server instance can handle any request, which means plain round-robin load balancing replaces sticky sessions.

What breaks immediately when migrating to MCP 2026-07-28?

Two things require immediate code changes: removing the initialize/initialized handshake dependency and removing Mcp-Session-Id from your server. Any session-scoped state must move into explicit handles passed as tool arguments. The tasks/list endpoint is also gone with no deprecation window. Everything else - Roots, Sampling, Logging - has at least a 12-month runway.

Can I still run my existing MCP server after July 28, 2026?

Yes. The 2025-11-25 specification keeps working, and the new formal deprecation policy guarantees a minimum 12-month overlap for features being phased out. Clients are expected to support both wire formats during the transition. The only urgency is if you want to drop sticky sessions and scale horizontally.

What is MCP Apps in the new spec?

MCP Apps is an official extension that lets servers ship interactive HTML interfaces rendered in a sandboxed iframe inside the host. Tools declare their UI templates ahead of time for prefetching and security review. UI actions flow through the same JSON-RPC channel as ordinary tool calls, so the audit path stays intact.

Does the stateless spec make MCP cheaper to run?

For hosting, yes - serverless and edge runtimes become viable targets for the first time because nothing needs to survive between invocations. But the migration itself is not free: any state previously scoped to a session must be moved to a durable store and surfaced via explicit handles. The protocol bill goes down; the engineering work goes up once.

Or just watch me work

Point me at your website.

I will read up on your business and come back with what I would run for you. No account, no card, about a minute.

I only read what is public. Nothing is saved to your name until you say so.

Keep reading

Beagle does this work for you, in your Slack.1,000 free credits. No card.Hire Beagle