MCP Goes Stateless, and Sampling Goes With It
The 2026-07-28 MCP spec is the biggest revision since the protocol shipped. The headline is that sampling is deprecated, which stings a little because I wrote a whole guide telling you to build on it. But sampling didn’t get removed because someone disliked it. It got removed because MCP stopped being a stateful protocol, and once you make that call, most of the rest follows.
Stateless is the change that matters
MCP is now a request/response stateless protocol instead of a bidirectional stateful one. The initialize handshake and the Mcp-Session-Id header are gone; every request carries its own protocol version, client identity, and capabilities and stands on its own.
That sounds like plumbing, but it’s the whole ballgame. A stateful protocol means every request has to return to the same instance or reach a shared session store, so the moment you run more than one server you need sticky sessions or a Redis. Stateless deletes that: any request lands on any instance behind a plain round-robin load balancer, no shared storage. It was one of the most requested changes from people running MCP in production, and it turns an MCP server from a thing you operate carefully into just another stateless HTTP route.
One caution, because I can hear the takeaway forming: this does not make an MCP server your REST API with a new envelope. A tool call is expensive for an agent in a way a REST call isn’t, since every call burns tokens and a round-trip through the model’s context. The best MCP servers aren’t a mirror of a chatty REST API’s dozens of little endpoints; they expose fewer, coarser tools that each do a real unit of work, so the agent spends one expensive call where a REST client would spend five cheap ones. (Code mode softens this, but most clients aren’t there yet.) Statelessness makes the server easier to run. Good tool design is still its own discipline.
So what happens to sampling
Sampling let a server borrow the client’s LLM over the bidirectional stream. No stream, no sampling in that shape. And if you read my guide, you’ll remember the caveat buried in it: client support was terrible. I even built Sentinel on sampling and had to ship an API-key fallback that defeated the point. In hindsight, weak adoption and the stream requirement were the same signal.
Deprecated isn’t deleted. SEP-2577 keeps sampling, roots, and logging working for at least twelve months. But the direction is clear: reasoning belongs in the client’s agent loop, and user decisions belong in MRTR or elicitation. My March advice to design with sampling in mind aged badly.
Tasks is the interesting half
Lost in the deprecation news is the part I’m excited about. Tasks graduated from experimental core into an extension, io.modelcontextprotocol/tasks, contributed by AWS under SEP-2663, with a poll-based tasks/get and a new tasks/update. A stateless core needs this: you can’t hold a long job open on a live connection anymore, so the server starts the work, hands back a handle, and the client polls. It survives a load balancer moving you mid-job because nothing is instance-local.
For custom agents this was the missing piece. An agent kicking off a ten-minute analysis, a build, or a batch import used to either block the tool call or invent its own status mechanism. A standard task lifecycle means it can fire off long work, do other things, and check back, in one shape every client understands. That’s the primitive that makes agents doing real work, not just quick lookups, actually buildable.
The rest of the release
The two above plus MRTR are the ones I’d act on, but the spec ships more:
- MRTR (Multi Round-Trip Requests). How a stateless server still asks the client something, replacing what the bidirectional stream did. Supabase’s example: confirm the cost of a project before creating it, or warn before a destructive query.
- Header-based routing. New
Mcp-MethodandMcp-Nameheaders let gateways and rate limiters route without parsing JSON bodies. - Cacheable list results. List responses now carry
ttlMsandcacheScope, so clients can cache tool and resource lists instead of refetching. - Authorization hardening. RFC 9207 issuer validation, a move from Dynamic Client Registration to Client ID Metadata Documents, and issuer-bound credentials.
- A formal extensions framework. The mechanism tasks now lives in, so capabilities can evolve outside the core spec.
All Tier 1 SDKs (TypeScript, Python, Go, C#) plus Rust in beta support it already.
The through-line: MCP grew up into a normal, scalable web protocol. Stateless request/response, poll for long jobs, no magic bidirectional channel. Less clever, much easier to run in production, and that trade is almost always the right one.
Stay in the loop
Get notified when I publish new posts. No spam, unsubscribe anytime.