Anthropic Tool Schema Validation Errors: 7 Patterns That Return 400 (2026)
Claude Code v2.0.21+ strict MCP schema validation breaks working tools. This guide covers every 400 error pattern — oneOf/allOf/anyOf, $schema property key, invalid $ref, strict field, outputSchema — and gives the exact fix for each.
Have broken JSON right now? Fix it free in under 1 second — no signup.
Fix My JSON →Your MCP server works perfectly. The MCP Inspector accepts every tool. Your local tests pass.
Then you connect to Claude Code, and get this:
API Error 400: tools.0.custom.input_schema: input_schema does not support
oneOf, allOf, or anyOf at the top level
Or this:
Invalid JSON Schema for Tool Definition: property key "$schema" does not
match pattern ^[a-zA-Z0-9_.-]{1,64}$
Or your tool definitions were fine for months, and Claude Code v2.0.21 silently dropped your entire MCP server without explanation.
These errors follow specific patterns. Each one has a fix. This guide covers all seven.
Why Anthropic's Tool Schema Validation Is Stricter Than JSON Schema
The Anthropic API uses a restricted subset of JSON Schema draft 2020-12 for tool input_schema. It does not support the full specification.
Claude Code v2.0.21 (released 2026) made this validation stricter and applied it earlier — at the MCP server connection phase rather than at tool call time. The result: MCP servers that returned valid JSON Schema and worked fine with older Claude Code versions now fail on connection.
The MCP 2026-07-28 RC will flip part of this: oneOf, anyOf, allOf, and $ref/$defs will be fully supported in tool schemas. But until then, you need to work within the current constraints.
The 7 Error Patterns
Error 1: oneOf, allOf, anyOf at the Top Level
Error message:
tools.N.custom.input_schema: input_schema does not support oneOf, allOf,
or anyOf at the top level
Why it happens:
The Anthropic API requires input_schema to have "type": "object" at the top level. If the top-level schema uses oneOf or anyOf (for example, a union type generated by Zod via the MCP TypeScript SDK), the API rejects the entire tool definition.
The MCP TypeScript SDK v1.26.0+ generates oneOf when your tool accepts union parameter types (e.g., string | number). This passes MCP Inspector validation — which runs full JSON Schema — but fails Anthropic API validation.
Flatten the union into an object with type: "object" and describe the variants in the property descriptions:
// Before (fails Anthropic API)
{
"input_schema": {
"oneOf": [
{ "type": "string" },
{ "type": "integer" }
]
}
}
// After (works)
{
"input_schema": {
"type": "object",
"properties": {
"value": {
"description": "String or integer value"
}
},
"required": ["value"]
}
}
For Zod-based MCP servers, avoid z.union() at the parameter root level. Wrap it in a z.object().
Error 2: The $schema Property Key
Error message:
tools.N.custom.input_schema: property key "$schema" does not match
pattern ^[a-zA-Z0-9_.-]{1,64}$
Why it happens:
The Anthropic API enforces a strict naming pattern on all property keys in tool schemas: ^[a-zA-Z0-9_.-]{1,64}$. The dollar sign $ is not in this allowed set.
$schema is a standard JSON Schema meta-keyword (e.g., "$schema": "https://json-schema.org/draft/2020-12/schema"). Most JSON Schema generators include it by default. The Anthropic API rejects it.
This issue surfaced widely in early 2026 when the MCP Explore subagent began sending full tool schemas to the API upfront rather than deferring them (GitHub issue #34249).
Fix:Strip $schema before sending to the API:
# Python — strip $schema before registering tool
def clean_schema(schema: dict) -> dict:
return {k: v for k, v in schema.items() if k != "$schema"}
// TypeScript
function cleanSchema(schema: Record<string, unknown>) {
const { $schema, ...rest } = schema;
return rest;
}
Same pattern applies to $id, $defs references that point outside the schema, and any other $-prefixed meta-keywords.
Error 3: Invalid $ref References
Error message:
Invalid JSON Schema for Tool Definition: $ref "#/$defs/MyType" points to a
definition that does not exist in the schema
Why it happens:
$ref is supported in tool schemas only when the referenced $defs definition exists within the same schema object. Cross-schema references ($ref to an external URL or a $defs key not present in the current schema) are rejected.
This commonly happens when shared schema types are factored into a central definitions file and referenced across multiple tool schemas — a pattern that works in full JSON Schema but fails Anthropic's per-schema validation.
Fix:Inline the referenced type directly in each tool schema:
// Before (fails — $defs missing in this schema)
{
"type": "object",
"properties": {
"config": { "$ref": "#/$defs/ConnectionConfig" }
}
}
// After (works — definition inlined)
{
"type": "object",
"properties": {
"config": {
"type": "object",
"properties": {
"host": { "type": "string" },
"port": { "type": "integer" }
},
"required": ["host", "port"]
}
}
}
Error 4: The OpenAI strict Field
Error message (Claude Desktop):
MCP server exposes API-specific 'strict' field in tool schemas, breaking
Claude Desktop compatibility
Why it happens:
OpenAI's structured output API uses a "strict": true field in tool definitions. MCP servers that support multiple LLM clients sometimes include this field in their tool schemas. Claude Desktop's MCP client rejects it during schema validation (GitHub issue #10858).
The strict field is an OpenAI-specific extension, not part of the MCP or JSON Schema specification.
Strip the strict field before exposing tools via MCP:
// Strip OpenAI-specific fields from MCP tool definitions
function sanitizeForMCP(tool: OpenAITool): MCPTool {
const { strict, ...rest } = tool.function;
return {
name: rest.name,
description: rest.description,
inputSchema: rest.parameters
};
}
If your MCP server targets multiple providers, maintain separate schema objects per provider rather than sharing one schema with provider-specific extensions.
Error 5: Claude Code v2.0.21 Silent MCP Drops
Symptom: MCP server connects but tools are missing. No error message. The server worked fine before updating Claude Code. Why it happens:Claude Code v2.0.21 introduced stricter MCP schema validation with no opt-out mechanism and no migration warning (GitHub issue #10606). Invalid schemas cause Claude Code to skip the entire MCP server silently — it continues without the tools rather than surfacing the error.
How to diagnose:Check Claude Code logs for validation errors:
# macOS / Linux
tail -f ~/.claude/logs/mcp-*.log
Look for lines containing:
grep -i "schema\|validation\|invalid" ~/.claude/logs/mcp-*.log
The skipSchemaValidation: true config option bypasses Claude Code's local validation but does not bypass the Anthropic API's validation — tools with invalid schemas will still return 400 errors on API calls.
Use the validator in MCP Inspector before deploying:
npx @modelcontextprotocol/inspector validate-schema ./your-mcp-server
Fix the underlying schema issues using the patterns in this guide.
Error 6: Property Keys Outside ^[a-zA-Z0-9_.-]{1,64}$
Error message:
tools.N.custom.input_schema: property key "my:property" does not match
pattern ^[a-zA-Z0-9_.-]{1,64}$
Why it happens:
Anthropic enforces the naming pattern on all property keys in the schema, not just top-level meta-keywords. Property names containing :, @, /, spaces, or other special characters are rejected.
This is uncommon but surfaces when generating schemas from OpenAPI specs (which allow : in parameter names via x- extensions) or from RDF/linked data schemas.
Normalize property key names to the allowed pattern:
import re
def normalize_key(key: str) -> str:
# Replace disallowed chars with underscore
return re.sub(r'[^a-zA-Z0-9_.\-]', '_', key)[:64]
Error 7: outputSchema Defined But No structuredContent Returned
Error message:
Output validation error: outputSchema defined but no structured output returned
Why it happens:
If a tool definition includes outputSchema, the MCP SDK checks that the tool's response includes a structuredContent field matching the schema. This check runs even when isError: true — so error responses from tools with outputSchema always fail validation (tracked across GitHub issues #4202, #4042 in IBM/mcp-context-forge, #654 in modelcontextprotocol/typescript-sdk, #662 in dgunning/edgartools).
Two options:
Option A: ReturnstructuredContent in all responses including errors:
return {
content: [{ type: "text", text: errorMessage }],
structuredContent: { error: errorMessage, success: false },
isError: true
};
Option B: Remove outputSchema from tool definitions until the MCP spec resolves this (the MCP RC July 28 includes a fix for error response handling).
The Safe MCP Tool Schema Template
This template is compatible with the current Anthropic API:
{
"name": "tool_name",
"description": "Clear description of what this tool does",
"input_schema": {
"type": "object",
"properties": {
"param_one": {
"type": "string",
"description": "Description of param_one"
},
"param_two": {
"type": "integer",
"description": "Description of param_two"
}
},
"required": ["param_one"]
}
}
What to avoid:
- No
$schemaat any level - No
oneOf/allOf/anyOfat the top level - No
$refto external or missing$defs - No
strictfield - Property keys:
[a-zA-Z0-9_.-]only, max 64 chars - If using
outputSchema, always returnstructuredContentin every response
Preparing for MCP RC July 28, 2026
The MCP 2026-07-28 RC will restore full JSON Schema 2020-12 support in tool schemas, including oneOf, anyOf, allOf, $ref, and $defs.
This has a non-obvious side effect: if you wrote normalization code that strips or rewrites oneOf from schemas (to work around the current restriction), that code will silently mangle valid schemas after July 28.
Audit your schema normalization code before the RC:
# Flag any code that deletes oneOf/allOf/anyOf
grep -r "delete.oneOf\|oneOf.=.*\[\]" ./src
See also: MCP Python SDK v2 Beta: 5 JSON Breaking Changes for the full migration checklist.
Quick Validation Before Deploying
Before connecting to Claude Code, run:
# Validate your MCP server's tool schemas
npx @modelcontextprotocol/inspector@latest http://localhost:3000
Check each tool schema against Anthropic's constraints manually
node -e "
const schema = require('./your-schema.json');
const forbidden = ['$schema', '\$id'];
const badKeys = Object.keys(schema).filter(k => forbidden.includes(k));
if (badKeys.length) console.error('Remove:', badKeys);
else console.log('OK');
"
If your tool schemas fail the Anthropic API despite passing MCP Inspector, paste the raw schema into AI JSONMedic's validator to check for structural issues and get a repaired version.
FAQ
Q: DoesskipSchemaValidation: true in Claude Code fix API 400 errors?
No. skipSchemaValidation: true only bypasses Claude Code's local schema check before connecting. The Anthropic API still validates schemas on every tool call and returns 400 for invalid schemas. You must fix the schema itself.
OpenAI's schema validation is more permissive. OpenAI supports oneOf/anyOf, allows strict: true, and accepts $schema. Anthropic does not (currently). If you're targeting both, maintain separate schema definitions per provider.
oneOf and anyOf work after the MCP RC in July 2026?
Yes — the MCP 2026-07-28 RC includes full JSON Schema 2020-12 support in tool schemas. After the RC, oneOf, anyOf, allOf, $ref, and $defs will be valid. Existing normalization workarounds that strip these keywords should be removed before upgrading.
$ref work in MCP Inspector but fail with Claude?
MCP Inspector validates against full JSON Schema, which supports $ref to any valid URI. The Anthropic API only supports $ref to definitions within the same schema object (local $defs). Cross-schema and external $ref values are rejected.
tools.21?
The number in tools.21 is a zero-indexed position in the tools array sent to the API. Log your full tools array before the API call and check tools[21] for the problematic schema.
MCP Inspector's --fix flag can resolve some structural issues. For JSON schema repair more broadly — stripping invalid keys, normalizing property names, fixing $ref issues — try AI JSONMedic's repair tool, which handles structural JSON errors automatically.
Key Takeaways
- Anthropic's tool schema validation is a strict subset of JSON Schema — the full spec is not supported (until MCP RC July 28)
oneOf/allOf/anyOfmust not appear at the top level ofinput_schema$schemaand other$-prefixed meta-keys violate the property naming constraint- Claude Code v2.0.21+ drops MCP servers with invalid schemas silently — check logs
outputSchemarequiresstructuredContentin all responses, including errors- MCP RC July 28 restores full JSON Schema 2020-12 — remove normalization workarounds before upgrading
For MCP server schema validation errors that appear in other clients (Azure AI Foundry, VS Code), see the MCP JSON Schema Errors guide.
Still dealing with broken JSON?
Paste it in and get it fixed in under 1 second — free, no signup, no install. Works with ChatGPT, Claude, n8n, and any AI output.
Fix My JSON Free →Related Articles