MCP: tools/list fails ("tools fetch failed") for servers with recursive $ref in outputSchema
Bug: MCP tools/list fails ("tools fetch failed") for servers exposing a recursive outputSchema $ref cycle
Claude Code version: 2.1.207 (latest as of 2026-07-10)
Platform: Windows 11 Pro (win32)
Summary
Adding an HTTP MCP server whose tools/list response includes a tool outputSchema with a self-referential $defs entry (a $ref cycle, e.g. a recursive tree-node type) causes claude mcp list to report:
<server>: <url> (HTTP) - ! Connected · tools fetch failed
The server connects and authenticates successfully (initialize succeeds), but tool discovery silently fails with no further detail in claude mcp list output.
Repro
- Add an HTTP MCP server:
````
claude mcp add stitch https://stitch.googleapis.com/mcp --transport http -H "X-Goog-Api-Key: <key>"
- Run
claude mcp list. - Observe:
stitch: ... (HTTP) - ! Connected · tools fetch failed
Meanwhile, calling the same server's tools/list directly via curl returns a valid, complete JSON-RPC response (verified manually — 15 tools, ~316KB payload, no errors).
Root cause (found by manual inspection)
Three of the returned tools (create_project, get_project, list_projects) declare an outputSchema containing a $defs.ScreenInstance definition with a field that self-references the same definition:
{
"$defs": {
"ScreenInstance": {
"type": "object",
"properties": {
"variantScreenInstance": {
"$ref": "#/$defs/ScreenInstance",
"description": "Optional. The variant Screen Instance."
}
// ...other fields
}
}
}
}
This is valid JSON Schema (self-referential/recursive schemas are legal and commonly used for tree-like structures), but appears to break Claude Code's schema handling — most likely a $ref resolver that fully inlines/expands references without cycle detection, causing unbounded recursion that gets caught and surfaced only as a generic "tools fetch failed" with no diagnostic detail.
Expected behavior
- Claude Code's MCP client should support recursive/self-referential JSON Schema
$refs (per spec, these are valid), OR - If unsupported, it should fail gracefully with a specific, actionable error (e.g. naming the offending tool/schema) rather than a generic "tools fetch failed", and ideally should still allow use of the other tools that don't hit the cycle rather than failing the entire
tools/listcall.
Additional notes
- This was reproduced against Google's Stitch MCP server (
https://stitch.googleapis.com/mcp), which generates its schemas from protobuf message definitions — recursive message types (like a screen instance with a self-typed "variant" field) are a normal pattern there, so other real-world MCP servers built from protobuf/OpenAPI schemas are likely to hit the same issue. - Happy to share the full captured
tools/listresponse if useful for a regression test.