The biggest MCP revision since launch ships July 28. Sessions and the initialize handshake are gone. If you shipped a remote MCP server fast, some of your transport assumptions break. Here's what changes and the checklist to migrate without a fire drill.
On July 28, the Model Context Protocol changes more than it has at any point since it launched. The lead maintainers locked the release candidate for 2026-07-28 on May 21 and called it "the largest revision of the protocol since launch." The headline: MCP is now stateless at the protocol layer. The initialize handshake is gone. The session is gone.
If you wired up a remote MCP server in the last year and moved on, some of your transport assumptions are about to stop being true. This is the post I'd want handed to me before the deadline: what actually changes, what breaks, and the checklist to migrate without a fire drill.
Stateless MCP means any request can land on any server instance, because everything the server needs to handle it now travels in that one request. There's no session pinning a client to the instance that first answered it, and no handshake that has to happen before real work starts.
Here's the old shape. In 2025-11-25, calling a tool over Streamable HTTP meant opening with an initialize request, getting back an Mcp-Session-Id, and carrying that header on every subsequent call — which pinned you to whichever instance issued it. That's why horizontally-scaled MCP deployments needed sticky load balancing and a shared session store.
In 2026-07-28, the same tool call is a single self-contained request. The protocol version, client info, and capabilities that used to be exchanged once at connection time now ride in _meta on every request, and a new server/discover method lets a client fetch server capabilities when it wants them up front. Two SEPs do the demolition: SEP-2575 removes the initialize/initialized handshake, and SEP-2567 removes the Mcp-Session-Id header and the protocol-level session.
The operational payoff is real and it's the reason this is worth your attention even if you're not deep in the spec: a deployment that previously needed sticky routing, a Redis cluster to share session state, and a gateway smart enough to parse request bodies for session IDs can now run as a plain deployment behind a dumb round-robin load balancer. Less infrastructure, fewer moving parts, less to break at 2am.
Removing the protocol session does not mean your application has to forget everything between calls. It means the protocol stops managing that state for you, and you manage it the way HTTP APIs always have: mint an explicit handle.
A tool returns a basket_id or a browser_id, and the model passes it back as an ordinary argument on the next call. The maintainers argue — and I agree after seeing it in practice — that this is often better than hidden session state, because the handle is visible to the model. It can compose handles across tools, reason about them, and thread them between steps in ways that session state buried in transport metadata never allowed.
If your server leaned on the session to remember who was doing what, this is the part of the migration that takes actual design work. Everything else on the list below is mostly mechanical. This isn't.
This release contains breaking changes. Here's the set that will touch a typical small-team deployment.
The handshake and session are gone. Covered above — initialize/initialized and Mcp-Session-Id both removed. If your client or gateway assumes either exists, it breaks.
Two new required headers. The Streamable HTTP transport now requires Mcp-Method and Mcp-Name headers (SEP-2243) so load balancers, gateways, and rate-limiters can route on the operation without cracking open the body. Servers reject requests where the headers and body disagree. If you run a proxy or gateway in front of your servers, make sure it passes these through and doesn't strip them.
Caching is now explicit. List and resource-read results carry ttlMs and cacheScope (SEP-2549), modeled on HTTP Cache-Control. A client now knows exactly how long a tools/list response is fresh and whether it's safe to share across users — and a long-lived SSE stream is no longer the only way to learn a list changed.
Server-to-client requests are restructured. A stateless protocol still needs a way for a server to ask the client something mid-call (an elicitation, a confirmation). Instead of holding an SSE stream open, the server returns an InputRequiredResult with a requestState blob; the client gathers answers and re-issues the original call with inputResponses and the echoed state (SEP-2260, SEP-2322). Any instance can pick up the retry because everything it needs is in the payload.
Tasks moved and tasks/list is gone. Tasks shipped as an experimental core feature in 2025-11-25. It now graduates to an extension with a reshaped lifecycle: a server can answer a tools/call with a task handle, and the client drives it with tasks/get, tasks/update, and tasks/cancel. tasks/list is removed because it can't be scoped safely without sessions. If you shipped against the experimental Tasks API, you migrate to the new lifecycle.
Roots, Sampling, and Logging are deprecated. Under the new feature-lifecycle policy (SEP-2577), these three are annotation-only deprecations — they still work in this release and in every version published within a year of it. Replacements: tool parameters or resource URIs for Roots, direct LLM-provider APIs for Sampling, and stderr/OpenTelemetry for Logging. Nothing breaks today, but stop building new work on them.
One error code changed. The "resource not found" error moves from MCP's custom -32002 to the standard JSON-RPC -32602 Invalid Params (SEP-2164). If any client code matches on the literal -32002, update it. This is the kind of one-line assumption that silently breaks a retry path.
Tool schemas get more powerful. Tool inputSchema and outputSchema are lifted to full JSON Schema 2020-12 (SEP-2106) — composition (oneOf, anyOf, allOf), conditionals, and $ref/$defs. Not breaking, but worth knowing if your tool definitions were fighting the old constraints.
The auth changes in this release land at the same time the U.S. government is telling everyone their MCP auth is too loose. On May 20, 2026 — the day before the RC locked — the NSA's AI Security Center published a Cybersecurity Information Sheet, "Model Context Protocol (MCP): Security Design Considerations for AI-Driven Automation" (U/OO/6030316-26). Its blunt finding: MCP doesn't define how a session maps to a verifiable identity, authentication is optional rather than required, role-based access control isn't part of the protocol, and many production servers ship with no auth at all. Its recommendations: treat every session as untrusted until verified, enforce least-privilege tokens per action and tool, and require signed provenance for any dynamically discovered server.
Going stateless makes that advice more load-bearing, not less. When there's no session to anchor identity to, every request has to carry and prove its own authority. The 2026-07-28 release hardens authorization across six SEPs to align with how OAuth 2.0 and OpenID Connect actually get deployed. The two changes most likely to bite a small team: clients must now validate the iss parameter on authorization responses per RFC 9207 (SEP-2468) — a cheap fix for a mix-up attack that's more likely in MCP's single-client, many-server pattern — and clients now declare their OpenID Connect application_type during Dynamic Client Registration (SEP-837), which fixes the common case where an auth server defaults a CLI client to "web" and rejects its localhost redirect.
If you haven't read it yet, our take on the April stdio injection mess — your MCP servers are production infrastructure, treat them like it — pairs with this. The migration is the moment to fix both at once.
Most servers need a focused pass, not a rewrite. Here's the order I'd run it in.
Inventory. List every MCP server you run or depend on, and which spec version each speaks today. You can't migrate what you can't see — and vendor-operated servers count, because their behavior changes under you.
Upgrade the SDK. If you're on a Tier 1 SDK — the Anthropic-maintained Python and TypeScript SDKs — most of the transport changes get hidden for you once it ships RC support. The maintainers expect Tier 1 SDKs to land support inside the ten-week validation window before July 28. If you control both client and server, migrate as soon as your SDK ships that support.
Kill session assumptions. Drop any reliance on Mcp-Session-Id. Where you genuinely need cross-call state, move it to explicit handles the model passes back as arguments. This is the only step that's real design work — budget for it.
Fix your edge. Make sure your gateway, proxy, or load balancer emits and forwards the new Mcp-Method and Mcp-Name headers, and stops requiring sticky routing. The reward is being able to run behind a plain round-robin balancer.
Add cache metadata. Emit ttlMs and cacheScope on your tools/list and resource-read responses so clients cache correctly instead of polling.
Migrate Tasks. If you used the experimental Tasks API, move to the extension lifecycle and stop calling tasks/list.
Grep for -32002. Update any client that matches the old missing-resource error code; switch to -32602.
Harden auth. Validate iss on auth responses, declare application_type in registration, and — per the NSA guidance — scope tokens to least privilege per action and tool. Treat every request as untrusted until verified.
Flip the version on ratification. When the spec finalizes on July 28, set your servers' declared protocol version to 2026-07-28. Keep deprecated features (Roots, Sampling, Logging) functional — the lifecycle policy guarantees at least twelve months before anything can be removed, so there's no rush to rip them out.
Test against conformance. A Standards Track change can't reach Final until a matching scenario lands in the conformance suite. Use it to validate your servers instead of trusting that "it still seems to work."
If you're a builder running remote MCP servers, this is a breaking change with a silver lining. The transport assumptions you shipped against are changing, but the new model is simpler to operate — no sticky sessions, no shared session store, no body-parsing gateway. The work is front-loaded into one migration; after it, your deployment is plainer and cheaper to run. That's the kind of thing an operator stack is supposed to make routine rather than dramatic, and where keeping your environment's context in something like Operator Vault pays off — the migration is a documented, repeatable change instead of tribal knowledge.
If you're an SMB that bought agent tooling, you mostly don't touch this directly — but your vendors do, and their infrastructure is shifting underneath you between now and late July. Worth one email to anyone whose product speaks MCP: are you targeting 2026-07-28, and does anything change for us? The ones who answer crisply are the ones who'll still be reliable in six months.
What does it mean that MCP is stateless?
It means any MCP request can be handled by any server instance, because everything the server needs travels in that one request. As of the 2026-07-28 specification there's no protocol-level session pinning a client to one instance and no initialize handshake before work starts — the protocol version, client info, and capabilities ride in _meta on every request. The practical result is that MCP servers can run behind an ordinary round-robin load balancer without sticky routing or a shared session store.
When does the stateless MCP spec ship?
The release candidate for MCP 2026-07-28 was locked on May 21, 2026, and the final specification ships on July 28, 2026. The ten weeks between are a validation window for SDK maintainers and client implementers; Tier 1 SDKs (Anthropic's Python and TypeScript SDKs) are expected to ship support within it.
What are the breaking changes in MCP 2026-07-28?
The biggest are the removal of the initialize/initialized handshake (SEP-2575) and the Mcp-Session-Id header and protocol session (SEP-2567). Also breaking: Streamable HTTP now requires Mcp-Method and Mcp-Name headers (SEP-2243), the experimental Tasks API moves to an extension with tasks/list removed, and the missing-resource error code changes from -32002 to -32602 (SEP-2164). Roots, Sampling, and Logging are deprecated but still functional for at least twelve months.
Do I have to rewrite my MCP server?
Usually no. Most servers need a focused migration: upgrade to an RC-supporting SDK, drop Mcp-Session-Id assumptions and use explicit handles for any state, forward the new routing headers, add ttlMs to list responses, migrate experimental Tasks, and harden auth. The only part that's genuine design work is replacing session state with explicit handles the model passes between calls.
What replaces sessions in stateless MCP?
The explicit-handle pattern. A tool returns an identifier — a basket_id, a browser_id — and the model passes it back as a normal argument on later calls. The protocol no longer manages that state, but your application still can; the difference is the state is now visible to the model instead of hidden in transport metadata, which lets the model compose and reason about it.
Is stateless MCP more or less secure?
Neither by itself, but it raises the stakes on authentication. With no session to anchor identity to, every request must carry and prove its own authority. The 2026-07-28 release hardens authorization across six SEPs (including iss validation per RFC 9207), and the NSA's May 2026 guidance recommends treating every MCP session as untrusted until verified and scoping tokens to least privilege per action. Do the auth work as part of the migration, not after.
Running MCP servers in production and staring down the July 28 deadline? That's exactly the kind of work a Last Mile production-hardening sprint is built for — we inventory what you run, migrate it to the stateless model, harden the auth, and leave you with documentation instead of a guess. Start with a Workflow Audit and we'll give you a straight read on what breaks and what it takes to fix. Receipts over slideware.