The 2026-07-28 MCP spec is the biggest revision since the protocol launched, and it is not backward compatible. If you run a production MCP server, code stops working that day.
Most write-ups explain the why (MCP went stateless). But you need the what: which lines break, and what to change them to. Here are all seven changes, with before/after code and a grep you can run right now.
Key Takeaways
- The 2026-07-28 MCP spec removes sessions and the initialize handshake.
- Run these 7 greps against your src/ to find every breaking change, then migrate in order: sessions first, then handshake, then error codes.
1. The session is gone (SEP-2567)
The Mcp-Session-Id header and protocol-level session are removed. The transport is now stateless — any request can land on any server instance.
Upside: No more sticky sessions, shared session stores, or smart gateways. Run behind plain round-robin load balancing.
Cost: Anything reading/writing a session breaks.
// before — TS SDK
new StreamableHTTPServerTransport({
sessionIdGenerator: () => randomUUID(),
});
// after — no session id
new StreamableHTTPServerTransport({
sessionIdGenerator: undefined,
});
What lived in the session now travels in _meta on every request. Read protocol version, client info, capabilities per-request instead of by session id.
grep -rn "Mcp-Session-Id\|sessionIdGenerator\|sessionStore" src/
Need state across calls? Mint an explicit handle from a tool (a cart_id, a run_id) and have the model pass it back as an argument.
2. The initialize handshake is removed (SEP-2575)
No more initialize/initialized round trip. Without a session, there's no "connection time" to pin it to.
Capability data now arrives in _meta on each request. Move capability checks inline where you use them.
grep -rn "initialized\|onInitialize\|InitializeRequestSchema" src/
3. Error code -32002 becomes -32602 (SEP-2164)
The MCP-custom "resource not found" code now returns standard JSON-RPC -32602 (Invalid Params).
// before
throw new McpError(-32002, "Unknown resource");
// after
throw new McpError(-32602, "Unknown resource");
Check both your server throws and client matches:
grep -rn "32002" src/ test/
4. Two new required routing headers (SEP-2243)
Streamable HTTP transport now requires Mcp-Method and Mcp-Name headers. This lets load balancers route without reading the request body.
If you sit behind a proxy/gateway, make sure these headers pass through. If you hand-roll HTTP, set them.
5. ttlMs and cacheScope on list/read responses (SEP-2549)
Additive, not breaking. Set ttlMs on responses for free client-side caching. Worth a pass once the rest compiles.
6. Roots, sampling, and logging are deprecated (SEP-2577)
Still function on 2026-07-28, but on a 12-month runway to removal (July 2027).
- sampling: Replace with direct LLM API calls
- roots: Pass working context as tool inputs
- logging: Move to stderr or OpenTelemetry
grep -rn "createMessage\|ListRootsRequest\|sendLoggingMessage\|setLoggingLevel" src/
7. Tasks move to an extension (SEP-2663)
Tasks ship as a versioned extension instead of core. The redesign drops tasks/result for polling via tasks/get, adds tasks/update, and removes tasks/list.
grep -rn "tasks/list\|tasks/result\|CreateTaskRequest" src/
How to sequence the work
Do first (hard breaks, fail July 28): sessions (1), handshake (2), error code (3). Ship. Then headers (4), caching (5), deprecations (6, 7) on their longer runway.
Run all seven greps against your src/. They catch the obvious call sites in about two minutes. Read the hits — don't trust the count — but the punch list will be short.
Source: dev.to








