MCP 2026-07-28 spec supported; McpAgent deprecated
Agents SDK v0.20.0 adds client and server support for the MCP 2026-07-28 release candidate ↗. Workers can serve tools, prompts, resources, and elicitation without an MCP transport session or Durable Object. Agents can connect to both MCP 2026-07-28 servers and existing legacy servers.
Client support
The MCP client manager now uses @modelcontextprotocol/client. For each connection, it probes for MCP 2026-07-28 support with server/discover. If the server does not support the stateless protocol, the client continues with the legacy initialize handshake on the same connection. Existing addMcpServer calls do not need a protocol-version setting or separate clients for each protocol generation.
For stateless requests, elicitation uses input_required through multi-round-trip requests (MRTR). The legacy path uses the same form and URL handlers for pushed requests. The SDK collects input, retries the original operation, and resolves the original callTool, getPrompt, or readResource promise with its final result.
OAuth callbacks now validate issuer metadata through the v2 SDK. Discovery state and issuer-bound credentials persist across browser redirects and Durable Object hibernation.
Run stateless servers
createMcpHandler now accepts a factory that returns a server from @modelcontextprotocol/server. The factory creates an isolated server for each request.
<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { McpServer } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "@modelcontextprotocol/server"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { createMcpHandler } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "agents/mcp/server"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-1itgoe">function</span><span class="nb-shiki-1t8gfj"> createServer</span><span class="nb-shiki-140thh">() {</span></span>
<span class="line"><span class="nb-shiki-1itgoe"> return</span><span class="nb-shiki-1itgoe"> new</span><span class="nb-shiki-1t8gfj"> McpServer</span><span class="nb-shiki-140thh">({ name: </span><span class="nb-shiki-mdbnqw">"example"</span><span class="nb-shiki-140thh">, version: </span><span class="nb-shiki-mdbnqw">"1.0.0"</span><span class="nb-shiki-140thh"> });</span></span>
<span class="line"><span class="nb-shiki-140thh">}</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-1itgoe">export</span><span class="nb-shiki-1itgoe"> default</span><span class="nb-shiki-140thh"> {</span></span>
<span class="line"><span class="nb-shiki-1t8gfj"> fetch</span><span class="nb-shiki-140thh">(</span><span class="nb-shiki-1jdh33">request</span><span class="nb-shiki-140thh">, </span><span class="nb-shiki-1jdh33">env</span><span class="nb-shiki-140thh">, </span><span class="nb-shiki-1jdh33">ctx</span><span class="nb-shiki-140thh">) {</span></span>
<span class="line"><span class="nb-shiki-1itgoe"> return</span><span class="nb-shiki-1t8gfj"> createMcpHandler</span><span class="nb-shiki-140thh">(createServer)(request, env, ctx);</span></span>
<span class="line"><span class="nb-shiki-140thh"> },</span></span>
<span class="line"><span class="nb-shiki-140thh">};</span></span>
<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { McpServer } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "@modelcontextprotocol/server"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { createMcpHandler } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "agents/mcp/server"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-1itgoe">function</span><span class="nb-shiki-1t8gfj"> createServer</span><span class="nb-shiki-140thh">() {</span></span>
<span class="line"><span class="nb-shiki-1itgoe"> return</span><span class="nb-shiki-1itgoe"> new</span><span class="nb-shiki-1t8gfj"> McpServer</span><span class="nb-shiki-140thh">({ name: </span><span class="nb-shiki-mdbnqw">"example"</span><span class="nb-shiki-140thh">, version: </span><span class="nb-shiki-mdbnqw">"1.0.0"</span><span class="nb-shiki-140thh"> });</span></span>
<span class="line"><span class="nb-shiki-140thh">}</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-1itgoe">export</span><span class="nb-shiki-1itgoe"> default</span><span class="nb-shiki-140thh"> {</span></span>
<span class="line"><span class="nb-shiki-1t8gfj"> fetch</span><span class="nb-shiki-140thh">(</span><span class="nb-shiki-1jdh33">request</span><span class="nb-shiki-140thh">, </span><span class="nb-shiki-1jdh33">env</span><span class="nb-shiki-140thh">, </span><span class="nb-shiki-1jdh33">ctx</span><span class="nb-shiki-140thh">) {</span></span>
<span class="line"><span class="nb-shiki-1itgoe"> return</span><span class="nb-shiki-1t8gfj"> createMcpHandler</span><span class="nb-shiki-140thh">(createServer)(request, env, ctx);</span></span>
<span class="line"><span class="nb-shiki-140thh"> },</span></span>
<span class="line"><span class="nb-shiki-140thh">} </span><span class="nb-shiki-1itgoe">satisfies</span><span class="nb-shiki-1t8gfj"> ExportedHandler</span><span class="nb-shiki-140thh">;</span></span>
The isolated agents/mcp/server entry keeps McpAgent, WorkerTransport, MCP client transports, and SDK v1 modules out of stateless server bundles.
The Workers wrapper validates present browser Origins, supports explicit delegation to trusted Origin middleware, and exposes request handling plus typed change notifications.
Backward compatibility
The same createMcpHandler(createServer)(request, env, ctx) route serves MCP 2026-07-28 clients and legacy clients that use stateless requests. You do not need separate routes or tool definitions for ordinary tools, prompts, and resources.
McpAgent is deprecated and feature-frozen. Migrate existing McpAgent servers to the stateless handler at your earliest convenience. If a server depends on protocol sessions, RPC, pushed server-to-client requests, standalone streams, or replay, use the migration guide to design stateless equivalents and run both routes while clients transition.
Migrate existing SDK v1 servers
Upgrade the Agents SDK:
if (!customElements.get("nb-pm-restore")) { customElements.define( "nb-pm-restore", class extends HTMLElement { connectedCallback() { const card = this.closest("[data-nb-pm]"); if (!card) return; let saved; try { saved = sessionStorage.getItem("ui-pm-tab"); } catch { return; } if (!saved) return; const tabs = card.querySelectorAll("[data-nb-pm-tab]"); let idx = -1; tabs.forEach(function (t, i) { if (t.textContent.trim() === saved) idx = i; }); if (idx < 1) return; tabs.forEach(function (t, i) { t.setAttribute("aria-selected", String(i === idx)); }); card.querySelectorAll("[data-nb-pm-panel]").forEach(function (p, i) { p.hidden = i !== idx; }); } }, ); }
npmyarnpnpmbun
<span class="text-success">npm</span><span class="text-warning"> i agents@latest</span>
<span class="text-success">yarn</span><span class="text-warning"> add agents@latest</span>
<span class="text-success">pnpm</span><span class="text-warning"> add agents@latest</span>
<span class="text-success">bun</span><span class="text-warning"> add agents@latest</span>
Move ordinary SDK v1 server definitions into an SDK v2 factory and serve them with createMcpHandler. The handler's default legacy compatibility means most stateless deployments need only one route.
If an existing McpAgent server still needs sessionful features, add the stateless path beside it. Use isLegacyRequest() to send only legacy traffic to the existing route:
<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { isLegacyRequest } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "@modelcontextprotocol/server"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { createMcpHandler } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "agents/mcp/server"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { MyMcpAgent } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "./legacy-server"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { createServer } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "./server"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-1itgoe">const</span><span class="nb-shiki-dzsirb"> stateless</span><span class="nb-shiki-1itgoe"> =</span><span class="nb-shiki-1t8gfj"> createMcpHandler</span><span class="nb-shiki-140thh">(createServer, {</span></span>
<span class="line"><span class="nb-shiki-140thh"> route: </span><span class="nb-shiki-mdbnqw">"/mcp"</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh"> legacy: </span><span class="nb-shiki-mdbnqw">"reject"</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh">});</span></span>
<span class="line"><span class="nb-shiki-1itgoe">const</span><span class="nb-shiki-dzsirb"> legacy</span><span class="nb-shiki-1itgoe"> =</span><span class="nb-shiki-140thh"> MyMcpAgent.</span><span class="nb-shiki-1t8gfj">serve</span><span class="nb-shiki-140thh">(</span><span class="nb-shiki-mdbnqw">"/mcp"</span><span class="nb-shiki-140thh">);</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-1itgoe">export</span><span class="nb-shiki-1itgoe"> default</span><span class="nb-shiki-140thh"> {</span></span>
<span class="line"><span class="nb-shiki-1itgoe"> async</span><span class="nb-shiki-1t8gfj"> fetch</span><span class="nb-shiki-140thh">(</span><span class="nb-shiki-1jdh33">request</span><span class="nb-shiki-140thh">, </span><span class="nb-shiki-1jdh33">env</span><span class="nb-shiki-140thh">, </span><span class="nb-shiki-1jdh33">ctx</span><span class="nb-shiki-140thh">) {</span></span>
<span class="line"><span class="nb-shiki-1itgoe"> if</span><span class="nb-shiki-140thh"> (</span><span class="nb-shiki-1itgoe">await</span><span class="nb-shiki-1t8gfj"> isLegacyRequest</span><span class="nb-shiki-140thh">(request)) {</span></span>
<span class="line"><span class="nb-shiki-1itgoe"> return</span><span class="nb-shiki-140thh"> legacy.</span><span class="nb-shiki-1t8gfj">fetch</span><span class="nb-shiki-140thh">(request, env, ctx);</span></span>
<span class="line"><span class="nb-shiki-140thh"> }</span></span>
<span class="line"><span class="nb-shiki-1itgoe"> return</span><span class="nb-shiki-1t8gfj"> stateless</span><span class="nb-shiki-140thh">(request, env, ctx);</span></span>
<span class="line"><span class="nb-shiki-140thh"> },</span></span>
<span class="line"><span class="nb-shiki-140thh">};</span></span>
<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { isLegacyRequest } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "@modelcontextprotocol/server"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { createMcpHandler } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "agents/mcp/server"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { MyMcpAgent } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "./legacy-server"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { createServer } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "./server"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-1itgoe">const</span><span class="nb-shiki-dzsirb"> stateless</span><span class="nb-shiki-1itgoe"> =</span><span class="nb-shiki-1t8gfj"> createMcpHandler</span><span class="nb-shiki-140thh">(createServer, {</span></span>
<span class="line"><span class="nb-shiki-140thh"> route: </span><span class="nb-shiki-mdbnqw">"/mcp"</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh"> legacy: </span><span class="nb-shiki-mdbnqw">"reject"</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh">});</span></span>
<span class="line"><span class="nb-shiki-1itgoe">const</span><span class="nb-shiki-dzsirb"> legacy</span><span class="nb-shiki-1itgoe"> =</span><span class="nb-shiki-140thh"> MyMcpAgent.</span><span class="nb-shiki-1t8gfj">serve</span><span class="nb-shiki-140thh">(</span><span class="nb-shiki-mdbnqw">"/mcp"</span><span class="nb-shiki-140thh">);</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-1itgoe">export</span><span class="nb-shiki-1itgoe"> default</span><span class="nb-shiki-140thh"> {</span></span>
<span class="line"><span class="nb-shiki-1itgoe"> async</span><span class="nb-shiki-1t8gfj"> fetch</span><span class="nb-shiki-140thh">(</span><span class="nb-shiki-1jdh33">request</span><span class="nb-shiki-1itgoe">:</span><span class="nb-shiki-1t8gfj"> Request</span><span class="nb-shiki-140thh">, </span><span class="nb-shiki-1jdh33">env</span><span class="nb-shiki-1itgoe">:</span><span class="nb-shiki-1t8gfj"> Env</span><span class="nb-shiki-140thh">, </span><span class="nb-shiki-1jdh33">ctx</span><span class="nb-shiki-1itgoe">:</span><span class="nb-shiki-1t8gfj"> ExecutionContext</span><span class="nb-shiki-140thh">) {</span></span>
<span class="line"><span class="nb-shiki-1itgoe"> if</span><span class="nb-shiki-140thh"> (</span><span class="nb-shiki-1itgoe">await</span><span class="nb-shiki-1t8gfj"> isLegacyRequest</span><span class="nb-shiki-140thh">(request)) {</span></span>
<span class="line"><span class="nb-shiki-1itgoe"> return</span><span class="nb-shiki-140thh"> legacy.</span><span class="nb-shiki-1t8gfj">fetch</span><span class="nb-shiki-140thh">(request, env, ctx);</span></span>
<span class="line"><span class="nb-shiki-140thh"> }</span></span>
<span class="line"><span class="nb-shiki-1itgoe"> return</span><span class="nb-shiki-1t8gfj"> stateless</span><span class="nb-shiki-140thh">(request, env, ctx);</span></span>
<span class="line"><span class="nb-shiki-140thh"> },</span></span>
<span class="line"><span class="nb-shiki-140thh">} </span><span class="nb-shiki-1itgoe">satisfies</span><span class="nb-shiki-1t8gfj"> ExportedHandler</span><span class="nb-shiki-140thh"><</span><span class="nb-shiki-1t8gfj">Env</span><span class="nb-shiki-140thh">>;</span></span>
Migrate the remaining sessionful features, allow existing sessions to drain, then remove the legacy route. Refer to Migrate to MCP SDK v2 for package changes, compatibility limits, and rollout steps.
Deprecations in v0.20.0
This release deprecates the following Agents SDK APIs:
Deprecated API
Replacement
Status
McpAgent
Use an SDK v2 factory with createMcpHandler for stateless servers. Use the migration guide to replace stateful features before removing a legacy route.
Feature-frozen. No removal version is announced.
createMcpHandler(v1Server, options)
Move the server to an SDK v2 factory and call createMcpHandler(factory, options). Use createLegacyMcpHandler only as a temporary bridge for sessionful features.
Scheduled for removal in the next major version.
MCPClientManager.callTool(params, resultSchema, options) and the equivalent withX402Client overload
Use callTool(params, options) or callTool(confirm, params, options).
Compatibility overload. No removal version is announced.
The MCP 2026-07-28 draft separately deprecates Roots, Sampling, Logging, the old HTTP+SSE transport, and Dynamic Client Registration.
Fetched July 27, 2026


