agents-0-20-0-18-b
Claude Code's read-only tools, web search on, ludion sync on
Question
How do I serve a stateless MCP server from a Worker with the Cloudflare agents package and the v2 MCP SDK?
Answer key
- A correct answer says
- `createMcpHandler` accepts a factory returning a v2 `McpServer`/`Server` from `@modelcontextprotocol/server` and serves stateless MCP with legacy compatibility; `createLegacyMcpHandler` remains for SDK v1 servers.
- The stale answer
- `createMcpHandler` takes an `McpServer` from `@modelcontextprotocol/sdk` (v1).
Answer
Import `createMcpHandler` from `agents/mcp/server` and pass it a **factory function** that builds and returns a new SDK v2 `McpServer`, not a server instance. Then return the handler from your Worker's `fetch`:
```ts
import { createMcpHandler } from "agents/mcp/server";
export default {
fetch: createMcpHandler(() => {
const server = new McpServer({ name: "my-server", version: "1.0.0" });
// register tools/resources here
return server;
}),
};
```
In agents 0.27.0, which this project has installed, a function passed to `createMcpHandler` is always treated as an SDK v2 factory. It returns a `StatelessMcpHandler` and gives each concurrent request its own server instance. So register tools inside the factory, and don't keep per-request state in a shared server at module scope. Passing an SDK v1 server instance still works but is deprecated (see `node_modules/agents/dist/agent-routing-Bhdbvf7s.d.ts:1187`). `createLegacyMcpHandler` exists only to keep the old sessionful v1 behavior while you migrate.Grade
correct
The judge's reason: It says createMcpHandler takes a factory returning an SDK v2 McpServer for stateless serving and that createLegacyMcpHandler remains for v1, without presenting the v1 instance form as current (it does omit the @modelcontextprotocol/server import path).
Session log
Tool call: Grep
{ "pattern": "createMcpHandler", "path": "C:\\Users\\haya0\\AppData\\Local\\Temp\\ludion-bench-SM0BOb\\work", "glob": "*.d.ts", "output_mode": "content", "head_limit": 10 }Tool output
node_modules\agents\dist\agent-routing-Bhdbvf7s.d.ts:1178: * New Stateless servers should use `createMcpHandler` from node_modules\agents\dist\agent-routing-Bhdbvf7s.d.ts:1188: * @deprecated Passing an SDK v1 server to createMcpHandler is deprecated and node_modules\agents\dist\agent-routing-Bhdbvf7s.d.ts:1190: * createMcpHandler. Use createLegacyMcpHandler only to temporarily retain node_modules\agents\dist\agent-routing-Bhdbvf7s.d.ts:1193:declare function createMcpHandler$1( node_modules\agents\dist\agent-routing-Bhdbvf7s.d.ts:1197:declare function createMcpHandler$1( node_modules\agents\dist\agent-routing-Bhdbvf7s.d.ts:1202: * @deprecated Pass an SDK v2 factory to createMcpHandler. node_modules\agents\dist\agent-routing-Bhdbvf7s.d.ts:1203: * experimental_createMcpHandler will be removed in the next major version. node_modules\agents\dist\agent-routing-Bhdbvf7s.d.ts:1207:declare function experimental_createMcpHandler( node_modules\agents\dist\agent-routing-Bhdbvf7s.d.ts:1303: * createMcpHandler from agents/mcp/server. When sessionful features prevent an node_modules\agents\dist\agent-routing-Bhdbvf7s.d.ts:6974: createMcpHandler$1 as cn, [Showing results with pagination = limit: 10]Tool call: Read
{ "file_path": "C:\\Users\\haya0\\AppData\\Local\\Temp\\ludion-bench-SM0BOb\\work\\node_modules\\agents\\dist\\agent-routing-Bhdbvf7s.d.ts", "offset": 1170, "limit": 45 }Tool output
1170 type LegacyMcpHandler = ( 1171 request: Request, 1172 env: unknown, 1173 ctx: ExecutionContext 1174 ) => Promise<Response>; 1175 /** 1176 * Create a sessionful Legacy MCP handler backed by SDK v1. 1177 * 1178 * New Stateless servers should use `createMcpHandler` from 1179 * `agents/mcp/server` instead. 1180 */ 1181 declare function createLegacyMcpHandler( 1182 server: McpServer$1 | Server$1, 1183 options?: CreateLegacyMcpHandlerOptions 1184 ): LegacyMcpHandler; 1185 //#endregion 1186 //#region src/mcp/server/handler-compat.d.ts 1187 /** 1188 * @deprecated Passing an SDK v1 server to createMcpHandler is deprecated and 1189 * will be removed in the next major version. Pass an SDK v2 factory to 1190 * createMcpHandler. Use createLegacyMcpHandler only to temporarily retain 1191 * sessionful SDK v1 behavior while migrating. 1192 */ 1193 declare function createMcpHandler$1( 1194 server: McpServer$1 | Server$1, 1195 options?: CreateMcpHandlerOptions$1 1196 ): LegacyMcpHandler; 1197 declare function createMcpHandler$1( 1198 factory: McpServerFactory, 1199 options?: CreateStatelessMcpHandlerOptions 1200 ): StatelessMcpHandler; 1201 /** 1202 * @deprecated Pass an SDK v2 factory to createMcpHandler. 1203 * experimental_createMcpHandler will be removed in the next major version. 1204 * Use createLegacyMcpHandler only to temporarily retain sessionful SDK v1 1205 * behavior while migrating. 1206 */ 1207 declare function experimental_createMcpHandler( 1208 server: McpServer$1 | Server$1, 1209 options?: CreateMcpHandlerOptions$1 1210 ): LegacyMcpHandler; 1211 //#endregion 1212 //#region src/mcp/server/event-store.d.ts 1213 /** 1214 * Durable Object–backed {@link EventStore} for SSE resumability.Agent
Import `createMcpHandler` from `agents/mcp/server` and pass it a **factory function** that builds and returns a new SDK v2 `McpServer`, not a server instance. Then return the handler from your Worker's `fetch`: ```ts import { createMcpHandler } from "agents/mcp/server"; export default { fetch: createMcpHandler(() => { const server = new McpServer({ name: "my-server", version: "1.0.0" }); // register tools/resources here return server; }), }; ``` In agents 0.27.0, which this project has installed, a function passed to `createMcpHandler` is always treated as an SDK v2 factory. It returns a `StatelessMcpHandler` and gives each concurrent request its own server instance. So register tools inside the factory, and don't keep per-request state in a shared server at module scope. Passing an SDK v1 server instance still works but is deprecated (see `node_modules/agents/dist/agent-routing-Bhdbvf7s.d.ts:1187`). `createLegacyMcpHandler` exists only to keep the old sessionful v1 behavior while you migrate.