Agents, Workers - Agents SDK adds MCP Specification 2026-07-28 support
- Announced
- Effective
- Tags
- Agents, Workers
- Severity
- info, set by
reef/rss-rule-v1 - Source
- https://developers.cloudflare.com/changelog/post/2026-07-27-agents-sdk-v0.20.0-mcp-sdk-v2/
<p>Agents SDK v0.20.0 adds client and server support for the <a href="https://blog.modelcontextprotocol.io/posts/2026-07-28-release-candidate/" target="_blank" rel="noopener">MCP 2026-07-28 release candidate<span class="external-link"> ↗︎</span></a>. 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.</p> <div tabindex="-1" class="heading-wrapper level-h4"><h4 id="client-support">Client support</h4><a class="anchor-link" href="#client-support"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>The MCP client manager now uses <code>@modelcontextprotocol/client</code>. For each connection, it probes for MCP 2026-07-28 support with <code>server/discover</code>. If the server does not support the stateless protocol, the client continues with the legacy <code>initialize</code> handshake on the same connection. Existing <code>addMcpServer</code> calls do not need a protocol-version setting or separate clients for each protocol generation.</p> <p>For stateless requests, elicitation uses <code>input_required</code> 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 <code>callTool</code>, <code>getPrompt</code>, or <code>readResource</code> promise with its final result.</p> <p>OAuth callbacks now validate issuer metadata through the v2 SDK. Discovery state and issuer-bound credentials persist across browser redirects and Durable Object hibernation.</p> <div tabindex="-1" class="heading-wrapper level-h4"><h4 id="run-stateless-servers">Run stateless servers</h4><a class="anchor-link" href="#run-stateless-servers"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p><code>createMcpHandler</code> now accepts a factory that returns a server from <code>@modelcontextprotocol/server</code>. The factory creates an isolated server for each request.</p> <div><div data-nb-tabs data-nb-sync-key="workersExamples" class><div class="relative flex border-b border-border" role="tablist" data-nb-tabs-list><span class="bg-primary pointer-events-none absolute -bottom-px h-0.5 rounded-t-sm transition-[left,width] duration-200 ease-out" data-nb-tabs-indicator aria-hidden="true"></span></div><div class="mt-3"><div role="tabpanel" data-nb-tabs-content data-nb-tab-label="JavaScript" class><figure class="nb-code-figure" data-nb-lang="js"><pre class="astro-code astro-code-themes github-light github-dark nb-shiki-c6xiwz" tabindex="0" data-language="js" data-nb-lang="js"><code><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></code></pre></figure></div><div role="tabpanel" data-nb-tabs-content data-nb-tab-label="TypeScript" class><figure class="nb-code-figure" data-nb-lang="ts"><pre class="astro-code astro-code-themes github-light github-dark nb-shiki-c6xiwz" tabindex="0" data-language="ts" data-nb-lang="ts"><code><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></code></pre></figure></div></div></div><script type="module" src="https://developers.cloudflare.com/home/runner/work/cloudflare-docs/cloudflare-docs/src/components/ui/tabs/Tabs.astro?astro&type=script&index=0&lang.ts"></script></div> <p>The isolated <code>agents/mcp/server</code> entry keeps <code>McpAgent</code>, <code>WorkerTransport</code>, MCP client transports, and SDK v1 modules out of stateless server bundles.</p> <p>The Workers wrapper validates present browser Origins, supports explicit delegation to trusted Origin middleware, and exposes request handling plus typed change notifications.</p> <div tabindex="-1" class="heading-wrapper level-h4"><h4 id="backward-compatibility">Backward compatibility</h4><a class="anchor-link" href="#backward-compatibility"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>The same <code>createMcpHandler(createServer)(request, env, ctx)</code> 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.</p> <p><code>McpAgent</code> is deprecated and feature-frozen. Migrate existing <code>McpAgent</code> 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 <a href="https://developers.cloudflare.com/agents/model-context-protocol/guides/migrate-to-mcp-sdk-v2/">migration guide</a> to design stateless equivalents and run both routes while clients transition.</p> <div tabindex="-1" class="heading-wrapper level-h4"><h4 id="migrate-existing-sdk-v1-servers">Migrate existing SDK v1 servers</h4><a class="anchor-link" href="#migrate-existing-sdk-v1-servers"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Upgrade the Agents SDK:</p> <script> 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; }); } }, ); } </script><div data-nb-pm class="w-full"><div class="flex w-full flex-col overflow-hidden rounded-lg text-sm ring ring-border bg-card"><div class="flex items-center gap-2 px-3 py-2 text-[0.8125rem] font-medium leading-5 text-muted-foreground bg-[var(--nb-surface-sunken)]" role="tablist" aria-label="Package manager"><button role="tab" type="button" aria-selected="true" aria-controls="pm-panel-pm-19fe24e6-npm" id="pm-tab-pm-19fe24e6-npm" data-nb-pm-tab class="text-muted-foreground hover:bg-accent hover:text-foreground aria-selected:bg-selected aria-selected:text-foreground focus-visible:outline-ring m-0 cursor-pointer rounded-md border-0 bg-transparent px-2 py-0.5 text-xs leading-5 font-medium transition-colors focus-visible:outline-2 focus-visible:outline-offset-2">npm</button><button role="tab" type="button" aria-selected="false" aria-controls="pm-panel-pm-19fe24e6-yarn" id="pm-tab-pm-19fe24e6-yarn" data-nb-pm-tab class="text-muted-foreground hover:bg-accent hover:text-foreground aria-selected:bg-selected aria-selected:text-foreground focus-visible:outline-ring m-0 cursor-pointer rounded-md border-0 bg-transparent px-2 py-0.5 text-xs leading-5 font-medium transition-colors focus-visible:outline-2 focus-visible:outline-offset-2">yarn</button><button role="tab" type="button" aria-selected="false" aria-controls="pm-panel-pm-19fe24e6-pnpm" id="pm-tab-pm-19fe24e6-pnpm" data-nb-pm-tab class="text-muted-foreground hover:bg-accent hover:text-foreground aria-selected:bg-selected aria-selected:text-foreground focus-visible:outline-ring m-0 cursor-pointer rounded-md border-0 bg-transparent px-2 py-0.5 text-xs leading-5 font-medium transition-colors focus-visible:outline-2 focus-visible:outline-offset-2">pnpm</button><button role="tab" type="button" aria-selected="false" aria-controls="pm-panel-pm-19fe24e6-bun" id="pm-tab-pm-19fe24e6-bun" data-nb-pm-tab class="text-muted-foreground hover:bg-accent hover:text-foreground aria-selected:bg-selected aria-selected:text-foreground focus-visible:outline-ring m-0 cursor-pointer rounded-md border-0 bg-transparent px-2 py-0.5 text-xs leading-5 font-medium transition-colors focus-visible:outline-2 focus-visible:outline-offset-2">bun</button></div><div role="tabpanel" id="pm-panel-pm-19fe24e6-npm" aria-labelledby="pm-tab-pm-19fe24e6-npm" data-nb-pm-panel class="bg-card ring-border relative overflow-hidden rounded-lg text-inherit ring"><div class="flex items-stretch"><pre class="text-foreground my-0 min-w-0 grow overflow-x-auto border-0 bg-transparent px-4 py-3 font-mono text-sm leading-relaxed whitespace-pre"><code data-nb-pm-code><span class="text-success">npm</span><span class="text-warning"> i agents@latest</span></code></pre><button type="button" data-nb-pm-copy data-nb-command="npm i agents@latest" aria-label="Copy to clipboard" class="border-border text-muted-foreground hover:text-foreground focus-visible:outline-ring m-0 flex shrink-0 cursor-pointer items-center justify-center border-0 border-l border-solid bg-transparent px-3 transition-colors focus-visible:outline-2 focus-visible:-outline-offset-2"><svg width="1em" height="1em" viewBox="0 0 256 256" class="h-[18px] w-[18px]" data-icon="ph:copy"><path fill="currentColor" d="M216 32H88a8 8 0 0 0-8 8v40H40a8 8 0 0 0-8 8v128a8 8 0 0 0 8 8h128a8 8 0 0 0 8-8v-40h40a8 8 0 0 0 8-8V40a8 8 0 0 0-8-8m-56 176H48V96h112Zm48-48h-32V88a8 8 0 0 0-8-8H96V48h112Z"/></svg><svg width="1em" height="1em" viewBox="0 0 256 256" class="hidden h-[18px] w-[18px]" data-icon="ph:check"><path fill="currentColor" d="m229.66 77.66l-128 128a8 8 0 0 1-11.32 0l-56-56a8 8 0 0 1 11.32-11.32L96 188.69L218.34 66.34a8 8 0 0 1 11.32 11.32"/></svg></button></div></div><div role="tabpanel" id="pm-panel-pm-19fe24e6-yarn" aria-labelledby="pm-tab-pm-19fe24e6-yarn" hidden data-nb-pm-panel class="bg-card ring-border relative overflow-hidden rounded-lg text-inherit ring"><div class="flex items-stretch"><pre class="text-foreground my-0 min-w-0 grow overflow-x-auto border-0 bg-transparent px-4 py-3 font-mono text-sm leading-relaxed whitespace-pre"><code data-nb-pm-code><span class="text-success">yarn</span><span class="text-warning"> add agents@latest</span></code></pre><button type="button" data-nb-pm-copy data-nb-command="yarn add agents@latest" aria-label="Copy to clipboard" class="border-border text-muted-foreground hover:text-foreground focus-visible:outline-ring m-0 flex shrink-0 cursor-pointer items-center justify-center border-0 border-l border-solid bg-transparent px-3 transition-colors focus-visible:outline-2 focus-visible:-outline-offset-2"><svg width="1em" height="1em" viewBox="0 0 256 256" class="h-[18px] w-[18px]" data-icon="ph:copy"><path fill="currentColor" d="M216 32H88a8 8 0 0 0-8 8v40H40a8 8 0 0 0-8 8v128a8 8 0 0 0 8 8h128a8 8 0 0 0 8-8v-40h40a8 8 0 0 0 8-8V40a8 8 0 0 0-8-8m-56 176H48V96h112Zm48-48h-32V88a8 8 0 0 0-8-8H96V48h112Z"/></svg><svg width="1em" height="1em" viewBox="0 0 256 256" class="hidden h-[18px] w-[18px]" data-icon="ph:check"><path fill="currentColor" d="m229.66 77.66l-128 128a8 8 0 0 1-11.32 0l-56-56a8 8 0 0 1 11.32-11.32L96 188.69L218.34 66.34a8 8 0 0 1 11.32 11.32"/></svg></button></div></div><div role="tabpanel" id="pm-panel-pm-19fe24e6-pnpm" aria-labelledby="pm-tab-pm-19fe24e6-pnpm" hidden data-nb-pm-panel class="bg-card ring-border relative overflow-hidden rounded-lg text-inherit ring"><div class="flex items-stretch"><pre class="text-foreground my-0 min-w-0 grow overflow-x-auto border-0 bg-transparent px-4 py-3 font-mono text-sm leading-relaxed whitespace-pre"><code data-nb-pm-code><span class="text-success">pnpm</span><span class="text-warning"> add agents@latest</span></code></pre><button type="button" data-nb-pm-copy data-nb-command="pnpm add agents@latest" aria-label="Copy to clipboard" class="border-border text-muted-foreground hover:text-foreground focus-visible:outline-ring m-0 flex shrink-0 cursor-pointer items-center justify-center border-0 border-l border-solid bg-transparent px-3 transition-colors focus-visible:outline-2 focus-visible:-outline-offset-2"><svg width="1em" height="1em" viewBox="0 0 256 256" class="h-[18px] w-[18px]" data-icon="ph:copy"><path fill="currentColor" d="M216 32H88a8 8 0 0 0-8 8v40H40a8 8 0 0 0-8 8v128a8 8 0 0 0 8 8h128a8 8 0 0 0 8-8v-40h40a8 8 0 0 0 8-8V40a8 8 0 0 0-8-8m-56 176H48V96h112Zm48-48h-32V88a8 8 0 0 0-8-8H96V48h112Z"/></svg><svg width="1em" height="1em" viewBox="0 0 256 256" class="hidden h-[18px] w-[18px]" data-icon="ph:check"><path fill="currentColor" d="m229.66 77.66l-128 128a8 8 0 0 1-11.32 0l-56-56a8 8 0 0 1 11.32-11.32L96 188.69L218.34 66.34a8 8 0 0 1 11.32 11.32"/></svg></button></div></div><div role="tabpanel" id="pm-panel-pm-19fe24e6-bun" aria-labelledby="pm-tab-pm-19fe24e6-bun" hidden data-nb-pm-panel class="bg-card ring-border relative overflow-hidden rounded-lg text-inherit ring"><div class="flex items-stretch"><pre class="text-foreground my-0 min-w-0 grow overflow-x-auto border-0 bg-transparent px-4 py-3 font-mono text-sm leading-relaxed whitespace-pre"><code data-nb-pm-code><span class="text-success">bun</span><span class="text-warning"> add agents@latest</span></code></pre><button type="button" data-nb-pm-copy data-nb-command="bun add agents@latest" aria-label="Copy to clipboard" class="border-border text-muted-foreground hover:text-foreground focus-visible:outline-ring m-0 flex shrink-0 cursor-pointer items-center justify-center border-0 border-l border-solid bg-transparent px-3 transition-colors focus-visible:outline-2 focus-visible:-outline-offset-2"><svg width="1em" height="1em" viewBox="0 0 256 256" class="h-[18px] w-[18px]" data-icon="ph:copy"><path fill="currentColor" d="M216 32H88a8 8 0 0 0-8 8v40H40a8 8 0 0 0-8 8v128a8 8 0 0 0 8 8h128a8 8 0 0 0 8-8v-40h40a8 8 0 0 0 8-8V40a8 8 0 0 0-8-8m-56 176H48V96h112Zm48-48h-32V88a8 8 0 0 0-8-8H96V48h112Z"/></svg><svg width="1em" height="1em" viewBox="0 0 256 256" class="hidden h-[18px] w-[18px]" data-icon="ph:check"><path fill="currentColor" d="m229.66 77.66l-128 128a8 8 0 0 1-11.32 0l-56-56a8 8 0 0 1 11.32-11.32L96 188.69L218.34 66.34a8 8 0 0 1 11.32 11.32"/></svg></button></div></div><nb-pm-restore style="display:contents"></nb-pm-restore></div></div><script type="module" src="https://developers.cloudflare.com/home/runner/work/cloudflare-docs/cloudflare-docs/src/components/ui/package-managers/PackageManagerTabs.astro?astro&type=script&index=0&lang.ts"></script> <p>Move ordinary SDK v1 server definitions into an SDK v2 factory and serve them with <code>createMcpHandler</code>. The handler's default legacy compatibility means most stateless deployments need only one route.</p> <p>If an existing <code>McpAgent</code> server still needs sessionful features, add the stateless path beside it. Use <code>isLegacyRequest()</code> to send only legacy traffic to the existing route:</p> <div><div data-nb-tabs data-nb-sync-key="workersExamples" class><div class="relative flex border-b border-border" role="tablist" data-nb-tabs-list><span class="bg-primary pointer-events-none absolute -bottom-px h-0.5 rounded-t-sm transition-[left,width] duration-200 ease-out" data-nb-tabs-indicator aria-hidden="true"></span></div><div class="mt-3"><div role="tabpanel" data-nb-tabs-content data-nb-tab-label="JavaScript" class><figure class="nb-code-figure" data-nb-lang="js"><pre class="astro-code astro-code-themes github-light github-dark nb-shiki-c6xiwz" tabindex="0" data-language="js" data-nb-lang="js"><code><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></code></pre></figure></div><div role="tabpanel" data-nb-tabs-content data-nb-tab-label="TypeScript" class><figure class="nb-code-figure" data-nb-lang="ts"><pre class="astro-code astro-code-themes github-light github-dark nb-shiki-c6xiwz" tabindex="0" data-language="ts" data-nb-lang="ts"><code><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></code></pre></figure></div></div></div></div> <p>Migrate the remaining sessionful features, allow existing sessions to drain, then remove the legacy route. Refer to <a href="https://developers.cloudflare.com/agents/model-context-protocol/guides/migrate-to-mcp-sdk-v2/">Migrate to MCP SDK v2</a> for package changes, compatibility limits, and rollout steps.</p> <div tabindex="-1" class="heading-wrapper level-h4"><h4 id="deprecations-in-v0200">Deprecations in v0.20.0</h4><a class="anchor-link" href="#deprecations-in-v0200"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>This release deprecates the following Agents SDK APIs:</p> <div class="table-scroll" tabindex="0" role="region" aria-label="Table"><table> <thead> <tr> <th>Deprecated API</th> <th>Replacement</th> <th>Status</th> </tr> </thead> <tbody> <tr> <td><code>McpAgent</code></td> <td>Use an SDK v2 factory with <code>createMcpHandler</code> for stateless servers. Use the migration guide to replace stateful features before removing a legacy route.</td> <td>Feature-frozen. No removal version is announced.</td> </tr> <tr> <td><code>createMcpHandler(v1Server, options)</code></td> <td>Move the server to an SDK v2 factory and call <code>createMcpHandler(factory, options)</code>. Use <code>createLegacyMcpHandler</code> only as a temporary bridge for sessionful features.</td> <td>Scheduled for removal in the next major version.</td> </tr> <tr> <td><code>MCPClientManager.callTool(params, resultSchema, options)</code> and the equivalent <code>withX402Client</code> overload</td> <td>Use <code>callTool(params, options)</code> or <code>callTool(confirm, params, options)</code>.</td> <td>Compatibility overload. No removal version is announced.</td> </tr> </tbody> </table></div> <p>The MCP 2026-07-28 draft separately deprecates Roots, Sampling, Logging, the old HTTP+SSE transport, and Dynamic Client Registration.</p>
The text above is the source's. reef added the severity, the dates it could read from the text, and the endpoints and scopes named in code.