
MCP goes stateless: what the new spec changes
The 2026-07-28 MCP spec deletes the session handshake, deprecates Sampling, and rewrites Tasks as an extension. Here's what breaks and what I'm changing in my own server.
I shipped the MCP server for axrank.ai in May, and about a week in I hit the wall that everybody running a remote MCP server eventually hits. A full AXRank eval takes minutes, not milliseconds. It points a frontier agent at a company's developer surface, watches where the agent gets confused, and grades what comes back. When I exposed that as an MCP tool I had two bad options: block the call and hope no client timed out, or hold a session open and pray the load balancer sent the follow-up request back to the same box.
I picked sticky sessions. It worked. I also hated it every single day.
The 2026-07-28 spec goes final next week, and it deletes that entire problem class. The release candidate locked on May 21 and it's the largest revision since MCP launched. If you already run a server, parts of this will break you. If you're about to build one, most of it is a straight upgrade.
The session handshake is gone
The initialize and initialized handshake is out. So is the Mcp-Session-Id header. Protocol metadata now rides along in _meta on every request, and clients pull capabilities on demand with a new server/discover call instead of negotiating them once at connect time.
Every request is self-contained, so any instance can serve any call. That means a round-robin load balancer, no shared session store, and no deep packet inspection at the gateway to work out where a request belongs. Serverless MCP servers stop being a hack you apologize for in the README.
The cost is that state you used to stash in the session has to become explicit. If you kept a shopping basket in session state, you now return a basket_id and the client passes it back as a tool argument on the next call. That's the whole migration. It's the same lesson REST learned twenty years ago, and I think it's the right call even though it means rewriting code I wrote three months ago.

Left, the old shape: every follow-up request has to find Instance A again. Right, the new one: any instance will do, because the request carries everything it needs.
On AXRank the only thing genuinely leaning on the session was per-user eval configuration, the stuff behind set_eval_cadence and get_evals_enabled. Those are now keyed off the auth token, which is honestly where they belonged in the first place.
Sampling, Roots, and Logging are deprecated
Three client features went on the clock. These are annotation-only deprecations with a guaranteed twelve-month minimum window, so the methods, types, and capability flags keep working through 2027-07-28. Nothing breaks Tuesday. The direction is not ambiguous though.
Sampling is the one I have mixed feelings about. The idea was lovely: my server borrows the user's model through their client, the user pays for their own tokens, and I never hold an API key. In practice client support was thin enough that writing against sampling meant writing a fallback path anyway, so I was maintaining two code paths for one feature. The guidance now is to integrate directly with your LLM provider API. I'm about 60% relieved and 40% annoyed, which turns out to be a weirdly common feeling with this spec.
Roots gets replaced by tool parameters, resource URIs, or plain server config. Logging moves to stderr if you're on stdio, or OpenTelemetry if you want structure.
Tasks moved out of core and got rewritten
This is the change I actually care about. Tasks shipped as an experimental core feature in the 2025-11-25 spec. It's now an official extension, redesigned for the stateless model, and the redesign is not subtle.
A long-running tools/call returns a task handle immediately instead of a result. The client drives the lifecycle from there with tasks/get, tasks/update, and tasks/cancel. tasks/list is gone entirely, because listing your tasks needed a session to scope the list against and sessions no longer exist.

The handle comes back in milliseconds. Everything after that is the client's job, which is exactly why it survives a load balancer.
If you built against the 2025-11-25 Tasks API, budget for a lifecycle rewrite rather than a patch. Read the migration note before you scope the sprint, not after.
For AXRank this is exactly the primitive I wanted. get_eval_report hands back a handle, the client polls at whatever cadence it likes, and I stop pretending a four-minute agent eval fits inside a request and a response.
There's a companion change worth knowing about. SEP-2322 replaces the old SSE stream for server-initiated questions with an InputRequiredResult carrying inputRequests and a base64-encoded requestState. The client answers, then re-issues the original call with inputResponses plus the echoed state, so any server instance can pick up the retry. Mid-flight input without a sticky connection.
Extensions are first class now, including MCP Apps
Extensions get reverse-DNS identifiers, live in their own ext-* repositories with independent versioning, and negotiate through an extensions capability map at connect time. There's a Standards Track that moves a feature from experimental to official, and SEPs now need matching conformance tests before they reach Final.
If you do anything close to agent experience work, this is the part to underline. The core protocol stays small and boring on purpose, and the interesting stuff ships on its own release cadence.
MCP Apps (SEP-1865) is the extension people will play with first. Your server hands the client an HTML template, the client renders it in a sandboxed iframe, and every action taken inside that UI routes back through the same JSON-RPC path as a direct tool call. Same audit trail, no side door.
I want an AXRank rank card rendered inline: the score, the failure-mode breakdown, and the three specific things an agent choked on, instead of a wall of JSON the model has to summarize back at you. getbitwit.com is an even more obvious fit, because live trivia has always been a UI problem wearing an API costume.
The small stuff that will bite you
- Caching:
tools/listand resource reads now carryttlMsand acacheScopetelling you whether the result is user-scoped or shareable. Tool ordering is deterministic too, which quietly improves prompt cache hit rates. - Routing headers:
Mcp-MethodandMcp-Nameare mandatory, so a load balancer can route on headers without parsing your request body. - Tracing: W3C Trace Context is standardized, meaning
traceparent,tracestate, andbaggageline your MCP spans up with the rest of your OpenTelemetry. - Schemas: tool schemas are full JSON Schema 2020-12. You get
oneOf,anyOf,allOf, conditionals, and$ref/$defs, though the input root is still an object. Output schemas are unrestricted andstructuredContentaccepts any JSON value. External$refURIs are not auto-dereferenced, so bound your schema depth. - One error code moved: a missing resource returns
-32602now instead of-32002. If your client matches on the old number, fix that today. - Authorization tightened across six SEPs. Validate the
issparameter per RFC 9207, declareapplication_typeduring dynamic client registration, and expect credentials bound to their issuer, so moving authorization servers means re-registering.
That schema upgrade matters more than it looks. Richer types are how you stop an agent from guessing, which is the same argument I made about why prose API docs break AI agents. Every conditional you can express in a schema is a sentence the model doesn't have to interpret.
What I'm changing, and what I'm waiting on
Tasks first. Moving AXRank's eval tools onto the Tasks extension fixes a real thing users complain about, and it doesn't depend on anything else landing. Dropping sticky sessions comes second, mostly because the operational win is large and the code change is small once the state is explicit.
Sampling I'm leaving alone until closer to the 2027 window. A twelve-month deprecation policy is a gift and I intend to use it.
MCP Apps I'm waiting on. Tier 1 SDK support is expected inside a ten-week window after the final release, and I've been burned before building against a spec that shipped faster than its SDKs. Ask me again in October.
If you want more of this, subscribe at quintonwall.com and come find me on YouTube at @seeqcode, where I'll walk through the AXRank Tasks migration once it's actually working.
Subscribe
New posts on AI, developer relations, photography, and the odd long walk, straight to your inbox. No spam.