[BUG] MCP Tools with draft-07 are rejected
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 andoutputSchema 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)
- The SDK should not emit
$schemaat 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.
registerToolshould exposetarget, since its absence is what makes this
unfixable downstream.
Environment
@anthropic-ai/claude-code2.1.240 (darwin arm64)@modelcontextprotocol/sdk1.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
- 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"]
}
}
}
- Start a session. The server connects and all 14 of its tools register
successfully — no error at this stage.
- Call any one of its tools, e.g.
list_allowed_directories(it takes no
arguments), or read_text_file.
- 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 anoutputSchema 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_
Showing cached comments. Read the full discussion on GitHub ↗
3 Comments
Confirming this on Claude Code (not Desktop), and adding what I think is the missing
piece in the reports so far: an exact client version boundary from a bisect over local
session transcripts.
Version boundary
Counted
mcp__filesystem__*tool calls against occurrences ofunsupported dialectacross 45 local session transcripts, grouped by the
versionfield recorded in eachtranscript:
| Date | Claude Code | filesystem calls | dialect errors |
|------------|-------------|------------------|----------------|
| 2026-07-26 | 2.1.219 | 91 | 0 |
| 2026-08-01 | 2.1.219 | 157 | 0 |
| 2026-08-02 | 2.1.219 | 297 | 0 |
| 2026-08-08 | 2.1.219 | 180 | 0 |
| 2026-08-10 | 2.1.219 | 23 | 0 |
| 2026-08-14 | 2.1.229 | 9 | 2 ← first |
| 2026-08-22 | 2.1.237 | 6 | 3 |
| 2026-08-25 | 2.1.237 | 12 | 10 |
748 successful calls on 2.1.219 with zero errors. Failures begin at 2.1.229 and never stop.
So the regression landed somewhere in 2.1.220 … 2.1.229.
The server did not change
Same
@modelcontextprotocol/server-filesystem@2026.1.14throughout, installed2026-04-12 and untouched since — its install timestamp straddles both the working and
the broken period. Same package, same
outputSchema, same draft-07 stamp. The onlyvariable that moved is the client version.
Upgrading the server does not help
Worth flagging for anyone arriving here looking for a workaround: the newest published
server-filesystem(2026.7.10) is affected too — see the report earlier in #86142 ofAnthropic's own bundled filesystem extension at v2026.7.10 failing identically. There is
no version of this server that passes, because the schema shape is the same across all
of them.
Root cause chain (client-side, reproducible)
server-filesystemdeclaresoutputSchemaon its tools — 14 occurrences indist/index.js(e.g. lines 158, 175, 185, 235, 264, 288), all the shapeoutputSchema: { content: z.string() }.zod-to-json-schema, which unconditionally setscombined.$schema = "http://json-schema.org/draft-07/schema#"atdist/cjs/zodToJsonSchema.js:76.outputSchemawith an Ajv instance restricted toJSON Schema 2020-12. Ajv throws at validator-construction time on an unknown dialect.
process is never contacted and retrying cannot help.
Useful negative control
A co-installed SQL Server MCP on the same machine also emits
"$schema": "http://json-schema.org/draft-07/schema#"— but only in its inputSchema,and it declares no
outputSchema. It works perfectly, in the same sessions, at the sameclient versions where every filesystem tool fails.
That isolates the trigger precisely: it is
outputSchemavalidation, not draft-07in general. Input schemas in draft-07 are accepted without complaint.
Scope
Every tool on the server, including zero-argument ones —
list_allowed_directories(no parameters at all) fails identically to
read_text_file. There is no usable subset,so no partial workaround.
Environment
@modelcontextprotocol/server-filesystem@2026.1.14@modelcontextprotocol/sdk@^1.25.2,zod-to-json-schema@^3.23.5Expected
Either configure Ajv to accept draft-07 for
outputSchema, or degrade gracefully — log awarning and skip output validation rather than hard-failing the tool before dispatch.
Hard-failing turns a validation nicety into total loss of the server.
Confirming issue on Claude Cowork.
Confirming it started between 2026-08-12 and 2026-08-14.
Can confirm — hitting the exact same error, reproduced with 7 independently configured
instances of @modelcontextprotocol/server-filesystem (each pointing at a different
allowed directory, via
npx -y @modelcontextprotocol/server-filesystem <dir>inclaude_desktop_config.json). All 7 fail identically on every tool invocation
(read_file, write_file, edit_file, list_directory, search_files,
list_allowed_directories, etc.), not just list_allowed_directories.
Also observed through the Claude Desktop app's conversational interface (not just a
CLI session), so this affects that code path too.
Environment: macOS, Claude Desktop app.