Streamable-HTTP MCP connector: 405 on SSE GET surfaces fatal "Client server capabilities not available" toast
What happened
Claude Desktop repeatedly shows a toast "Client server capabilities not available" when a remote Streamable-HTTP MCP connector is enabled (in my case an Atlassian remote connector, but the failure is in the client transport layer, not the server).
Enabling DevTools (developer_settings.json → {"allowDevTools": true}) and watching the renderer console shows the toast corresponds 1:1 with this repeating error:
GET https://claude.ai/v1/toolbox/shttp/mcp/<connector-id> 405 (Method Not Allowed)
at s
at _startOrAuthSse
at send
at notification
at connect
at refreshClient
at useClient
at listTools
So the MCP client, while (re)connecting the connector, calls _startOrAuthSse to open the optional GET / SSE notification stream against the streamable-HTTP endpoint. The claude.ai proxy route for that connector answers 405 Method Not Allowed (it accepts POST only). The client treats that 405 as a failed connect → capabilities never load → the toast fires.
Per the MCP spec, a 405 on the standalone GET (SSE) stream is explicitly allowed and the client is supposed to simply not use that stream and continue with POST. Here it is being treated as a fatal connection failure instead.
Triggered from AutoSyncConnectorsToSession / refreshClient (the app re-syncing remote connectors to a session), and it recurs continuously.
Impact
Mostly cosmetic but persistent and noisy. The actual tool calls (POSTs) do succeed — e.g. the same connector's tools work when invoked, and a parallel probe of the same connector from the Claude Code CLI completed normally in ≤17s. Only the capability-refresh path fails, so the user gets a stream of scary "capabilities not available" toasts even though tools are working. It also appears to correlate with occasional multi-minute stalls on the first calls after a (re)connect.
Notable
- No
401/ auth / token error anywhere in the console — it is not OAuth/credential related. - Only affects the remote Streamable-HTTP connector; local
mcp-remotestdio bridges on the same machine are unaffected.
Steps to reproduce
- Enable a remote Streamable-HTTP MCP connector routed through
claude.ai/v1/toolbox/shttp/mcp/<id>whose endpoint returns405on a GET (SSE stream open). - Use it in a session so the app runs
AutoSyncConnectorsToSession/refreshClient. - Observe the recurring "Client server capabilities not available" toast; DevTools console shows the
405 (Method Not Allowed)on_startOrAuthSse → connect.
Tried / did not help
- Disconnect + reconnect the connector.
- Full machine reboot.
Both leave the toast recurring.
Expected
Client should tolerate a 405 on the optional SSE GET stream (per MCP spec), fall back to POST-only operation silently, and not surface a fatal "capabilities not available" toast when tool calls are actually succeeding.
Environment
- Claude Desktop 1.21459.3.0 (x64, Windows)
- Embedded Claude Code 2.1.209
- Windows 11 Pro (26200)
(Connector ID, cloud ID, and internal item keys redacted — the repro is transport-layer and connector-agnostic.)
Showing cached comments. Read the full discussion on GitHub ↗
11 Comments
---
Reproduced with a different server stack — confirming this is client-side and transport-layer, not specific to the Atlassian connector.
Setup: custom remote MCP server built on Python FastMCP with
stateless_http=True+json_response=True, i.e. no standalone SSE stream at all — GET on the streamable-HTTP endpoint returns405by design, which the MCP spec explicitly permits (client SHOULD fall back to POST-only).Symptoms match 1:1:
tools/callarriving and completing200in \<1s at the exact time the UI showed "Unable to reach", and the model's answer contained the correct data from the tool result.So the failed capability-refresh (GET/SSE → 405 treated as fatal) not only fires the toast but also mislabels successful tool calls as unreachable in the transcript UI, which makes users suspect their server is down when it isn't.
Agree with the expected behavior: tolerate
405on the optional GET stream and continue silently POST-only.Correction to my earlier comment — I overstated the mechanism there. The part I can actually measure points somewhere slightly different, so I want to fix the record.
Two things I got wrong:
405by design". I inferred that from the FastMCP config (stateless_http=True+json_response=True) rather than measuring it. Measured: an unauthenticated GET on/mcpreturns401, because the OAuth gate sits in front of the transport. I never verified what an authenticated GET returns.GET /mcpever reaches my origin at all. Across the request windows I can still see (≈17:14–17:18Z and ≈20:48–21:12Z today), the connector's traffic is exclusivelyPOST /mcp— all200, sub-second — plus platform health checks on a separate path. Zero GETs on the MCP endpoint, authenticated or not.So on my side the toast fires without the SSE/GET leg ever being attempted against the upstream server.
Worth noting the failing request in the OP's trace is
GET https://claude.ai/v1/toolbox/shttp/mcp/<connector-id>— that is the claude.ai proxy route, not the upstream endpoint. I can't tell from outside whether that route forwards the GET leg upstream at all; from my origin's perspective it does not.That may matter for where the fix belongs: "tolerate a
405on the optional GET stream and fall back to POST-only" is correct per spec, but if the405originates inside the toolbox route rather than at the upstream server, then the tolerant handling — or the missing GET/SSE leg — needs to live there, and hardening only the upstream-facing path would not clear the toast.The rest of my earlier comment stands as observed: the toasts recur, the chat UI additionally renders an "Unable to reach \<connector\>" card on the tool-call block, and the tool calls themselves succeed — the POST
tools/callarrives and completes200in under a second at the exact timestamps the UI reports the connector unreachable.We have this as well with a custom MCP integration. It seems to have started last night with the most recent Claude Desktop updates: 1.21459.3.0 or 1.21459.3.1.
++++1 -> we have this as well.
For anyone using MCP Apps-based integrations, this is a critical bug that breaks the integration. MCP Apps depend on the negotiated host capabilities and the client↔server notification channel, so with this bug they fail to load within the Claude client.
You can see this in the renderer console as it repeats:
"[MCP Apps] oncalltool handler replaced. Previous handler will no longer be called."
The widget starts to render and then collapses into an "Unable to reach [connector]" error where the widget should be. The tool call itself actually succeeds (it returns a result, e.g. a review_id), so it's not that the tool is unreachable or blocked. It looks like the widget loses the host connection it needs when the capability refresh fails, and it tears itself down to that error state.
Adding an independent MCP Apps reproduction that may help narrow the impact beyond the recurring toast.
Our setup is a remote Streamable-HTTP MCP connector serving an MCP App. The app uses the official MCP Apps bridge and the supported external-navigation flow:
Appbridge;openLinkshost capability;App.openLink({ url }).The same app bundle, remote server, and HTTPS URL have succeeded in non-Windows Claude clients. On Windows, the host-mediated action does not complete reliably, which is consistent with the capability/connection failure described in this issue. A copy-to-clipboard fallback can reduce the damage, but it is not equivalent and does not help when the widget loses its host connection entirely.
I have not independently proven that the upstream cause is the GET/405 path, so I do not want to overstate that mechanism. The useful narrowing from this reproduction is:
window.open, a raw popup, or direct iframe navigation;Update: correlated evidence and 405 boundary
After correlating another failure/recovery and inspecting the public host-side MCP Apps implementation, the immediate failure mode is more concrete:
AppBridge.connect()implementation documents that this happens when the bridge connects before the MCP client has completed server initialization. It callsgetServerCapabilities()and throws the exact stringClient server capabilities not availablewhen the result is absent.405evidence must remain scoped carefully. A direct unauthenticated GET to the live origin returned401at the OAuth gate. Separately, local authenticated transport tests confirm that a stateless server without the optional notification stream returns the spec-valid405 Allow: POST. However, we have not captured Claude sending that authenticated GET to the origin during a failure. The only measured failing405in this thread is on Claude'sclaude.ai/v1/toolbox/shttp/mcp/<connector-id>route.So the evidence supports this chain:
capabilities absent during refresh → AppBridge.connect() throws → widget/host bridge is torn down or never becomes usableIt does not yet prove why the capabilities became absent. The proxy's GET/405 handling, capability-cache invalidation during
refreshClient, and bridge-mount sequencing are the layers that need investigation. A legal optional-GET405should not clear otherwise valid POST-negotiated capabilities or collapse an MCP App whose tool result already exists.The external-link symptom above was first isolated on Windows, but the underlying capabilities/widget failure should not be treated as Windows-only; the newer macOS reproduction in this thread shows the same lifecycle can recover after relaunch and degrade again later.
Please prioritize this as an integration-breaking host lifecycle regression rather than a cosmetic toast. MCP Apps rely on stable capability negotiation and the client/server notification bridge; when that state is lost, essential user actions and the entire embedded UI can become unusable even while the remote MCP server and POST tool flow are healthy.
we have same issue
macOS reproduction on a newer build — the
platform:windowslabel looks too narrow.com.anthropic.claudefordesktop), i.e. newer than the1.21459.3.0/1.21459.3.1builds named above.It is not fixed in 1.22209.0, and the recurrence pattern may be the most useful part:
The update installed and relaunched the app today at 11:08 local. Immediately afterwards the connector looked completely healthy — no toast, and MCP Apps widgets rendered normally, including widgets in previous transcripts that had previously collapsed into the "Unable to reach \<connector\>" card. Those re-rendered fine from the stored tool results, which supports @mike-phipps's read that the tool result was intact all along and only the widget's host connection was lost.
After continued use in the same session, the toast and the "Unable to reach" card came back.
So on macOS this behaves like a lifecycle/degradation issue rather than a static failure at connect time: healthy immediately after a fresh client launch, degrading after some usage. That is consistent with the periodic capability-refresh path in the OP's trace (
AutoSyncConnectorsToSession→refreshClient→listTools) rather than with a handshake that fails deterministically on first connect. Relaunching the client clears it temporarily, which may serve as a stopgap for others but obviously is not a fix.Origin-side observation from my earlier comment still holds at the same timestamps: the
POST tools/callarrives and completes200in under a second exactly when the UI reports the connector unreachable, and no GET ever reaches my origin at all — so from the server's perspective there is nothing failing to observe.Noting that this issue also occurs on the Claude web app (along the desktop app). The issue does not occur on mobile.
Happened to us as well
It seems like this issue was fixed? Haven't seen it reappear since Friday, at least on Windows + Claude Desktop.