HTTP MCP server registers as Connected with zero tools when it issues no Mcp-Session-Id
What happens
A remote MCP server registered with --transport http reports ✔ Connected in claude mcp list / claude mcp get, but none of its tools are registered into the session. ToolSearch for mcp__<server>__* returns "No matching deferred tools found". No error is surfaced anywhere — not in the CLI, not in the session, not in the connection status.
This has persisted across four sessions, including fresh starts. A restart does not change it.
The server is not at fault
Verified by speaking JSON-RPC to the endpoint directly:
initialize→200, returnsprotocolVersion: 2025-06-18,serverInfo,capabilities: {tools:{}}notifications/initialized→202tools/list→ 61 tools, and the payload is well-formed: 0 missinginputSchema, 0 missingdescription, 0 names failing^[a-zA-Z0-9_-]{1,64}$, every schematype: "object", ~77 KB, nonextCursortools/listalso succeeds on a bare POST with no prior handshake
Suspected cause
The server is stateless and issues no Mcp-Session-Id response header, while its CORS layer advertises one:
Access-Control-Expose-Headers: Mcp-Session-Id
Access-Control-Allow-Headers: Authorization, Content-Type, Mcp-Session-Id, Mcp-Protocol-Version, Accept, Last-Event-ID
A stateless streamable-HTTP server is spec-legal — Mcp-Session-Id is optional, and a server that omits it should be driven without one. The observed behaviour is consistent with the client treating the advertised-but-absent session id as required: initialize succeeds (hence "Connected"), and tool registration then silently yields nothing.
I have not read Claude Code's MCP internals, so the client half is inference from the server's behaviour rather than a confirmed root cause.
Why it is worth fixing even though there is a workaround
The failure is silent and misreported. "✔ Connected" is the only signal a user gets, and it is affirmative while the integration is entirely non-functional. Three separate working sessions were spent re-diagnosing this, each one starting from a status line that said the server was fine. A connected-with-zero-tools state should surface as a warning at minimum.
Workaround (confirmed working)
Register the same endpoint through a stdio bridge instead:
claude mcp add <name> -s user -- npx -y mcp-remote "<endpoint-url>"
Driving that bridge over stdio relays initialize and returns the full 61-tool tools/list.
Repro
Any stateless streamable-HTTP MCP server that returns a valid initialize and tools/list without ever setting Mcp-Session-Id.
claude mcp add <name> --transport http "<endpoint-url>"claude mcp get <name>→✔ ConnectedToolSearchformcp__<name>__*→ no matches, no error
Environment
- Claude Code in the VS Code extension, Windows 11 (10.0.26200)
- Server: streamable-HTTP,
protocolVersion 2025-06-18, stateless, auth by API key (query param; a Bearer header also works)
Suggested fix
Do not require Mcp-Session-Id for servers that never issue one, and treat "initialized but zero tools registered" as a reportable condition rather than a healthy Connected.