A leading product engineering company, creating adaptive software solutions to improve operations, providing businesses with expert development services from across domain.

A leading product engineering company, creating adaptive software solutions to improve operations, providing businesses with expert development services from across domain.

Mobile App Development

MCP specification breaking changes: sessions are gone

The MCP specification breaking changes of 28 July 2026 remove the handshake and session header, harden authorization, and start a 12-month deprecation clock.

MCP specification breaking changes: sessions are gone

The Model Context Protocol specification finalised on 28 July 2026 contains real MCP specification breaking changes, and the largest one is an absence. The initialize and initialized handshake is gone. So is the Mcp-Session-Id header, and with it protocol-level sessions altogether.

If you built a remote MCP server this year, some of your infrastructure exists only to serve a requirement that no longer exists.

Stateless, and what that deletes

The protocol version, client info and client capabilities that used to be exchanged once at connection time now travel in _meta on every request. A new server/discover method lets a client fetch server capabilities proactively rather than receiving them as a handshake reply.

The consequence is stated plainly in the release announcement: 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.

Read that as an infrastructure bill. Sticky routing is a constraint that propagates: it shapes your load balancer configuration, your autoscaling behaviour, your deployment strategy, and what happens to in-flight work when a pod is replaced. Teams paid that cost because the protocol required it. It no longer does.

State has not disappeared, it has moved up a layer, and the specification is explicit about the intended pattern: the model calls create_basket, the server returns a basket_id, and the model passes that same basket_id back as an argument to later calls. Explicit handles rather than implicit sessions. That is a better design for a system where the client is a language model, because a handle in an argument is visible in the transcript and a session on the wire is not.

One caveat worth stating before anyone celebrates. Stateless at the protocol layer does not mean stateless at the application layer, and a server that has been quietly keeping per-connection context in memory — an authenticated user, a selected tenant, a cursor — now has nowhere to keep it. Those are the servers where this upgrade is a redesign rather than a version bump, and they are easy to identify: if two consecutive requests from the same client must reach the same process to behave correctly, you have found one.

Six changes to authorization, and none of them optional

Six specification enhancement proposals harden authorization to match how OAuth is actually deployed. They are individually small and collectively a real migration.

  • SEP-2468 — clients must validate the iss parameter on authorization responses, per RFC 9207. This closes a mix-up attack where a response from one authorization server is accepted as though it came from another.
  • SEP-837 — clients declare an OpenID Connect application_type during Dynamic Client Registration.
  • SEP-2352 — credentials bind to the issuing authorization server's issuer, so a credential cannot be replayed against a different one.
  • SEP-2207 — documents how refresh tokens are requested from OpenID Connect style servers.
  • SEP-2350 — clarifies how scopes accumulate during step-up.
  • SEP-2351 — clarifies the .well-known discovery suffix.

The pattern is worth naming. None of these adds a feature; every one removes an ambiguity that a permissive implementation could have resolved insecurely. That is what a specification looks like when it stops being new. If your server was written against an earlier revision and your client was written by someone else against a different one, the interoperability you have today may be resting on both of you having guessed the same way.

It is also a reasonable moment to ask whether your server should be doing authorization at all, or whether it should sit behind a gateway that already does. Six SEPs' worth of OAuth subtlety implemented once, correctly, in a component your security team already reviews is a better outcome than the same logic reimplemented in each of four MCP servers by whoever was free that sprint. The specification pushes toward standard OAuth deployment precisely so that this is possible.

The smaller changes that will still break you

Two items are easy to miss in a release note and awkward to find in production.

The Tasks feature moved from the core experimental specification to an extension, with a redesigned lifecycle built around statelessness: servers answer tools/call with task handles, and clients drive progression through tasks/get, tasks/update and tasks/cancel. The tasks/list method is removed. Anyone who shipped against the earlier experimental Tasks API has a migration rather than an upgrade.

The Tasks change is worth a second look if you run anything long-running, because the new shape is better suited to it. A task handle returned from tools/call survives a client reconnecting, a load balancer moving traffic, or a process restarting, none of which a connection-scoped task did reliably. Losing tasks/list costs you the ability to enumerate work, so if your product surfaces a list of in-flight jobs you now own that index yourself.

And the error code for a missing resource changes from the MCP-specific -32002 to the JSON-RPC standard -32602, Invalid Params. This is the change most likely to pass every test you have and fail in the field, because client code that branches on -32002 will simply stop recognising a condition it used to handle. Grep for the literal before you upgrade anything.

There is a practical sequencing trap here too. Dynamic Client Registration changes and issuer binding touch the parts of the system where a mistake locks everyone out rather than letting the wrong person in. Test the registration path against a staging authorization server before the client changes ship, and keep the old credentials valid through the transition, because rotating credentials and changing how they are validated in the same deployment leaves you with no way to tell which half failed.

Three features on a twelve-month clock

Roots, Sampling and Logging are deprecated under SEP-2577 with minimum twelve-month windows before removal. They keep working throughout that period, which is precisely why they are dangerous — nothing forces the conversation.

  • Roots gives way to tool parameters, resource URIs or server configuration.
  • Sampling gives way to integrating an LLM provider API directly.
  • Logging gives way to stderr for stdio servers and OpenTelemetry for structured observability.

The Logging replacement is the one we would act on first, and not because of the deadline. Structured observability through OpenTelemetry is what you need anyway the moment an MCP server is doing something a customer depends on, and swapping a protocol log channel for a real telemetry pipeline is a change that pays for itself independently of any deprecation.

Planning for the MCP specification breaking changes

A sensible order of work, for a team running MCP servers in production.

  1. Search for -32002 across every client and server you own. Ten minutes, and it is the cheapest bug you will prevent this quarter.
  2. Inventory which revision each component targets. Servers, clients, and any SDK you have pinned. Tier 1 SDKs were expected to ship support within the validation window, so check your dependency versions rather than assuming.
  3. Take the authorization changes as one piece of work. Six SEPs touching registration, issuance and validation is a single focused change, not six scattered ones, and splitting it across sprints is how half-migrations happen.
  4. Only then remove the sticky-session infrastructure. It is the most satisfying item and the one with the least urgency. Deleting a load balancer rule while your servers still assume sessions is how a quiet upgrade becomes an incident.
  5. Move Logging to OpenTelemetry. Independently valuable, and it takes the longest.

Both of those are cheap to get right in advance and expensive to diagnose afterwards, which is the general character of this release: nothing here is conceptually hard, and almost all of it fails quietly.

The wider point is about what MCP has become. A protocol that removes its own handshake, standardises its error codes and publishes twelve-month deprecation windows is a protocol being run for operators rather than for demos. That is good news if you are integrating it into something that has to stay up, and it is a reason to hold your own tool definitions and prompts in version control so that a spec revision is a reviewable diff rather than an archaeology exercise.

It also sharpens the build-versus-buy question. A managed runtime absorbs some of this churn on your behalf, which is one of the honest arguments in favour of the OpenAI Agents API and its equivalents — though the authorization and sandbox posture stays yours either way, for the reasons we set out about what an agent's environment can reach. If you want a second pair of eyes on an MCP estate before the upgrade, that is squarely integration work and we are happy to look.

Frequently asked questions

The initialize and initialized handshake and the Mcp-Session-Id header are removed, protocol metadata moves into _meta on every request, the Tasks feature becomes an extension with a redesigned lifecycle, and the missing-resource error code changes from -32002 to -32602.

No. With protocol-level sessions removed, any request can land on any server instance. The specification notes a server that previously needed sticky sessions, a shared session store and gateway packet inspection can now run behind a plain round-robin load balancer.

Through explicit handles at the application layer rather than protocol sessions. The documented pattern is that the model calls something like create_basket, the server returns a basket_id, and the model passes that same basket_id back as an argument on later calls.

Six specification enhancement proposals harden it: validating the iss parameter per RFC 9207, declaring an OpenID Connect application_type during Dynamic Client Registration, binding credentials to the issuing authorization server, refresh token guidance, scope accumulation during step-up, and the .well-known discovery suffix.

Roots, Sampling and Logging are deprecated under SEP-2577 with minimum twelve-month windows before removal. Roots gives way to tool parameters or server configuration, Sampling to direct LLM provider APIs, and Logging to stderr for stdio servers or OpenTelemetry.

The error code change. Client code branching on the MCP-specific -32002 for a missing resource will silently stop recognising that condition once servers return the JSON-RPC standard -32602. Searching for the literal across clients and servers takes minutes and prevents a field-only failure.

Written by

Akash Mohapatra

Akash Mohapatra

Co Founder & Director

11 Sep 2026

·

8 min read

Share

LET'S CONNECT

Connect with Creuto!

Ready to take the first step towards unlocking opportunities, realizing goals, and embracing innovation? We're here and eager to connect.

Contact Us

We don't just aim to fit in – we strive to stand out. Experience the perfect blend of innovation, excellence, and trust that makes us truly unforgettable. Discover the difference with Creuto.

© 2026 Creuto All Rights Reserved