Problem
The emulate tool fails when used with Claude Code (and the Claude API in general) because the tool's input schema contains anyOf, which the Claude API does not support.
Error:
tools.N.custom.input_schema: input_schema does not support oneOf, allOf, or anyOf
Root Cause
In build/src/tools/emulation.js, the geolocation and viewport fields use .nullable().optional() on Zod objects:
geolocation: zod
.object({
latitude: zod.number().min(-90).max(90),
longitude: zod.number().min(-180).max(180),
})
.nullable() // <-- produces anyOf
.optional()
viewport: zod
.object({
width: zod.number().int().min(0),
height: zod.number().int().min(0),
deviceScaleFactor: zod.number().min(0).optional(),
isMobile: zod.boolean().optional(),
hasTouch: zod.boolean().optional(),
isLandscape: zod.boolean().optional(),
})
.nullable() // <-- produces anyOf
.optional()
The bundled zod-to-json-schema converter in third_party/index.js (line ~22174) translates .nullable() on objects to:
{
"anyOf": [
{ "type": "object", "properties": { ... } },
{ "type": "null" }
]
}
Note: .nullable() on primitives (like userAgent: zod.string().nullable()) is fine — the converter uses type: ["string", "null"] for those. The issue only affects .nullable() on object schemas.
Impact
- Version affected: 0.16.0 (latest via npx)
- Tool affected:
emulate only (the other 25+ tools work fine)
- Who's affected: Anyone using this MCP server with Claude Code or the Claude API
Suggested Fix
Replace .nullable().optional() with .optional() and handle null clearing logic at the tool handler level. For example:
// Before:
geolocation: zod.object({ ... }).nullable().optional()
// After:
geolocation: zod.object({ ... }).optional()
// Handle "clear geolocation" via a separate boolean flag or empty object convention
Alternatively, post-process the generated JSON Schema to replace anyOf: [{object}, {type: "null"}] with just the object schema marked as optional.
Environment
chrome-devtools-mcp v0.16.0 (via npx)
- Claude Code CLI
- macOS (Apple Silicon)
Problem
The
emulatetool fails when used with Claude Code (and the Claude API in general) because the tool's input schema containsanyOf, which the Claude API does not support.Error:
Root Cause
In
build/src/tools/emulation.js, thegeolocationandviewportfields use.nullable().optional()on Zod objects:The bundled
zod-to-json-schemaconverter inthird_party/index.js(line ~22174) translates.nullable()on objects to:{ "anyOf": [ { "type": "object", "properties": { ... } }, { "type": "null" } ] }Note:
.nullable()on primitives (likeuserAgent: zod.string().nullable()) is fine — the converter usestype: ["string", "null"]for those. The issue only affects.nullable()on object schemas.Impact
emulateonly (the other 25+ tools work fine)Suggested Fix
Replace
.nullable().optional()with.optional()and handlenullclearing logic at the tool handler level. For example:Alternatively, post-process the generated JSON Schema to replace
anyOf: [{object}, {type: "null"}]with just the object schema marked as optional.Environment
chrome-devtools-mcpv0.16.0 (via npx)