claude-code icon indicating copy to clipboard operation
claude-code copied to clipboard

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

Open sir4ur0n opened this issue 9 months ago • 6 comments

Environment

  • Platform (select one):
    • [x] Anthropic API
    • [ ] AWS Bedrock
    • [ ] Google Vertex AI
    • [ ] Other:
  • 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.

sir4ur0n avatar Mar 21 '25 12:03 sir4ur0n

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 avatar May 06 '25 23:05 jeffrey-l-turner

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.

sir4ur0n avatar May 07 '25 11:05 sir4ur0n

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

Lucheti avatar May 10 '25 21:05 Lucheti

see https://github.com/orgs/modelcontextprotocol/discussions/366

Hendler avatar May 17 '25 15:05 Hendler

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

andig avatar Jun 30 '25 18:06 andig

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.

Image
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."}}
Image

rossshannon avatar Jun 30 '25 21:06 rossshannon

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

boundless-oss avatar Jul 04 '25 21:07 boundless-oss

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.

vlasky avatar Jul 04 '25 23:07 vlasky

@vlasky for reference: you mean https://github.com/vlasky/pdf-reader-mcp/commit/9dfd52421cbd21b5604ae7c45e6aec3959d595ad#diff-a2a171449d862fe29692ce031981047d7ab755ae7f84c707aef80701b3ea0c80?

andig avatar Jul 05 '25 05:07 andig

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"
}

Sunsvea avatar Jul 08 '25 10:07 Sunsvea

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.

jussi-sa avatar Jul 09 '25 16:07 jussi-sa

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] avatar Dec 05 '25 10:12 github-actions[bot]