anthropics / anthropics/claude-ai-mcp
Custom MCP connector tools never injected into chat despite fully spec-compliant backend (verified via manual curl)
- Dominant language
- No language data
- Stars
- 471
- Forks
- 76
- PR merge metrics
- No merged PRs in 30d
Description
### What happened?
Custom MCP connector (Streamable HTTP) never progresses past `initialize` in
claude.ai — no `notifications/initialized` or `tools/list` ever reaches the
server, despite the server being fully spec-compliant.
Setup: self-hosted MCP servers behind supergateway (stdio→Streamable HTTP),
authless, exposed via HTTPS reverse proxy. Tested with THREE independent
backends (Python mysql-mcp-server, Go-based mcp-grafana, custom Python/FastMCP
script) — all three show identical behavior.
Symptom: Settings shows "This connector has no tools available." Chat
conversations can sometimes produce a correct-looking answer (likely from
memory/context, not a live tool call), but explicit tool widgets fail with
"Failed to fetch."
Verified via manual curl (bypassing Claude entirely):
1. POST .../mcp {initialize} → 200 OK, valid capabilities, Mcp-Session-Id
returned
2. POST .../mcp {notifications/initialized} with session header → 202 Accepted
3. POST .../mcp {tools/list} with session header → 200 OK, full valid tool
array returned (3 tools, correct inputSchema)
supergateway logs show `initialize` received and answered correctly across
multiple client identities (Anthropic, Anthropic/Toolbox, Anthropic/ClaudeAI),
but `notifications/initialized`/`tools/list` never arrive from Claude's side
in any of them.
Already ruled out: --stateful vs stateless supergateway modes, CORS
enabled/disabled, root path vs sub-path routing, shared domain vs dedicated
subdomain — no change in behavior with any combination.
Possibly related to anthropics/claude-ai-mcp#552 and #572 (same symptom:
server confirmed healthy, tools never injected into chat).
### What did you expect to happen?
After adding a custom Streamable HTTP connector and having it show as "Connected,"
I expected Claude to call notifications/initialized followed by tools/list, and
for the server's tools to appear both in Settings and be usable in chat — the
same behavior documented for any spec-compliant remote MCP server.
Instead, the connector Settings page permanently shows "This connector has no
tools available," and no chat can successfully invoke a tool through the normal
MCP flow.
### Steps to reproduce
1. Deploy any Streamable HTTP MCP server (tested with 3 independent backends:
Python mysql-mcp-server, Go-based mcp-grafana, custom Python/FastMCP script)
behind supergateway (stdio→Streamable HTTP), exposed via HTTPS reverse proxy,
authless.
2. Add it in claude.ai as a custom connector (URL only, no OAuth).
3. Connector shows "Connected," but Settings reports "This connector has no
tools available." Server logs show `initialize` received and answered
correctly (multiple client identities: Anthropic, Anthropic/Toolbox,
Anthropic/ClaudeAI) — but notifications/initialized and tools/list are
never sent by the client.
4. Manually replicated the protocol via curl, bypassing Claude entirely:
- POST /mcp {initialize} → 200 OK, valid capabilities, Mcp-Session-Id returned
- POST /mcp {notifications/initialized} + session header → 202 Accepted
- POST /mcp {tools/list} + session header → 200 OK, full valid tool array
This confirms the server is 100% spec-compliant; the client never attempts
the same sequence.
5. Ruled out: --stateful vs stateless supergateway modes, CORS on/off, root
path vs sub-path routing, shared domain vs dedicated subdomain — no change
in behavior with any combination.
### Area
MCP Connector (adding/managing servers)
### MCP Server (if applicable)
Self-hosted, not publicly shared (server confirmed authless — see protocol trace in reproduction steps for full evidence instead of a live URL).
### Error messages or logs
```shell
Server-side log (supergateway), showing the pattern across all 3 client identities:
[supergateway] StreamableHttp → Child: {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"Anthropic","version":"1.0.0"}}}
[supergateway] Child → StreamableHttp: {"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2025-11-25", ...valid capabilities...}}
[supergateway] Response finished
[supergateway] StreamableHttp → Child: {"jsonrpc":"2.0","id":1,"method":"initialize","params":{...,"clientInfo":{"name":"Anthropic/Toolbox","version":"1.0.0"}}}
[supergateway] Child → StreamableHttp: {"jsonrpc":"2.0","id":1,"result":{...valid capabilities...}}
[supergateway] StreamableHttp → Child: {"jsonrpc":"2.0","id":1,"method":"initialize","params":{...,"clientInfo":{"name":"Anthropic/ClaudeAI","version":"1.0.0"}}}
[supergateway] Child → StreamableHttp: {"jsonrpc":"2.0","id":1,"result":{...valid capabilities...}}
— log ends here every time. notifications/initialized and tools/list are
never sent, from any of the three client identities, across many repeated
connection attempts over several days.
---
Manual protocol replay via curl (same server, same endpoint), for comparison:
POST /mcp {initialize}
→ HTTP/1.1 200 OK
Content-Type: text/event-stream
Mcp-Session-Id:
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2025-06-18", ...valid capabilities...}}
POST /mcp {notifications/initialized} [header: Mcp-Session-Id: ]
→ HTTP/1.1 202 Accepted
POST /mcp {tools/list} [header: Mcp-Session-Id: ]
→ HTTP/1.1 200 OK
{"jsonrpc":"2.0","id":2,"result":{"tools":[{"name":"execute_sql",...},
{"name":"get_schema_info",...},{"name":"get_table_sample",...}]}}
This confirms the exact same three-step sequence, against the exact same
endpoint, completes successfully when performed manually — the gap is
specifically in what the Claude client sends (or doesn't send) after
initialize.
```
### Additional context
_No response_
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.