anthropics / anthropics/claude-code
MCP (stdio): one boolean property schema silently drops ALL tools of the server (SDK 0.1.77; stdio twin of #88049, re-filing of #82949)
- 主要言語
- Python
- スター
- 145k
- フォーク
- 23.1k
- PR マージ指標
- PR 指標を取得中
説明
## Summary
If **any single tool** advertised by a stdio MCP server has an `inputSchema` containing a
**boolean property schema** — e.g. `"payload": true` inside a `properties` map, which is legal
JSON Schema meaning "any value" (JSON Schema 2020-12 §4.3.2) — the SDK's bundled CLI rejects that
schema during MCP tool conversion and silently drops the **entire server's tool list**. Not just
the offending tool: every tool from that server vanishes from the outgoing API request. There are
**zero diagnostics anywhere** — no stderr warning, no error message — and the server still reports
as "connected". The model simply never sees any of the server's tools.
This is the same root cause and blast radius as #82949 (a boolean schema at a named property
throwing inside `jsonSchemaToZodShape`) and #88049 (a non-object top-level schema, HTTP
transport), reproduced independently against a **stdio** MCP server. #82949 was closed
`NOT_PLANNED` by an inactivity bot on 2026-09-08 with no fix landed, so this re-files it with a
concrete stdio-side repro, a bisect, and a suggested fix — per that issue's own closing-bot
guidance ("open a new issue if still relevant").
## Affected version
- `@anthropic-ai/claude-agent-sdk` **0.1.77** (declared `^0.1.0`, lockfile-resolved `0.1.77`) and
its bundled `cli.js`
- Node.js 22.x, via `tsx`
- Linux x86_64
No newer SDK version was tested against this repro.
## Minimal repro
1. Stand up a stdio MCP server whose `tools/list` returns several tools, exactly one of which
carries a boolean property schema in its `inputSchema`, e.g.:
```json
{
"name": "propose",
"inputSchema": {
"type": "object",
"properties": {
"target": { "type": "string" },
"op": { "type": "string", "enum": ["set", "delete"] },
"payload": true
}
}
}
```
(`"payload": true` is the trigger — a boolean schema in a `properties` map. `true` = "accept
any value" per JSON Schema 2020-12 §4.3.2. `false` presumably triggers the same rejection
path; the proven case is `true`.)
2. Configure that server under `mcpServers` (stdio transport) and run a query through
`@anthropic-ai/claude-agent-sdk` 0.1.77.
3. Capture the outgoing API request (we pointed `ANTHROPIC_BASE_URL` at a credential-free
Anthropic-format capture stub and counted the `tools` array in the recorded request body).
**Observed:** 0 of the server's tools reach the API request. Server status: "connected". No
warning or error is emitted anywhere.
**Expected:** either (a) the boolean schema is accepted (it is valid JSON Schema — a boolean is a
legal schema everywhere a schema may appear), or (b) at minimum, only the offending **tool** is
dropped, **with a diagnostic** naming the tool and the reason. Silently discarding all N tools of
a connected server with no signal anywhere is the worst of every option.
## Bisect evidence
Our MCP bridge advertises 53 tools whose schemas are enriched from an OpenAPI document. Two
operations declared `"payload": true` (an honest any-value payload). Per-path bisect via the
capture stub:
- With any single path **not** containing `"payload": true` in the doc → **53/53** tools reach
the API request.
- With only a path containing `"payload": true` → **0/53** tools reach the API request.
- Replacing both occurrences with the semantically-equivalent **object-form** any-value schema
`{"description": "Any JSON value ..."}` (no `type`) → **53/53** again.
This isolates the trigger to the one boolean schema node, independent of tool count or catalog
size, and matches #88049's own bisect showing the same all-or-nothing behavior for a different
non-object-at-schema-root trigger.
## Impact
- **Server-wide blast radius from one property:** a single legal schema construct anywhere in one
tool disables an entire MCP server.
- **Silent:** the failure mode presents as "the model chose not to use my tools." We burned a
credentialed eval run (a capability floor collapsed from 11/11 to 1/6) and a bisect session
root-causing what looked like a model-behavior regression but was actually a tool-palette drop.
- Boolean schemas are common in generated schemas (OpenAPI → JSON Schema pipelines,
`additionalProperties: false`-style toolchains, some `zod`-based converters' `z.any()`
emission), so this is easy to hit and near-impossible to self-diagnose — exactly the pattern
#82949 and #88049 both independently report.
## Workaround
1. Replace every boolean property schema with the object-form equivalent: `true` →
`{ "description": "Any JSON value" }` (a bare schema object with no `type` keeps the identical
"any value" contract and passes the CLI's conversion).
2. A lint check that walks every schema node in our tool-schema source and fails if any value in
any `properties` map is not a JSON object, so the construct can never be reintroduced.
## Suggested fix
Accept boolean schemas per JSON Schema (ideal: `true` → `{}`, `false` → `{"not": {}}` during
conversion), matching #82949's own suggested fix (`typeof node === 'boolean'` handled before any
`'properties' in node` check in `jsonSchemaToZodShape`). Failing that: drop only the offending
tool and emit a diagnostic naming the server, the tool, and the schema path — never silently drop
the whole server's tool list. #82949's suggested per-tool `try/catch` isolation in
`createSdkServer` would close this stdio case, #88049's HTTP case, and #82949's Desktop case at
once, since all three share the same "one bad schema drops the whole server" mechanism.
## Related
- #82949 — same root cause (boolean schema at a named property, `jsonSchemaToZodShape` throwing),
Claude Desktop + binary extension transport. **Closed `NOT_PLANNED` by an inactivity bot on
2026-09-08** with no fix landed; this issue re-files it with an independent stdio-side repro
and bisect, per that closing comment's own "open a new issue if still relevant" guidance.
- #88049 — open, same blast radius and same "completely silent on both sides" symptom, different
trigger (non-object top-level schema, e.g. bare `anyOf`) and different transport (HTTP).
- #50194 — the original report of this blast radius (Claude Desktop, Grafana MCP server),
closed; #82949 established its stated root cause (`additionalProperties: true`) was wrong.
コントリビューションガイド
このリポジトリのコントリビューションガイドは索引されていません
調査の方向性
Read the bundled cli.js around jsonSchemaToZodShape and createSdkServer, then run the stdio repro with the credential-free capture stub. Verify that a boolean property schema no longer removes the entire server tool list, and that invalid tools are isolated or diagnostics are emitted.
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- node.js
- 領域
- api, cli
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 活発
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 52/100