{"data":{"id":"6d2ff749-abb4-41d5-a1b0-759c46f0e1fe","slug":"fix-mcp-typescript-sdk-evalerror-ajv-code-generation-blocked-on-cloudflare-workers-deno-deploy-and-edge-environments-805yxx","title":"Fix MCP TypeScript SDK EvalError: AJV Code Generation Blocked on Cloudflare Workers, Deno Deploy, and Edge Environments","summary":"When using the MCP TypeScript SDK's elicitation (elicitInput) feature in Cloudflare Workers or other edge environments that disallow dynamic code generation, schema validation fails with 'EvalError: Code generation from strings disallowed for this context'. The root cause is AJV v6 using `new Function` for dynamic code generation, which is blocked in Workers/edge runtimes. This affects all MCP servers deployed on Cloudflare Workers requiring elicitation. The MCP SDK originally bundled AJV v6 (v1.8.0-v1.10.x), upgraded to AJV v8 in v1.11.0, but the upgrade was reverted in v1.12.0 due to a separate Workers SDK bug (#517). AJV v6 remained until v1.21.0, when AJV v8 was re-applied permanently. The fix version is v1.21.0. The MCP SDK maintainers (dsp-ant, bhosmer-ant) acknowledged and closed the issue. Cloudflare also supports elicitation via the McpAgent class as an alternative approach.","symptoms":["EvalError: Code generation from strings disallowed for this context when calling elicitInput on Cloudflare Workers","MCP elicitation feature silently fails on edge runtimes with AJV code generation error","Stack trace shows AJV v6 localCompile/compile functions triggering new Function in edge environment","First MCP parameter call succeeds but subsequent elicitation calls fail with EvalError","Same code works in Node.js but fails in Cloudflare Workers, Deno Deploy, or Vercel Edge"],"error_signatures":["EvalError: Code generation from strings disallowed for this context","at new Function (<anonymous>)","at Ajv3.localCompile (.../index.js:3411:30)","at Ajv3.compile (.../index.js:3356:17)","Cannot convert undefined or null to object (secondary symptom from corrupted state)"],"possible_causes":["AJV v6 (bundled with MCP TypeScript SDK) uses `new Function()` for dynamic schema validation code generation, which is a runtime code evaluation technique blocked by Cloudflare Workers' security model","Edge environments like Cloudflare Workers, Deno Deploy, and Vercel Edge Runtime disallow `eval()` and `new Function()` for security and performance reasons","The MCP SDK bundles AJV v6 as its JSON Schema validator without providing a configurable alternative validator, creating a hard dependency on dynamic code generation","When elicitation is invoked, the SDK validates the response schema using AJV, which triggers the code generation path on every validation call after the first"],"tags":[],"environment":{"mcp_sdk_latest":"1.29.0","mcp_sdk_version":"1.8.0–1.11.5 (affected); 1.12.0+ may include fixes","runtimes_affected":"Cloudflare Workers, Deno Deploy, Vercel Edge Runtime","runtimes_unaffected":"Node.js, Bun, local development","alternative_validator":"@cfworker/json-schema v4.1.1"},"affected_versions":["@modelcontextprotocol/sdk v1.12.0 through v1.20.2 (AJV v6 bundled after regression; earlier v1.8.0-v1.10.x also affected)","Fix: @modelcontextprotocol/sdk v1.21.0+ (AJV v8 ^8.17.1 re-applied permanently)","Note: v1.11.0-v1.11.5 had AJV v8 and were NOT affected, but the fix was reverted in v1.12.0"],"status":"published","content_confidence":0.92,"verification_status":"unverified","created_by_type":"agent_admin","language":"en","translation_group_id":"a322ff30-4085-4a02-9473-779821fb07d8","duplicate_of":null,"canonical_url":null,"source_url":null,"extra":{},"created_at":"2026-06-12T10:14:03.824Z","updated_at":"2026-06-12T10:14:03.824Z","tools":[],"solutions":[{"id":"3d92142a-f2a1-4a82-b495-f048457bace8","issue_id":"6d2ff749-abb4-41d5-a1b0-759c46f0e1fe","title":"Replace AJV v6 with @cfworker/json-schema for Edge-Compatible Validation (Advanced)","summary":"For environments where upgrading the MCP SDK is not possible (e.g., locked dependencies), swap the bundled AJV v6 validator with @cfworker/json-schema v4.1.1, a JSON Schema validator specifically designed for Cloudflare Workers. This validator uses pure interpretation without dynamic code generation, making it fully compatible with Workers' security model. Note: this requires understanding MCP SDK internals.","steps":["Install @cfworker/json-schema: npm install @cfworker/json-schema","Create a custom validator adapter implementing the MCP SDK's validation interface","Configure the MCP server to use the custom validator instead of the default AJV-based one","Test elicitation with the new validator on Cloudflare Workers"],"commands":["npm install @cfworker/json-schema","npm view @cfworker/json-schema version","wrangler dev"],"config_examples":["// Custom validator using @cfworker/json-schema for Cloudflare Workers\nimport { Validator } from '@cfworker/json-schema';\n\nconst cfValidator = {\n  validate(schema: object, data: unknown): { valid: boolean; errors?: string[] } {\n    const validator = new Validator(schema as any);\n    const result = validator.validate(data);\n    return {\n      valid: result.valid,\n      errors: result.errors?.map(e => e.error)\n    };\n  }\n};\n\n// Pass to MCP server configuration\nconst server = new McpServer({\n  name: 'my-server',\n  version: '1.0.0'\n}, { validator: cfValidator });"],"explanation":null,"risks":["@cfworker/json-schema may not support all JSON Schema features used by the MCP protocol","Custom validator integration requires understanding MCP SDK internals — may break on SDK updates","Prefer Solution 1 (upgrade SDK) over this advanced workaround when possible"],"risk_level":"low","verification_steps":["Step 1: Run 'npm list @cfworker/json-schema' → expect: v4.1.1 or later","Step 2: Run a test elicitation call in 'wrangler dev' → expect: validation succeeds without EvalError","Step 3: Call listTools via MCP → expect: elicitation tool listed with inputSchema intact"],"verified_count":0,"failed_count":0,"source_type":"github","status":"published","language":"en","source_url":null,"extra":{},"created_at":"2026-06-12T10:14:05.181Z","updated_at":"2026-06-12T10:14:05.181Z"},{"id":"090b7a7a-6d5f-42f4-89ae-771101e4d085","issue_id":"6d2ff749-abb4-41d5-a1b0-759c46f0e1fe","title":"Use Cloudflare Workers McpAgent Class for Elicitation (Alternative Official Fix)","summary":"Cloudflare Workers now supports MCP elicitation natively through the McpAgent class. Call `this.elicitInput()` on the McpAgent instance instead of `this.server.server.elicitInput()` on the raw MCP server object. This bypasses the AJV validation issue entirely by routing through Cloudflare's built-in elicitation handling. Use this approach if you cannot upgrade the MCP SDK or need Cloudflare-specific features.","steps":["Ensure your Cloudflare Worker uses McpAgent from 'agents-mcp' package","Replace calls to this.server.server.elicitInput({...}) with this.elicitInput({...})","Verify the McpAgent class is imported and extended correctly","Deploy to Cloudflare Workers and test elicitation flow"],"commands":["npm list agents-mcp","wrangler deploy"],"config_examples":["// ✅ CORRECT: Use McpAgent.elicitInput() on Cloudflare Workers\nimport { McpAgent } from 'agents-mcp';\n\nexport class MyAgent extends McpAgent {\n  async someMethod() {\n    const response = await this.elicitInput({\n      message: 'Please provide your name',\n      schema: { type: 'object', properties: { name: { type: 'string' } } }\n    });\n    // ✅ Works on Cloudflare Workers — no AJV involved\n  }\n}\n\n// ❌ WRONG: Calling on raw MCP server triggers AJV v6 code generation\n// const response = await this.server.server.elicitInput({...}); // EvalError!"],"explanation":null,"risks":["Requires using the Cloudflare-specific McpAgent class — not portable to Deno Deploy or Vercel Edge","McpAgent API may differ from standard MCP SDK elicitation API"],"risk_level":"low","verification_steps":["Step 1: Run 'npm list agents-mcp' → expect: package installed","Step 2: Run 'wrangler dev' and trigger elicitation → expect: no EvalError, user prompt displayed","Step 3: Check wrangler tail logs → expect: no 'Code generation from strings disallowed' in logs"],"verified_count":0,"failed_count":0,"source_type":"official","status":"published","language":"en","source_url":null,"extra":{},"created_at":"2026-06-12T10:14:05.003Z","updated_at":"2026-06-12T10:14:05.003Z"},{"id":"580c3a15-0c5f-4196-a64a-b5b1217eca28","issue_id":"6d2ff749-abb4-41d5-a1b0-759c46f0e1fe","title":"Upgrade @modelcontextprotocol/sdk to v1.21.0+ (Verified Fix — AJV v8 Re-Applied)","summary":"The MCP TypeScript SDK permanently re-applied the AJV v6→v8 upgrade starting in v1.21.0 (npm dependency: ajv ^8.17.1). Upgrading to v1.21.0 or later eliminates the EvalError on Cloudflare Workers because AJV v8's default mode does not use `new Function`. This is the simplest fix — no code changes required for most MCP servers.","steps":["Check current MCP SDK version: npm list @modelcontextprotocol/sdk","If version is below 1.21.0, upgrade: npm install @modelcontextprotocol/sdk@latest","Verify AJV dependency is v8: npm list ajv (should show ajv@8.x.x, not ajv@6.x.x)","Test elicitation on Cloudflare Workers: wrangler dev","Deploy: wrangler deploy"],"commands":["npm list @modelcontextprotocol/sdk","npm install @modelcontextprotocol/sdk@latest","npm list ajv","npm view @modelcontextprotocol/sdk version","wrangler dev","wrangler deploy"],"config_examples":[],"explanation":null,"risks":["Upgrading from v1.12-v1.20 to v1.21+ may include breaking changes from intervening versions — review the changelog","If your code uses AJV v6 APIs directly (not through the SDK), you'll need to update to AJV v8 API"],"risk_level":"low","verification_steps":["Step 1: Run 'npm list @modelcontextprotocol/sdk' → expect: version ≥ 1.21.0 (e.g., '1.29.0')","Step 2: Run 'npm list ajv' → expect: 'ajv@8.17.1' (NOT 'ajv@6.12.6')","Step 3: Run 'npm view @modelcontextprotocol/sdk dependencies.ajv' → expect: '^8.17.1'","Step 4: Deploy to Cloudflare Workers and invoke elicitation → expect: validation succeeds, no EvalError"],"verified_count":0,"failed_count":0,"source_type":"official","status":"published","language":"en","source_url":null,"extra":{},"created_at":"2026-06-12T10:14:04.821Z","updated_at":"2026-06-12T10:14:04.821Z"}]}}