Skip to content

feat(agents): make @modelcontextprotocol/sdk and /server optional peers - #2634

Open
mattzcarey wants to merge 4 commits into
mainfrom
chore/optional-peer-deps
Open

mattzcarey wants to merge 4 commits into
mainfrom
chore/optional-peer-deps

Conversation

@mattzcarey

@mattzcarey mattzcarey commented Oct 20, 2026 •

Copy link
Copy Markdown
Member

@modelcontextprotocol/sdk (v1) and @modelcontextprotocol/server (v2) are now optional peers of agents, so apps that do not serve MCP stop installing the v1 server stack (express, cors, raw-body, @hono/node-server, ...). The root agents entry and agents/mcp/client now load neither package, at runtime or in their .d.ts. Fixes #2209.

Marking them optional was not enough on its own, because the root entry reached the v1 SDK through the MCP client:

  • src/mcp/rpc.ts held both RPC transports. RPCServerTransport imported v1 values, and the client chunk pulled it in. It now lives in src/mcp/rpc-server.ts, used only by McpAgent.
  • addMcpServer(name, binding) and RPCClientTransportOptions were typed against McpAgent, which dragged the whole legacy server into the root types. They now use a structural McpRpcAgent (an Agent with handleMcpMessage). It accepts the same classes as before.
  • The v1/v2 client binder that agents/x402 uses moved to src/mcp/client/invoker-compat.ts. The deprecated legacy result-schema overload of MCPClientManager.callTool now takes any { parse } schema instead of the v1 zod type.
Package Needed for
@modelcontextprotocol/server agents/mcp/server (createMcpHandler)
@modelcontextprotocol/sdk agents/mcp (McpAgent, WorkerTransport, createLegacyMcpHandler), agents/experimental/webmcp

agents/mcp/client now also exports RPCClientTransport, RPC_DO_PREFIX, McpClientOptions and the elicitation handler types, so apps that took those from the agents/mcp barrel can move off it and drop the v1 SDK.

@modelcontextprotocol/client and zod stay required, because every Agent constructs the MCP client. The changeset is minor: npm users who use the legacy APIs and relied on the auto-installed peer without declaring it must now add @modelcontextprotocol/sdk themselves. McpAgent stays.

Docs updated in docs/agents/mcp-servers.md, mcp-transports.md, mcp-client.md and the package README. cloudflare-docs: cloudflare/cloudflare-docs#34485.

  • New src/node-tests/optional-mcp-peers-bundle.test.ts bundles agents, agents/client, agents/react and agents/mcp/client and fails if either package is reached. It fails on main.
  • Packed the tarball into a scratch Worker with only agents installed: no v1 SDK or express in node_modules, and wrangler deploy --dry-run builds an Agent that calls addMcpServer.
  • pnpm run typecheck, check:exports, and the workers MCP, x402, webmcp and node suites ran.

Devin Review

Fixes #2209. The root entry reached the v1 SDK at runtime through the RPC
server transport, and its types through McpAgent and the v1 client invoker.
Split RPCServerTransport into mcp/rpc-server.ts, type the RPC client against a
structural McpRpcAgent, and move the v1/v2 client binder used by x402 into
invoker-compat.ts. Adds a bundle test so the root, client, react, and
mcp/client entries stay free of both packages.
@changeset-bot

changeset-bot Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: dba5454

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
agents Minor
@cloudflare/agent-think Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@agent-think

agent-think Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

🟢 agents import sizes: 4 entry points changed, no growth

Entry point Exports Largest gzip change Size now
🆕 agents/mcp/client 4 resized, 2 new up to -3.3 KiB (-2.03%) 157.8 KiB
🟢 agents/chat-sdk 5 resized up to -3.4 KiB (-1.28%) 263.8 KiB
🟢 agents 30 resized up to -3.4 KiB (-1.27%) 262.8 KiB
🟢 agents/workflows 2 resized up to -3.4 KiB (-1.26%) 263.5 KiB
Changed exports (43)
Import Gzip change Size now
🆕 agents/mcp/client#RPCClientTransport — 61 KiB
🆕 agents/mcp/client#RPC_DO_PREFIX — 60.1 KiB
🟢 agents/chat-sdk#ChatSdkStateAgent -3.4 KiB (-1.28%) 263.8 KiB
🟢 agents#buildAgentUrl -3.4 KiB (-1.27%) 262.8 KiB
🟢 agents#routeSubAgentRequest -3.4 KiB (-1.27%) 262.3 KiB
🟢 agents#routeAgentEmail -3.4 KiB (-1.27%) 262.4 KiB
🟢 agents/chat-sdk#ChatSdkStateAdapter -3.4 KiB (-1.26%) 264.7 KiB
🟢 agents/chat-sdk#createChatSdkState -3.4 KiB (-1.26%) 264.7 KiB
🟢 agents/workflows#AgentWorkflow -3.4 KiB (-1.26%) 263.5 KiB
🟢 agents#routeAgentRequest -3.4 KiB (-1.26%) 262.8 KiB
🟢 agents#createHeaderBasedEmailResolver -3.3 KiB (-1.26%) 262.3 KiB
🟢 agents#getSubAgentByName -3.3 KiB (-1.26%) 262.4 KiB
🟢 agents#buildAgentPath -3.3 KiB (-1.26%) 262.7 KiB
🟢 agents#MessageType -3.3 KiB (-1.26%) 262.3 KiB
🟢 agents#Agent -3.3 KiB (-1.26%) 262.1 KiB
🟢 agents#StreamingResponse -3.3 KiB (-1.26%) 262.1 KiB
🟢 agents#SUB_PREFIX -3.3 KiB (-1.26%) 262.1 KiB
🟢 agents#AGENT_TOOL_PROGRESS_PART -3.3 KiB (-1.26%) 262.1 KiB
🟢 agents#isDurableObjectStorageReset -3.3 KiB (-1.25%) 262.1 KiB
🟢 agents#MCP_SERVER_ID_MAX_LENGTH -3.3 KiB (-1.25%) 262.1 KiB
🟢 agents#callable -3.3 KiB (-1.25%) 262.1 KiB
🟢 agents#SqlError -3.3 KiB (-1.25%) 262.1 KiB
🟢 agents#__DO_NOT_USE_WILL_BREAK__agentContext -3.3 KiB (-1.25%) 262.1 KiB
🟢 agents#camelCaseToKebabCase -3.3 KiB (-1.25%) 262.1 KiB
🟢 agents#__DO_NOT_USE_WILL_BREAK__withInvocationScope -3.3 KiB (-1.25%) 262.1 KiB
🟢 agents/chat-sdk#defaultKeyShard -3.3 KiB (-1.25%) 262.2 KiB
🟢 agents#unstable_callable -3.3 KiB (-1.25%) 262.3 KiB
🟢 agents#getAgentByName -3.3 KiB (-1.25%) 262.1 KiB
🟢 agents#isDurableObjectMemoryLimitReset -3.3 KiB (-1.25%) 262.1 KiB
🟢 agents#parseSubAgentPath -3.3 KiB (-1.25%) 262.1 KiB
🟢 agents#getCurrentAgent -3.3 KiB (-1.25%) 262.1 KiB
🟢 agents#DEFAULT_AGENT_STATIC_OPTIONS -3.3 KiB (-1.25%) 262.1 KiB
🟢 agents#normalizeServerId -3.3 KiB (-1.25%) 262.1 KiB
🟢 agents/workflows#WorkflowRejectedError -3.3 KiB (-1.25%) 262.2 KiB
🟢 agents#isDurableObjectCodeUpdateReset -3.3 KiB (-1.25%) 262.1 KiB
🟢 agents/chat-sdk#defaultThreadShard -3.3 KiB (-1.25%) 262.1 KiB
🟢 agents#DurableObjectOAuthClientProvider -3.3 KiB (-1.25%) 262.1 KiB
🟢 agents#isPlatformTransientError -3.3 KiB (-1.25%) 262.1 KiB
🟢 agents#AGENT_TOOL_MILESTONE_PART -3.3 KiB (-1.25%) 262.1 KiB
🟢 agents/mcp/client#MCPClientManager -3.3 KiB (-2.03%) 157.8 KiB
🟢 agents/mcp/client#normalizeServerId -3.2 KiB (-5.04%) 60.2 KiB
🟢 agents/mcp/client#getNamespacedData -3.2 KiB (-5.02%) 60.2 KiB
🟢 agents/mcp/client#MCP_SERVER_ID_MAX_LENGTH -3.2 KiB (-5.01%) 60.1 KiB
How this works

Each runtime export is bundled on its own, minified, and gzipped. Changes smaller than 100 B, or smaller than 1% and 1 KiB, are ignored. Growth over 10% or 5 KiB is marked 🔴. This report is informational and does not fail CI. The workflow artifact contains every measurement.

Compared fc7f59fb → dba54541 · workflow run · reported by agent-think[bot]

@devin-ai-integration devin-ai-integration Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Newer findings are available below. Devin Review posted a newer report on this PR, in addition to the findings presented here.

Devin Review found 3 potential issues.

Devin Review

Comment on lines +110 to +111
"@modelcontextprotocol/server": {
"optional": true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Legacy MCP servers require both peers

Installing only the documented v1 peer makes McpAgent fail to load. McpAgent eagerly imports @modelcontextprotocol/server, which the new optional peer declaration no longer installs.

Learn more

The legacy agents/mcp entry re-exports McpAgent through the compatibility barrel. McpAgent imports v2 server constructors at module initialization for its version check, and the legacy handler barrel also re-exports a compatibility handler that imports v2 code. Marking the v2 peer optional lets npm omit it when users install only the documented v1 SDK, so a Worker importing agents/mcp fails before serving any request.

Example: An application installs agents and @modelcontextprotocol/sdk@1.32.1, then imports McpAgent from agents/mcp. Its Worker cannot load because @modelcontextprotocol/server is absent, although it uses only a v1 server.

Recommended fix: Remove eager v2 imports from the legacy entry, including the instanceof checks in McpAgent and the stateless handler re-export chain. Keep v2-dependent functionality behind the separate v2 entry or an explicit opt-in boundary; test importing and deploying agents/mcp with only the v1 peer installed.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

"agents": minor
---

`@modelcontextprotocol/sdk` and `@modelcontextprotocol/server` are now optional peer dependencies, so apps that do not serve MCP no longer install the SDK v1 server stack (`express`, `cors`, `@hono/node-server`, and others). Install `@modelcontextprotocol/server` for `agents/mcp/server`, and `@modelcontextprotocol/sdk` for `McpAgent`, `WorkerTransport`, `createLegacyMcpHandler`, and `agents/experimental/webmcp`. The root `agents` entry and `agents/mcp/client` need neither. If your app imports `@modelcontextprotocol/sdk` without listing it in `package.json`, add it before upgrading. The `agents/mcp` barrel needs `@modelcontextprotocol/sdk` even when you only import client helpers from it, so import those from `agents/mcp/client` instead. See [Creating MCP Servers](https://github.com/cloudflare/agents/blob/main/docs/agents/mcp-servers.md#choosing-an-approach).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Changeset duplicates documentation

The repository requires a single concise description linking to documentation. This multi-sentence release note embeds installation details that belong in the linked guide.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +17 to +24
The two server paths use different MCP SDK packages, and both are optional peer dependencies of `agents`. Install only the one you use:

| Package | Needed for |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------ |
| `@modelcontextprotocol/server@2.3.1` | `createMcpHandler()` from `agents/mcp/server` |
| `@modelcontextprotocol/sdk@1.32.1` | `McpAgent`, `WorkerTransport`, `createLegacyMcpHandler()`, and the other SDK v1 APIs from `agents/mcp` |

The `agents` root entry and the MCP client in `agents/mcp/client` do not need either package.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Public documentation sync is pending

The repository requires matching cloudflare-docs updates. The PR description says this port remains outstanding, leaving published installation guidance inconsistent.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

Devin Review

Comment on lines +110 to +112
"@modelcontextprotocol/server": {
"optional": true
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Legacy MCP servers require an undocumented peer

When an app installs only the documented v1 SDK, importing McpAgent fails without @modelcontextprotocol/server. McpAgent loads v2 classes at runtime, so the legacy server cannot start.

Learn more

The legacy agents/mcp entry imports McpAgent, which loads the v2 package to reject v2 servers. The same entry re-exports createMcpHandler, whose compatibility dispatcher imports the v2 handler. Marking v2 optional means an installation containing only the documented v1 peer cannot load the legacy entry at all.

Example: An existing app upgrades agents, adds @modelcontextprotocol/sdk@1.32.1 as instructed, and does not install @modelcontextprotocol/server. Loading its McpAgent class fails while resolving the missing v2 package, before it can serve requests.

Recommended fix: Remove eager v2 runtime imports from the legacy entry when v2 is absent, including the instanceof check and compatibility dispatcher. Preserve the v2 overload through an isolated entry or another approach that only loads v2 after the caller selects that path. Test bundling and loading agents/mcp with v1 installed and v2 absent.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

@pkg-pr-new

pkg-pr-new Bot commented Oct 20, 2026

Copy link
Copy Markdown

Open in StackBlitz

agents

npm i https://pkg.pr.new/agents@2634

@cloudflare/ai-chat

npm i https://pkg.pr.new/@cloudflare/ai-chat@2634

@cloudflare/codemode

npm i https://pkg.pr.new/@cloudflare/codemode@2634

hono-agents

npm i https://pkg.pr.new/hono-agents@2634

@cloudflare/shell

npm i https://pkg.pr.new/@cloudflare/shell@2634

@cloudflare/think

npm i https://pkg.pr.new/@cloudflare/think@2634

@cloudflare/voice

npm i https://pkg.pr.new/@cloudflare/voice@2634

@cloudflare/worker-bundler

npm i https://pkg.pr.new/@cloudflare/worker-bundler@2634

commit: dba5454

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Avoid installing the legacy MCP SDK when legacy APIs are unused

1 participant