anthropics / anthropics/claude-code
[BUG] MCP Tools with draft-07 are rejected
- Vorherrschende Sprache
- Python
- Sterne
- 145k
- Forks
- 23.1k
- PR-Merge-Kennzahlen
- PR-Kennzahlen ausstehend
Beschreibung
### Preflight Checklist
- [x] I have searched [existing issues](https://github.com/anthropics/claude-code/issues?q=is%3Aissue%20state%3Aopen%20label%3Abug) 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
```bash
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`:
```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.
2. `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
```shell
```
### 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"]
}
}
}
2. Start a session. The server connects and all 14 of its tools register
successfully — no error at this stage.
3. Call any one of its tools, e.g. `list_allowed_directories` (it takes no
arguments), or `read_text_file`.
4. 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_
Beitragsleitfaden
Für dieses Repository ist kein Beitragsleitfaden indexiert
Rechercherichtung
Start by tracing MCP tool invocation after tools/list, focusing on the outputSchema validation path and the draft-07 rejection described in the report. Reproduce with @modelcontextprotocol/server-filesystem@2026.7.10 and verify that a tool such as list_allowed_directories succeeds; unsupported dialects should fail gracefully rather than make registered tools unusable.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- python, typescript
- Bereich
- api, cli
- Issue-Typ
- Bug
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Aktivitätsstatus
- Aktiv
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 55/100