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)

Status Open
Maintainer reply None cached
Activity 1 comment · opened Sep 8, 2026

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.)

  1. Configure that server under mcpServers (stdio transport) and run a query through

@anthropic-ai/claude-agent-sdk 0.1.77.

  1. 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).

  1. 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.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗