{"slug": "mcp-goes-stateless-and-that-s-the-point", "title": "MCP Goes Stateless, and That's the Point", "summary": "The Model Context Protocol (MCP) shipped its largest revision since launch on 2026-07-28, deleting protocol-level sessions, the Mcp-Session-Id header, the initialize handshake, SSE resumability, and the standalone GET stream to make remote servers stateless and scalable like plain HTTP. The breaking change, announced by maintainers, requires clients to carry protocol version and capabilities per-request in _meta, adds a mandatory server/discover RPC, and introduces Multi Round-Trip Requests for server-initiated interactions, enabling deployment behind round-robin load balancers or scale-to-zero platforms.", "body_md": "[AI](https://sourcefeed.dev/c/ai)Article\n\n# MCP Goes Stateless, and That's the Point\n\nThe 2026-07-28 spec deletes sessions and the handshake so remote servers scale like plain HTTP.\n\n[Rachel Goldstein](https://sourcefeed.dev/u/rachel_goldstein)\n\nThe [Model Context Protocol](https://modelcontextprotocol.io) just shipped its largest revision since launch, and the headline is subtraction. The 2026-07-28 spec deletes protocol-level sessions, the `Mcp-Session-Id`\n\nheader, the `initialize`\n\nhandshake, SSE resumability, and the standalone GET stream. Every request now stands alone, carrying its protocol version and client capabilities in `_meta`\n\n. A remote MCP server can finally sit behind a dumb round-robin load balancer — or cold-start on a scale-to-zero platform for every single call — and nothing breaks.\n\nThis is a breaking change, the maintainers say it's the kind that needed a clean break, and they're right. It's also MCP quietly admitting which part of the protocol was ever worth keeping.\n\n## What actually got deleted\n\nThe old Streamable HTTP transport was stateful by default: clients ran an `initialize`\n\nhandshake, the server minted a session ID, and every subsequent request had to land on an instance that remembered that session. That single design decision is why \"deploy a remote MCP server\" turned into a distributed-systems problem — sticky sessions at the load balancer, or a shared session store, or a gateway vendor selling you the fix.\n\nThe new spec removes the machinery wholesale. The handshake is gone; capabilities and version travel per-request in `_meta`\n\n, with a new mandatory `server/discover`\n\nRPC for up-front version negotiation. Two required headers, `Mcp-Method`\n\nand `Mcp-Name`\n\n, expose the operation on every POST, so a gateway or rate-limiter can route and throttle without parsing the JSON body — Cloudflare's engineers have already pointed out this lets ordinary WAF and API-gateway primitives apply to MCP traffic unmodified. List results (`tools/list`\n\n, `resources/list`\n\n, and friends) must now carry `ttlMs`\n\nand a `cacheScope`\n\n, which means CDNs and shared intermediaries can legitimately cache tool catalogs.\n\nThe trickiest deletion is server-initiated requests. Elicitation, sampling, and `roots/list`\n\nall assumed the server could reach back through an open channel and ask the client something mid-operation. Stateless servers can't do that, so the spec replaces the pattern with Multi Round-Trip Requests: the server returns an `InputRequiredResult`\n\nwith an opaque `requestState`\n\n, and the client retries the original request carrying the answers. It's continuation-passing over HTTP — the server externalizes its pending state into a token the client holds, which is exactly how every stateless system since OAuth has solved this.\n\n## The REST lesson, relearned\n\nNone of this is new territory. The web went through the identical arc twenty-five years ago: server-side session affinity was the default, it made horizontal scaling miserable, and the industry converged on stateless requests with state pushed to the edges — cookies, tokens, databases. MCP's original transport design ignored that history because it grew out of stdio, where a long-lived process talking to one client is the natural shape. Local-first assumptions leaked into the remote transport, and the ecosystem spent 2025 paying for it: session-aware gateways, resumability headers, redelivery semantics, all to preserve an abstraction most servers didn't need.\n\nThe new answer for servers that genuinely need cross-call state is refreshingly unclever: mint your own handles and pass them as ordinary tool arguments. Your database tool returns a `query_id`\n\n; the model threads it into the next call. That's arguably better than sessions, because the state becomes something the model can see, reason about, and hand off between steps — instead of ambient context glued to a transport connection the model doesn't even know exists.\n\n## \"So it's just an API again\"\n\nThe loudest criticism, surfaced in InfoQ's coverage, is that a stateless request/response protocol with cacheable list endpoints and routing headers is... an ordinary HTTP API, and MCP has negotiated itself back to where OpenAPI already was. It's a fair jab and a wrong conclusion. MCP's value was never the session plumbing — it's the standardized contract: uniform tool discovery, JSON Schema'd inputs and outputs, one integration surface that every client from Claude to Cursor speaks without bespoke glue. Converging on boring transport semantics while keeping that contract is the protocol maturing, not dissolving. The parts that made MCP annoying to operate are gone; the part that made it useful is intact.\n\nThe real losers are narrower. If you built on sampling (having the server borrow the client's LLM), roots, or protocol-level logging, those features are now deprecated with a twelve-month window — the official guidance is to call LLM provider APIs directly, pass directories as tool parameters, and log to stderr or OpenTelemetry. Servers that leaned on SSE resumability lose message redelivery entirely: a broken stream means re-issuing the request. And the experimental Tasks API moved out of core into an extension with a redesigned polling model, so early adopters get a second migration.\n\n## Migrating without tears\n\nThe SDK story is better than breaking changes usually get. The TypeScript SDK's v2 line retires the monolithic `@modelcontextprotocol/sdk`\n\nin favor of split packages — [ @modelcontextprotocol/server](https://github.com/modelcontextprotocol/typescript-sdk),\n\n`@modelcontextprotocol/client`\n\n, plus thin adapters for Express, Fastify, Hono, and plain Node — and ships a migration codemod. Python's 2.0 renames `FastMCP`\n\nto `MCPServer`\n\nand speaks both the legacy and new protocol versions simultaneously, so one deployment serves old and new clients during the transition. Go gates the new behavior behind an explicit `Stateless = true`\n\noption.For a typical tool server the migration is mostly deletion: drop the `sessionIdGenerator`\n\nconfig, remove any session-store wiring, and let each request be self-contained. The work concentrates in two places. First, anything you stashed in session state needs a home — either a handle-plus-database pattern or, for short-lived interactive flows, the MRTR `requestState`\n\ntoken. Second, if you're mid-flight on the 2025-11-25 elicitation API, that shape changed again; budget for it.\n\nMy read: do this migration soon, and be glad about it. Stateless-first is what remote MCP should have been from the start, and the twelve-month deprecation policy plus dual-version SDKs make this the cheapest window you'll get. The protocol got smaller, the ops story got dramatically simpler, and the ecosystem's gateway-and-glue industry just lost its reason to exist. Boring is what winning looks like for infrastructure.\n\n## Sources & further reading\n\n-\n[Key Changes - MCP 2026-07-28 Specification](https://modelcontextprotocol.io/specification/2026-07-28/changelog)— modelcontextprotocol.io -\n[The 2026-07-28 MCP Specification Release Candidate](https://blog.modelcontextprotocol.io/posts/2026-07-28-release-candidate/)— blog.modelcontextprotocol.io -\n[Beta SDKs for the 2026-07-28 MCP Spec Release Candidate Are Here](https://blog.modelcontextprotocol.io/posts/sdk-betas-2026-07-28/)— blog.modelcontextprotocol.io -\n[MCP Goes Stateless, and Developers Ask Whether That Just Makes it an API Again](https://www.infoq.com/news/2026/08/mcp-stateless-gateway/)— infoq.com -\n[The official TypeScript SDK for Model Context Protocol](https://github.com/modelcontextprotocol/typescript-sdk)— github.com -\n[MCP Is Going Stateless: What Changed and How I Migrated My Currency Converter Server](https://dev.to/dilumdarshana/mcp-is-going-stateless-what-changed-and-how-i-migrated-my-currency-converter-server-olm)— dev.to\n\n[Rachel Goldstein](https://sourcefeed.dev/u/rachel_goldstein)· Dev Tools Editor\n\nRachel has been embedded in the developer tooling ecosystem for nearly eight years, covering everything from IDE wars and package-manager drama to the quiet rise of AI-assisted coding. She has a soft spot for open-source maintainers and an unhealthy number of terminal emulators installed on a single laptop.\n\n## Discussion 0\n\nNo comments yet\n\nBe the first to weigh in.", "url": "https://wpnews.pro/news/mcp-goes-stateless-and-that-s-the-point", "canonical_source": "https://sourcefeed.dev/a/mcp-goes-stateless-and-thats-the-point", "published_at": "2026-08-19 16:08:19+00:00", "updated_at": "2026-08-19 16:13:10.180709+00:00", "lang": "en", "topics": ["ai-infrastructure", "developer-tools", "ai-policy"], "entities": ["Model Context Protocol", "Cloudflare", "Rachel Goldstein"], "alternates": {"html": "https://wpnews.pro/news/mcp-goes-stateless-and-that-s-the-point", "markdown": "https://wpnews.pro/news/mcp-goes-stateless-and-that-s-the-point.md", "text": "https://wpnews.pro/news/mcp-goes-stateless-and-that-s-the-point.txt", "jsonld": "https://wpnews.pro/news/mcp-goes-stateless-and-that-s-the-point.jsonld"}}