The Model Context Protocol ships its biggest update on Monday. The 2026-07-28 specification replaces the session-based architecture that has powered MCP since November 2024 with a stateless protocol that runs on ordinary HTTP infrastructure.
The release candidate has been locked since May 21. Tier 1 SDKs have had ten weeks to validate. Now server builders need to decide how to migrate.
Here is what changes, what breaks, and what you should do before the deprecation clock starts ticking.
Sessions Are Gone
The initialize/initialized handshake is removed. So is the Mcp-Session-Id header and the protocol-level session it carried. Every request in 2026-07-28 is self-contained.
In the previous spec (2025-11-25), calling a tool over Streamable HTTP meant establishing a session first. The server returned an Mcp-Session-Id, and every subsequent request had to carry it. This pinned the client to whichever server instance issued the session, forcing sticky routing and shared session stores for any horizontal deployment.
In 2026-07-28, a tool call is a single HTTP request. The protocol version, client info, and capabilities travel in _meta on every request. Any server instance can handle any request. Load balancers need nothing more than round-robin.
For servers that need state across calls, the pattern is explicit handles. A tool returns a basket_id or browser_id, and the model passes it back as an argument on the next call. This is the same pattern every stateless HTTP API uses, and it gives models more flexibility than hidden session state ever did.
New Headers Are Required
The Streamable HTTP transport now requires Mcp-Method and Mcp-Name headers on every request. Gateways, rate limiters, and load balancers can route on the operation without parsing the JSON-RPC body. Servers must reject requests where the headers and body disagree.
If you run an MCP server behind a reverse proxy or API gateway, check that your infrastructure passes these headers through. Most will by default, but any header allowlist configuration will need updating.
Extensions Get a Real Framework
Extensions existed before but had no formal process. Now they get reverse-DNS identifiers, negotiation through capability maps, dedicated repositories with their own maintainers, and independent versioning. A new Extensions Track in the SEP process gives them a path from experimental to official.
Two extensions ship with this release.
MCP Apps lets servers deliver interactive HTML interfaces that hosts render in a sandboxed iframe. Tools declare their UI templates ahead of time so hosts can prefetch and security-review them. Every action from the rendered UI goes through the same audit and consent path as a direct tool call.
Tasks moves from an experimental core feature to a proper extension. The lifecycle is rebuilt around stateless operation: a server answers tools/call with a task handle, and the client drives the task with tasks/get, tasks/update, and tasks/cancel. The previous tasks/list method is removed because it cannot be scoped safely without sessions. Anyone who shipped against the 2025-11-25 experimental Tasks API will need to migrate.
Authorization Gets Tighter
Six SEPs harden the authorization spec to match how OAuth 2.0 and OpenID Connect actually deploy in production.
The biggest practical change: clients must now validate the iss parameter on authorization responses per RFC 9207. This blocks a class of mix-up attacks that MCP’s single-client, many-server pattern is especially vulnerable to. A future version will reject responses that omit iss entirely, so authorization servers should start supplying it now.
Clients also declare their application_type during Dynamic Client Registration, fixing the common failure where a desktop or CLI client gets defaulted to "web" and its localhost redirect URI is rejected.
Three Features Are Deprecated
Roots, Sampling, and Logging are all deprecated in this release.
| Feature | What Replaces It |
|---|---|
| Roots | Tool parameters, resource URIs, or server configuration |
| Sampling | Direct integration with LLM provider APIs |
| Logging | stderr for stdio transports, OpenTelemetry for structured observability |
These are annotation-only deprecations. The methods and capability flags still work in this release and in every spec version published within the next twelve months. Removal requires a separate SEP under the new lifecycle policy. But the direction is clear: start planning your migration path now.
Tool Schemas Get Full JSON Schema 2020-12
Tool inputSchema and outputSchema are upgraded from a restricted subset to full JSON Schema 2020-12. Input schemas keep the type: "object" root constraint but now support oneOf, anyOf, allOf, conditionals, and $ref/$defs. Output schemas have no root constraint, and structuredContent can be any JSON value.
One caveat: implementations must not auto-dereference external $ref URIs, and should bound schema depth and validation time. This is a security measure to prevent resource exhaustion from recursive or hostile schemas.
Also: the error code for a missing resource changes from the MCP-custom -32002 to the JSON-RPC standard -32602 (Invalid Params). If your client matches on -32002, update it.
Caching and Tracing Are Built In
List and resource read results now carry ttlMs and cacheScope, modeled on HTTP Cache-Control. Clients know how long a tools/list response is fresh and whether it can be shared across users. A long-lived SSE stream is no longer the only way to detect when a list changes.
W3C Trace Context propagation is documented with fixed key names for traceparent, tracestate, and baggage in _meta. Distributed traces that start in a host application can now follow a tool call through the client SDK, the MCP server, and anything the server calls downstream. If you use OpenTelemetry, this connects your existing observability stack to MCP traffic.
The Deprecation Policy Protects What You Build
The spec now includes a formal feature lifecycle: Active, Deprecated, Removed. Every feature gets at least twelve months between deprecation and the earliest possible removal. Standards Track SEPs cannot reach Final status until a matching scenario lands in the conformance suite.
This is the governance change that matters most for anyone building on MCP long-term. The stateless rewrite needed a clean break. Future revisions are designed to avoid that. Server builders targeting 2026-07-28 should be able to adopt future spec versions without rewriting their transport or lifecycle code.
What to Do This Week
If you maintain an MCP server or client, here is your checklist:
-
Read the draft specification. The full release candidate is in the draft spec and the changelog lists every change against
2025-11-25. -
Remove session dependencies. If your server issues or consumes
Mcp-Session-Id, plan the migration to stateless operation. Replace session state with explicit handles returned from tools. -
Add the new headers. Make sure your Streamable HTTP implementation sends
Mcp-MethodandMcp-Nameon every request and validates them server-side. -
Audit deprecated features. If you use Roots, Sampling, or Logging, you have twelve months. Start scoping the replacement.
-
Update your Tasks integration. If you shipped against the
2025-11-25experimental Tasks API, the lifecycle is different now.tasks/listis gone. -
Check your auth flow. Validate
isson authorization responses. Setapplication_typeduring client registration.
The specification goes final on July 28. The twelve-month deprecation clock starts then.
FAQ
Q: Will my existing MCP server stop working on July 28?
A: Not immediately. The 2025-11-25 session-based approach will continue to work with clients that support it. But new SDK versions will target 2026-07-28, and the ecosystem will migrate. Plan your transition for the next few months, not the next few days.
Q: Do I need to rewrite my stdio transport?
A: No. The stateless changes primarily affect Streamable HTTP. Stdio transports are less affected, though the deprecation of Logging (replaced by stderr and OpenTelemetry) and the removal of the initialize handshake apply everywhere.
Q: What happened to server-sent notifications?
A: Server-to-client requests can now only happen while the server is processing a client request. Instead of holding an SSE stream open, servers return an InputRequiredResult and the client re-issues the call with the response. Any server instance can handle the retry because the state is in the payload.