[BUG] MCP Tools with draft-07 are rejected

Status Open
Reported on v2.1.240
Maintainer reply None cached
Activity 2 comments · opened Aug 22, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

MCP tools with a draft-07 outputSchema are rejected; current server-filesystem is unusable

Summary

Claude Code validates MCP tool outputSchema with an Ajv instance that supports
JSON Schema 2020-12 only. The MCP TypeScript SDK emits draft-07 by default, so any
server declaring an outputSchema fails at tool-call time:

Error: Tool 'list_allowed_directories' has an invalid outputSchema:
JSON Schema declares an unsupported dialect ("$schema": "http://json-schema.org/draft-07/schema#").
The default validator supports JSON Schema 2020-12 only; pass a pre-configured Ajv instance to AjvJs…

Note the failure mode: tools/list succeeds and the tools appear registered. The error
only surfaces when a tool is actually invoked.

Impact

This is not specific to one server. @modelcontextprotocol/sdk defaults its conversion
target to draft-7, so a large share of MCP servers in the wild emit draft-07 schemas.
Any of them that declare an outputSchema is unusable in Claude Code.

Concretely, every release of @modelcontextprotocol/server-filesystem since
2025.11.25 is broken with Claude Code
, including the current 2026.7.10.

Reproduction

npx -y @modelcontextprotocol/server-filesystem@2026.7.10 /tmp

Register it as an MCP server, then call any of its tools (e.g. list_allowed_directories).
All 14 tools carry a draft-07 outputSchema.

Probe across versions (14 tools each):

| version | bad inputSchema | tools w/ outputSchema | draft-07 output |
|------------|-------------------|--------------------------|-----------------|
| 2025.7.29 | 13 | 0 | 0 |
| 2025.8.21 | 13 | 0 | 0 |
| 2025.11.25 | 0 | 14 | 14 |
| 2026.1.14 | 0 | 14 | 14 |
| 2026.7.10 | 0 | 14 | 14 |

(The inputSchema breakage in older versions is a separate upstream issue — those
releases convert via zod-to-json-schema@3, which yields empty schemas under zod 4.
The net effect is that no version of this server works with Claude Code out of the box.)

Root cause

@modelcontextprotocol/sdk@1.30.0, dist/esm/server/zod-json-schema-compat.js:

function mapMiniTarget(t) {
    if (!t) return 'draft-7';          // <-- default
    ...
    return 'draft-7';                  // <-- fallback
}

dist/esm/server/mcp.js calls toJsonSchemaCompat for both inputSchema and
outputSchema and never passes target, so every schema is draft-07. There is no
public API on registerTool to override the dialect, so server authors cannot fix this
downstream.

Suggested fix (client)

Accept draft-07 rather than 2020-12 only — e.g. select the validator based on the
declared $schema, or register the draft-07 meta-schema on the Ajv instance. The error
text implies the code path already supports an injected pre-configured Ajv.

This is the highest-leverage fix: it repairs every affected server at once, including
unmaintained ones, with no ecosystem coordination.

Related SDK issues (filed separately)

  1. The SDK should not emit $schema at all. Note that switching the target to

draft-2020-12 is insufficient — the zod v3 branch uses zod-to-json-schema@3,
which supports only jsonSchema7 and jsonSchema2019-09 and has no 2020-12 target.
Omitting $schema is the only fix that works across both the zod v3 and v4 branches.
Verified the emitted bodies are byte-identical apart from that key for typical
object-of-scalars tool schemas.

  1. registerTool should expose target, since its absence is what makes this

unfixable downstream.

Environment

  • @anthropic-ai/claude-code 2.1.240 (darwin arm64)
  • @modelcontextprotocol/sdk 1.30.0
  • macOS 26.5.2, node v25.9.0

What Should Happen?

Calling an MCP tool whose outputSchema declares JSON Schema draft-07 should
succeed. Claude Code should validate against the dialect the schema declares —
selecting the validator from $schema, or registering the draft-07 meta-schema
on the Ajv instance — rather than assuming 2020-12.

Concretely: npx -y @modelcontextprotocol/server-filesystem@2026.7.10 /tmp
should work out of the box. Today all 14 of its tools register successfully and
then fail on invocation.

Secondarily, an unsupported dialect should degrade gracefully rather than hard-fail
the call. tools/list already succeeded and the tools appear registered, so the
current behavior surfaces as a broken tool at call time with no indication the
cause is schema validation. Skipping output validation with a warning would be
strictly better than making the tool unusable.

Error Messages/Logs

Steps to Reproduce

  1. Register the current filesystem server as an MCP server. Either run:

claude mcp add repro -- npx -y @modelcontextprotocol/server-filesystem@2026.7.10 /tmp

...or add this to the MCP config and restart the client:

{
"mcpServers": {
"repro": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem@2026.7.10", "/tmp"]
}
}
}

  1. Start a session. The server connects and all 14 of its tools register

successfully — no error at this stage.

  1. Call any one of its tools, e.g. list_allowed_directories (it takes no

arguments), or read_text_file.

  1. Observe the call fail:

Error: Tool 'list_allowed_directories' has an invalid outputSchema:
JSON Schema declares an unsupported dialect
("$schema": "http://json-schema.org/draft-07/schema#").
The default validator supports JSON Schema 2020-12 only;
pass a pre-configured Ajv instance to AjvJs…

Every tool on the server fails the same way, so the server is entirely unusable.

---

Confirming the server side independently (no Claude Code involved)

This speaks MCP over stdio directly and prints the declared dialect:

cd /tmp && printf '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"p","version":"1"}}}\n{"jsonrpc":"2.0","method":"notifications/initialized"}\n{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}\n' | npx -y @modelcontextprotocol/server-filesystem@2026.7.10 /tmp 2>/dev/null | grep '"id":2' | python3 -c 'import sys,json; t=json.load(sys.stdin)["result"]["tools"]; print(len(t),"tools;",sum(1 for x in t if x.get("outputSchema")),"with outputSchema"); print("dialect:",t[0]["outputSchema"]["$schema"])'

Output:

14 tools; 14 with outputSchema
dialect: http://json-schema.org/draft-07/schema#

This confirms the server emits valid MCP — the schemas are simply draft-07, which
the SDK produces by default. Swapping in any other server that declares an
outputSchema reproduces the same client-side failure.

Claude Model

None

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

2.1.240 (Claude Code)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗