[BUG] JSON schema is invalid. It must match JSON Schema draft 2020-12

Status Closed — not planned
Maintainer reply None cached
Activity 14 comments · opened Mar 21, 2025 · closed Jan 5, 2026

Environment

  • Platform (select one):
  • [x] Anthropic API
  • [ ] AWS Bedrock
  • [ ] Google Vertex AI
  • [ ] Other: <!-- specify -->
  • Claude CLI version: 0.2.52
  • Operating System: NixOS 25.05.20250201.3a22805 (Warbler)
  • Terminal: ZSH

Bug Description

Claude Code chokes on a simple MCP server with tuples (also happens with some other Zod syntaxes).

Steps to Reproduce

  1. Have this tool in your MCP server:
    server.tool(
      "someTool",
      "some description",
      {
         document: z
          .object({
            section: z.string(),
          }) ,
      },
      async () => {
          return {
            content: [{ type: "text", text: "response" }],
        }
      }
    );
  1. Give any prompt to Claude, it works 🎉
  2. Replace the MCP server tool with (the only difference is that z.string() becomes z.tuple([z.string(), z.string()])):
    server.tool(
      "someTool",
      "some description",
      {
         document: z
          .object({
            section: z.tuple([z.string(), z.string()]),
          }) ,
      },
      async () => {
          return {
            content: [{ type: "text", text: "response" }],
        }
      }
    );
  1. Give any prompt to Claude, it breaks with API Error: 400 {"type":"error","error":{"type":"invalid_request_error","message":"tools.12.custom.input_schema: JSON schema is invalid. It must match JSON Schema draft 2020-12 (https://json-schema.org/draft/2020-12). Learn more about tool use at https://docs.anthropic.com/en/docs/tool-use."}}

Note: run claude and type the prompt inside. If you run claude test then it will succeed, I assume because the MCP server is not started yet?

Expected Behavior

I have given a Zod schema, not a JSON schema, so it should work.
OR, I would be happy to pass a JSON schema directly instead of a Zod schema (we originally have a JSON schema and convert it to Zod using https://www.npmjs.com/package/json-schema-to-zod, so if then Claude Code converts this Zod schema back to JSON Schema, I would love todirectly pass a JSON schema instead...).

Actual Behavior

It breaks on any prompt, even "test".

Additional Context

Using Zod tuples is not the only Zod syntax that breaks, but it's one of the simplest examples I have pinpointed.

View original on GitHub ↗

14 Comments

jeffrey-l-turner · 1 year ago

I see the same thing b/c of a bad mcp server -- specifically I tried using https://github.com/sylphxltd/pdf-reader-mcp. You may want to check your ~/.claude.json or .mcp.json configurations

sir4ur0n · 1 year ago

See the "Steps to Reproduce" section of my original message: the MCP server originally works fine.
It only breaks after changing the Zod schema.
So I don't see how it can be related to a bad MCP server configuration in the Claude settings.

Lucheti · 1 year ago

Thank god i found this, i was getting mad crazy with it. That's 100% the cause of that error. @sir4ur0n mvp!

andig · 1 year ago

@Hendler I'm seeing this in https://github.com/anthropics/claude-code/issues/2758, too. But there an "empty" input_schema is present.

rossshannon · 1 year ago

This can also break Claude Code if you use the $ claude mcp add-from-claude-desktop command to port your Claude Desktop MCP servers into Claude Code. Despite a valid working configuration there, and Claude Code marking each imported server as ✔️ connected, some incompatibility has crept in in ~/.claude.json which means Claude Code now won't accept prompts.

<img width="1128" alt="Image" src="https://github.com/user-attachments/assets/12627251-1149-40f4-a495-c680b2480af2" />

API Error: 400 {"type":"error","error":{"type":"invalid_request_error","message":"t
    ools.124.custom.input_schema: JSON schema is invalid. It must match JSON Schema 
    draft 2020-12 (https://json-schema.org/draft/2020-12). Learn more about tool use at
     https://docs.anthropic.com/en/docs/tool-use."}}

<img width="1125" alt="Image" src="https://github.com/user-attachments/assets/05e38f1a-eabc-4d4c-9e68-8ae5b4f8a8e1" />

boundless-oss · 1 year ago

I ran into this issue and fixed it by using a json validator to find that the inputSchema for a tool in my MCP Server was in fact invalid. The problem was that a regex pattern was not properly escaping a backslash:

\s == BAD
\\s == GOOD

Suggest integrating this library into your tests: https://github.com/ajv-validator/ajv

vlasky · 1 year ago
I see the same thing b/c of a bad mcp server -- specifically I tried using https://github.com/sylphxltd/pdf-reader-mcp. You may want to check your ~/.claude.json or .mcp.json configurations

@jeffrey-l-turner I created my own pdf-reader-mcp fork https://github.com/vlasky/pdf-reader-mcp that resolves this JSON schema issue. Hopefully the fix will eventually be merged into the original.

Sunsvea · 1 year ago

Happens for me too. Findings are similar to those before me. I intercepted the Claude request and dug into the JSON request that was supposedly invalid.

What I found was that a single tool for one of my MCP servers (Mapbox) was using an unsupported/incorrect schema version, and therefore Claude was including it in every request (because that's how MCP's work) and so every request was failing.

  • The input_schema for the mcp__MapboxServer__DirectionsTool explicitly declares

"$schema": "http://json-schema.org/draft-07/schema#". However, the Anthropic API requires schemas to
conform to JSON Schema Draft 2020-12.

It would be helpful if Claude performed schema validation for the payload, either automatically during Claude's initialization or manually via /doctor. Ideally, the CLI should surface invalid input_schema formats upfront rather than allowing malformed tools to silently break all requests.

For those with dozens of MCP's where disabling them 1-by-1 may be time consuming:

Here's a script to resolve which MCP tools are contributing to the malformed request. Hope it helps someone: https://github.com/Sunsvea/diagnose-claude-mcp-400/tree/main

Example output:

{
 "timestamp": "2025-07-08T12:52:27.699956",
 "tool_name": "mcp__Mapbox__DirectionsTool",     <--- Responsible tool
 "tool_index": 74,
 "schema_url": "http://json-schema.org/draft-07/schema#",
 "message": "Problematic Tool Found"
}
jussi-sa · 1 year ago
Happens for me too. Findings are similar to those before me. I intercepted the Claude request and dug into the JSON request that was supposedly invalid. What I found was that a single tool for one of my MCP servers (Mapbox) was using an unsupported/incorrect schema version, and therefore Claude was including it in every request (because that's how MCP's work) and so every request was failing. * The input_schema for the mcp__MapboxServer__DirectionsTool explicitly declares "$schema": "http://json-schema.org/draft-07/schema#". However, the Anthropic API requires schemas to conform to JSON Schema Draft 2020-12. It would be helpful if Claude performed schema validation for the payload, either automatically during Claude's initialization or manually via /doctor. Ideally, the CLI should surface invalid input_schema formats upfront rather than allowing malformed tools to silently break all requests. ### For those with dozens of MCP's where disabling them 1-by-1 may be time consuming: Here's a script to resolve which MCP tools are contributing to the malformed request. Hope it helps someone: https://github.com/Sunsvea/diagnose-claude-mcp-400/tree/main Example output: { "timestamp": "2025-07-08T12:52:27.699956", "tool_name": "mcp__Mapbox__DirectionsTool", <--- Responsible tool "tool_index": 74, "schema_url": "http://json-schema.org/draft-07/schema#", "message": "Problematic Tool Found" }

We've fixed this on our end (Mapbox MCP - DirectionsTool).

The JSON Schema Draft 2020-12 does not support Zod tuples at the moment. So by using a z.array of length 2 instead of tuples in the schemas, Anthropic API accepts the requests.

github-actions[bot] · 8 months ago

This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.

github-actions[bot] · 7 months ago

This issue has been automatically closed due to 60 days of inactivity. If you're still experiencing this issue, please open a new issue with updated information.

github-actions[bot] · 7 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.