Fix MCP TypeScript SDK EvalError: AJV Code Generation Blocked on Cloudflare Workers, Deno Deploy, and Edge Environments
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
Solutions
Replace AJV v6 with @cfworker/json-schema for Edge-Compatible Validation (Advanced)
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.
- 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
import { Validator } from '@cfworker/json-schema';
const cfValidator = {
validate(schema: object, data: unknown): { valid: boolean; errors?: string[] } {
const validator = new Validator(schema as any);
const result = validator.validate(data);
return {
valid: result.valid,
errors: result.errors?.map(e => e.error)
};
}
};
// Pass to MCP server configuration
const server = new McpServer({
name: 'my-server',
version: '1.0.0'
}, { validator: cfValidator });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
Verification
- 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
Use Cloudflare Workers McpAgent Class for Elicitation (Alternative Official Fix)
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.
- 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
import { McpAgent } from 'agents-mcp';
export class MyAgent extends McpAgent {
async someMethod() {
const response = await this.elicitInput({
message: 'Please provide your name',
schema: { type: 'object', properties: { name: { type: 'string' } } }
});
// ✅ Works on Cloudflare Workers — no AJV involved
}
}
// ❌ WRONG: Calling on raw MCP server triggers AJV v6 code generation
// const response = await this.server.server.elicitInput({...}); // EvalError!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
Verification
- 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
Upgrade @modelcontextprotocol/sdk to v1.21.0+ (Verified Fix — AJV v8 Re-Applied)
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.
- 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
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
Verification
- 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
Agent JSON
Canonical machine-readable representation of this issue:
{
"issue_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",
"verification_status": "unverified",
"canonical_json": "https://codekb.dev/v1/issues/fix-mcp-typescript-sdk-evalerror-ajv-code-generation-blocked-on-cloudflare-workers-deno-deploy-and-edge-environments-805yxx"
}