If you host an MCP server on Cloudflare Workers, the deployment just got simpler. Agents SDK v0.20.0, out July 27, 2026, adds client and server support for the MCP 2026-07-28 specification — and its headline function, createMcpHandler, serves your tools, prompts, resources, and elicitation without an MCP transport session or a Durable Object (Cloudflare Changelog).
The short version: if your MCP server is a bag of read-or-compute tools — most are — drop the Durable Object and move to createMcpHandler. It's a straight upgrade to cheaper, autoscaling edge infrastructure.
What changed, and why the Durable Object goes away#
The 2026-07-28 MCP spec is the stateless revision: it turns MCP from a bidirectional, session-based protocol into plain request/response, so a server no longer needs to hold a session across the connection. We covered what that spec breaks and fixes and the v2 beta SDKs that preceded it; v0.20.0 is Cloudflare wiring that model into the Agents SDK.
Because the protocol is stateless, the server can be a plain fetch handler. That's what createMcpHandler gives you — and it's why the older McpAgent class, which required a Durable Object to hold the session, is now deprecated and feature-frozen (Cloudflare docs). Cloudflare recommends migrating.
The stateless handler#
The server collapses to a handler you export from your Worker:
import { createMcpHandler } from "agents/mcp";
const handler = createMcpHandler((server) => {
server.tool(
"get_order_status",
{ orderId: z.string() },
async ({ orderId }) => {
const status = await lookupOrder(orderId); // read/compute — no session
return { content: [{ type: "text", text: status }] };
}
);
});
export default { fetch: handler };
No Durable Object binding, no session object to provision, nothing pinned per-connection. The Worker autoscales like any other stateless edge function — which is the practical win: you stop paying for and reasoning about a per-session object just to answer tool calls.
On the client side, v0.20.0 probes each server for the new spec and auto-falls back to the legacy handshake when a server doesn't support it, so existing addMcpServer connections need no changes and you don't maintain per-protocol clients.
A stateless MCP server isn't a downgrade — it's the protocol admitting that most tool calls were never a conversation. They were a request and a response.
When to keep a stateful design#
createMcpHandler is the default now, but it isn't universal. Keep a stateful equivalent (a Durable Object or explicit state store) when your server genuinely depends on:
- protocol sessions that must persist across requests,
- server-to-client pushed requests,
- standalone streams or replay, or
- RPC patterns that assume a live connection.
For those, Cloudflare's migration guide has you design stateless equivalents — typically moving session state into an explicit handle passed on each request — and run both the old and new routes in parallel while clients transition, so there's no hard cutover. A server without those legacy dependencies migrates directly: swap the class for the handler and deploy.
What it means for how you ship: the bar for standing up an MCP server just dropped to "write a fetch handler." If you were putting off MCP because a Durable Object felt like too much machinery for three tools, that objection is gone. Start from the MCP server deploy guide, and if you're running the stateless model at any real volume, our load-balancer deploy guide covers putting plain round-robin in front of it — no sticky sessions required.



