Everything in this guide is based on the official release-candidate announcement on the MCP blog, which lists every change by its SEP number. We cite the SEP for each change so you can verify it against the source instead of taking our word for it.
The timeline
The release candidate locked on May 21, 2026. The final spec ships on July 28, 2026. That is a ten-week validation window, and it exists for one purpose: so SDK maintainers, client vendors, and server operators can migrate against a frozen target instead of chasing a moving one. The changes below are locked — what you migrate to now is what ships.
| Date | Milestone |
|---|---|
| 2026-05-21 | Release candidate locked; the change set is frozen |
| May 21 → July 28 | Ten-week validation window for SDKs, clients, and servers |
| 2026-07-28 | Final spec ships; spec-tracking clients negotiate the new version |
If you operate a remote MCP server, the practical reading: you have until late July to get RC-clean without doing anything under pressure, and the clients your users connect from — Claude, Cursor, everything that tracks the spec — will expect the new protocol version once it is final.
Stateless core: the handshake and the session ID are gone (SEP-2575, SEP-2567)
SEP-2575 removes the initialize / initialized handshake. SEP-2567 removes the Mcp-Session-Id header and protocol-level sessions entirely. Together they make the core of the protocol stateless: no setup phase, and no identifier tying one request to the next.
Two mechanisms replace what the handshake used to do. First, protocolVersion, clientInfo, and capabilities now travel in _meta on every request — each request identifies itself instead of leaning on a session established earlier. A post-migration tool call is shaped roughly like this:
{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "render_pdf",
"arguments": { "document_id": "doc_8f3a" },
"_meta": {
"protocolVersion": "2026-07-28",
"clientInfo": { "name": "example-client", "version": "1.0.0" }
}
}
}Second, a new server/discover method replaces the upfront capability exchange — clients ask what a server supports when they need to know, rather than caching the answer from an initialize call.
What this breaks: anything keyed on the session ID. Auth context, caches, rate limits, an open-document pointer — if it lives under Mcp-Session-Id, it loses its anchor the moment clients stop sending the header. The fix is architectural, not mechanical: every handler becomes self-contained, and application state moves to explicit handles — a tool returns an identifier, and later calls pass it back as an ordinary argument.
// Before: state hangs off the protocol session (gone with SEP-2567)
sessions[mcpSessionId].document = doc;
// After: the tool mints an explicit handle...
return {
content: [{ type: "text", text: JSON.stringify({ document_id: "doc_8f3a" }) }],
};
// ...and every later call passes it back as a normal argument:
// tools/call { name: "append_page",
// arguments: { document_id: "doc_8f3a", ... } }If you run on a serverless platform that already builds a fresh server per request — the mcp-handler pattern on Vercel, for instance — you are most of the way there. The audit is for every place your application code reads the session ID.
Mandatory Mcp-Method and Mcp-Name headers (SEP-2243)
SEP-2243 makes two headers mandatory on streamable HTTP: Mcp-Method and Mcp-Name, mirroring the JSON-RPC method and name from the request body. Servers must reject requests where the headers and the body disagree.
The SDK upgrade handles generation and validation. What the SDK cannot handle is your infrastructure: a WAF, reverse proxy, or firewall rule that strips or blocks unknown Mcp-* headers will fail every request, and from the outside it will look like a client bug. Walk the full request path — CDN, WAF, proxy, load balancer — and confirm Mcp-* headers pass through untouched.
Multi-round-trip requests replace long-lived SSE (SEP-2260, SEP-2322)
Under SEP-2260, a server may only send requests to the client while it is actively processing a client request. The long-lived GET SSE stream as a push channel is over. SEP-2322 supplies the replacement — Multi Round-Trip Requests: a tool that needs more input mid-execution returns an InputRequiredResult, and the client answers with inputResponses, carrying requestState back so the server can resume without holding anything in memory between round trips.
What breaks: tools that push to the client outside an active request — progress streams over the standing SSE connection, server-initiated notifications, interactive flows built on the GET channel. The migration: design every tool to complete within a single request, and express genuinely interactive flows as InputRequiredResult round trips. If your server is serverless, this constraint will feel familiar — it is the same one your platform already imposes.
Resource-not-found becomes -32602 (SEP-2164)
A small change with an outsized blast radius in test suites: the resource-not-found error code moves from the custom -32002 to the standard JSON-RPC -32602.
| Spec | Resource not found |
|---|---|
| 2025-11-25 and earlier | -32002 (custom) |
| 2026-07-28 | -32602 (standard) |
Grep your server, any in-house clients, and every test for a hardcoded -32002. Treat error semantics, not magic numbers, as the contract.
Tasks gets a new lifecycle — as an extension (SEP-2663)
Tasks, the experimental long-running-work API from the 2025-11-25 revision, moves out of the core and into an extension with a changed lifecycle: tools/call returns a task handle, the task is driven through tasks/get, tasks/update, and tasks/cancel, and tasks/list is removed entirely.
If you built on the experimental 2025-11-25 tasks API, plan a real port — the lifecycle changed, it was not just relocated. If you have not, do not start now; build on the extension version once it is final.
Auth hardening (SEP-2468, SEP-837, SEP-2352, SEP-2207, SEP-2350, SEP-2351)
Six SEPs tighten the OAuth story:
- Clients must validate the
issparameter on authorization responses per RFC 9207. - The OIDC
application_typeis declared during Dynamic Client Registration. - Credentials are bound to the issuing authorization server's issuer.
- When a resource migrates between authorization servers, clients must re-register.
- Scope accumulation is clarified for step-up auth flows.
Most of the enforcement burden lands on clients — but a server can fail those new client checks. Server-side, three things matter: publish accurate RFC 9728 protected-resource metadata with stable authServerUrls; keep your issuer stable, because an issuer change now forces every client to re-register; and validate audience-bound tokens rather than accepting anything your authorization server ever minted.
Roots, Sampling, and Logging are deprecated (SEP-2577)
SEP-2577 deprecates three core features, each with a 12-month removal window and a designated replacement:
| Deprecated | Replacement |
|---|---|
| Roots | Tool parameters and configuration |
| Sampling | Direct LLM provider APIs |
| Logging | stderr and OpenTelemetry |
Deprecated is not removed — existing servers keep working. But anything new built on these three is born with a countdown attached. New servers should not touch them; existing servers should schedule the move early in the removal window, not at the end of it.
What does not break — and why the rush is still rational
The release also ships purely additive features that require nothing from you and are worth adopting on their own merits:
- SEP-2549 —
ttlMsandcacheScopeontools/list, so clients can finally cache tool lists instead of re-fetching them. - SEP-414 — W3C trace context in
_metaundertraceparent,tracestate, andbaggage: distributed tracing across the agent boundary. - SEP-2106 — full JSON Schema 2020-12 for input and output schemas, with the
type: "object"root still required for inputs. - SEP-2133 — the extensions framework, which is where the new tasks API lives.
And the most important non-breaking fact in the release: SEP-2596, the lifecycle policy, guarantees at least 12 months between a feature's deprecation and its removal. To be plain about what that means: a remote server shipped today against the 2025-06-18 or 2025-11-25 protocol keeps working after July 28. Current clients keep speaking it. Nothing is removed on day one, and nobody should tell you otherwise.
So why migrate during the validation window? Two reasons, neither of them panic. First, the deprecation treadmill: every revision you skip compounds, and the 12-month clocks on sessions, the handshake, Roots, Sampling, and Logging are already running — migrating late means doing all of it at once, under a deadline you no longer control. Second, expectations: clients and directories will treat RC readiness as the bar. Claude connectors directory review, client compatibility matrices, and the registries your users discover you through will all be checking against the new spec long before the old one is actually removed. Inside the window, you migrate on your own schedule against a frozen target. After it, you migrate on someone else's.
The migration checklist
This is the checklist we run against every server we migrate — including our own.
- Remove session-keyed state: grep for every read of
Mcp-Session-Idand replace it with explicit handles passed as tool arguments. - Make every handler self-contained — no in-memory state that has to survive between requests.
- Walk the request path (CDN, WAF, proxy, firewall) and confirm
Mcp-*headers pass through unstripped. - Confirm every tool completes within one request; rebuild push-style flows as
InputRequiredResultround trips. - Grep server, clients, and tests for hardcoded
-32002; expect-32602. - Stay off the 2025-11-25 experimental tasks API — and if you are on it, plan the port to the extension lifecycle.
- Audit auth: RFC 9728 protected-resource metadata accurate,
authServerUrlsand issuer stable, audience-bound token validation in place. - Remove — or schedule the removal of — Roots, Sampling, and MCP Logging in favor of their replacements.
- Schedule the SDK bump inside the validation window, before July 28 — not after.
Who is telling you this
We are MCP Migration Studio, and we run our own production remote MCP server: Slipstack's JSON→PDF API serves agents in production at https://slipstack.dev/mcp on exactly the stack described in this guide. Every item on the checklist above is something we run against our own server before we run it against a client's. That is the whole pitch: not an agency that read the changelog, but operators with the same deadline you have.