What Actually Changed in the 2026 MCP Spec (Stateless Servers, Tasks & Apps)

The 2026-07-28 Model Context Protocol spec drops the handshake and goes stateless. A plain-English tour of what changed — Tasks, extensions, header routing — and why self-hosters probably don't need to touch anything yet.

What Actually Changed in the 2026 MCP Spec (Stateless Servers, Tasks & Apps)
Photo by Xu Haiwei / Unsplash
The 2026-07-28 MCP spec makes the protocol core stateless: no more startup handshake, no session header, every request stands on its own. For self-hosters that's mostly good news — any request can land on any server instance behind a plain load balancer. The release also locks in a proper extensions framework (Tasks, MCP Apps), adds header-based routing, and retires a few old pieces on a 12-month clock. The short version: you almost certainly don't need to change anything today.

I run a small pile of MCP servers at home. One for my UniFi network, one for my Sonarr/Radarr media stack, one for Arcane (my Docker manager), and a read-only one that answers questions about my finances. They all sit behind a single authenticated gateway, and I reach them through Nginx Proxy Manager and Cloudflare Tunnels. If you want the backstory on why I let an AI poke at my home lab through these things, I wrote about that in getting AI to manage my home lab.

So when the new Model Context Protocol spec landed on July 28, 2026 and the headline feature was "the core is now stateless," I had one selfish question: does this quietly break the reverse-proxied setup I already have, or does it make it easier?

Good news — it's the second one. Let me explain what actually changed, in plain terms, and what it means if you self-host this stuff.

a close up of a network switch box
Photo by Dimitri Karastelev / Unsplash

Quick note before we start: this is a "what changed in the new version" post, not a "what is MCP" post. If the whole idea of MCP is new to you, start with my definitive MCP guide and come back. MCP, in one sentence, is the open standard that lets an AI model talk to your tools and data through a common interface — think of it as a universal adapter between the model and everything else.

Stateful vs stateless, without the jargon

Here's the part that matters most, so let's slow down.

The old MCP had a handshake. Before a client (the AI app) could do anything useful, it had to send an initialize message, wait for the server to reply, then send an initialized message back. From then on, the two sides shared a session — a bit of remembered context tied together by a special Mcp-Session-Id header on every request.

That's stateful: the server has to remember who you are between requests. It works fine when one server handles your whole conversation. It gets annoying the moment you want more than one server.

Say you run two copies of the same MCP server so you can handle more load, or so one can restart without downtime. With sessions, request #2 has to go back to the exact same copy that did the handshake for request #1 — because that's the only copy that remembers you. Your load balancer (the traffic cop that spreads requests across servers) suddenly needs "sticky sessions" and shared storage. That's a real pain to run.

The 2026-07-28 spec throws that out. The initialize/initialized exchange and the Mcp-Session-Id header are gone. Every request now carries what it needs to stand on its own — the protocol version, who the client is, and what it can do — tucked into a _meta field:

POST /mcp HTTP/1.1
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: search

{"jsonrpc":"2.0","id":1,"method":"tools/call",
 "params":{"name":"search","arguments":{"q":"otters"},
 "_meta":{"io.modelcontextprotocol/clientInfo":{"name":"my-app","version":"1.0"}}}}

Because each request is self-describing, any request can land on any copy of the server — behind a plain round-robin load balancer (one that just hands each new request to the next server in line, no memory required). No stickiness, no shared session store. If a client does want to know a server's capabilities up front, there's a new optional server/discover call for that, but it's not required.

"Stateless protocol" doesn't mean your app can't remember anything. If a tool genuinely needs to carry something across calls, the new pattern is to have the tool hand back an explicit handle (basically a claim ticket) and let the model pass it into the next call. The maintainers found this works better than hiding state in the transport, because the model can actually see the handle and thread it through.

a group of cubes that are connected to each other
Photo by Shubham Dhage / Unsplash

The new bits: Tasks, extensions, and MCP Apps

Stateless is the headline, but a few other things shipped that are worth knowing by name.

A real extensions framework. Instead of bolting every new idea onto the core spec, MCP now has a formal way to ship optional add-ons. Extensions get reverse-DNS names (like io.modelcontextprotocol/tasks), live in their own repos, and version on their own schedule. Two official ones ship with this release: Tasks and MCP Apps, alongside Enterprise Managed Authorization (EMA) for the corporate crowd.

Tasks. This is the answer for long-running work. Instead of making a tool call hang while something slow finishes, a server can hand back a task, and the client checks on it with a poll-based tasks/get (plus a new tasks/update). It graduated out of the experimental core into its own io.modelcontextprotocol/tasks extension. If you've ever had a tool call time out because the job took 30 seconds, this is for you.

MCP Apps. The extension for richer, interactive experiences on top of MCP — the kind of thing that lets a tool render more than a wall of text back to the user.

A couple of plumbing changes round it out:

  • Multi Round-Trip Requests (MRTR). Sometimes a tool needs to stop and ask you something mid-call — a confirmation, or a missing value. Old MCP did that over a held-open two-way stream, which doesn't fit a stateless world. Now the server just replies with resultType: "input_required", and the client retries the same call with the answers attached. Cleaner, and it works without keeping a live connection open.
  • Header-based routing. Requests now carry Mcp-Method and Mcp-Name HTTP headers, so a gateway, rate limiter, or firewall can route and meter traffic by reading a header instead of cracking open the JSON body.
  • Cacheable lists. Responses from tools/list, prompts/list, and friends now carry cache hints (ttlMs and cacheScope), so clients can stop re-fetching the same tool catalog over and over.

What this actually changes for self-hosting

Okay, back to my selfish question. If you run MCP servers at home behind a reverse proxy — a reverse proxy being the server that sits out front and forwards requests to the right internal service, like Nginx Proxy Manager does — here's the honest breakdown.

The good. The stateless model is genuinely friendlier to the way we already run things. No session affinity to configure. If you ever scale a server to two containers, a dumb round-robin split just works. And because method and tool names ride in headers now, your proxy or firewall can route and rate-limit on them without inspecting request bodies — handy if you like keeping rules readable.

The "do I need to touch anything?" Today, almost certainly no. Two reasons. First, the change lives in the SDKs and server implementations, not in your proxy — Nginx Proxy Manager and Cloudflare Tunnels are just forwarding HTTP either way. Second, and more important: your self-hosted servers only become stateless once their images are rebuilt against the updated SDK. Most community MCP servers you're running right now still speak the older, session-based transport, and they'll keep working. So there's nothing to reconfigure this weekend.

The one thing I'd flag for later: if you built anything custom that leaned on the Mcp-Session-Id header — a rewrite rule, a hacky auth shim, a log filter — that assumption goes away in the stateless world. I don't have anything like that, and you probably don't either, but it's the kind of detail that bites if you forget it.

black and blue usb cable
Photo by Jainath Ponnala / Unsplash

Should you care yet?

The spec is final — it was finalized on July 28, 2026 after about a ten-week release-candidate period, so this isn't a preview. All four Tier 1 SDKs (TypeScript, Python, Go, and C#) already speak it, with Rust in beta.

But "the spec is out" and "everything you run supports it" are different things. Client apps and the community servers in your stack will adopt it on their own timelines over the coming months. Until the specific server you care about ships an updated build, you're still on the old behavior — which is fine.

There's also a deprecation clock worth knowing about. A few older features are now deprecated but still work for at least twelve months: Roots, Sampling, and Logging, plus the legacy HTTP+SSE transport, plus Dynamic Client Registration (being replaced by something called Client ID Metadata Documents, or CIMD, on the auth side). "Deprecated" here means "don't build new things on it," not "it broke today." The maintainers committed to a formal 12-month minimum window, which is a nice change from reacting to surprise breakage.

My take: if you're writing an MCP server, start targeting the new spec now — the SDKs are ready and the stateless model is simpler to run. If you're just running other people's servers, do nothing. Let your images update on their own, skim the release notes when something you depend on bumps its version, and enjoy the fact that scaling got easier without you lifting a finger.

Final thoughts

This is the kind of release I like: the exciting part (stateless core) also happens to be the part that makes self-hosting less annoying. My reverse-proxied gateway setup didn't need a single change, and the day one of my servers rebuilds against the new SDK, it quietly gets easier to scale.

I'm not rushing anything. I'll let the servers update on their own schedule and keep an eye on the release notes. But it's genuinely reassuring to read a big protocol revision and conclude that the correct action, for once, is to do nothing.

Want the primary sources? Start with the official 2026-07-28 announcement, then dig into the full specification and its changelog.