Follow-up from the investigation on #2187.
Why
The MCP client opens the standalone GET /mcp notification stream immediately after initialize and before the first tools/list. Against a server that cannot serve a second concurrent request from the same client, that stream permanently occupies the only slot: initialize always succeeds and every request after it hangs until the SDK's 60s per-request timeout fires.
That is exactly what #2187 turned out to be, and it took building six variants of a fixture to establish it — because from inside the Inspector the symptom is a bare Request timed out on a server that is, by every other measure, connected and healthy. A single curl against the same server answers instantly, precisely because curl never holds that stream open.
There is currently no way to take the stream out of the picture, so there is no way for a user to test the hypothesis themselves. Today the only proof available is to leave the Inspector entirely and run two terminals of curl by hand.
What
A per-server setting that suppresses the standalone GET notification stream, leaving request/response traffic on POST only.
Two distinct payoffs:
- A diagnostic. Toggle it off; if the server starts answering, the cause is established in one click instead of an afternoon.
- An escape hatch. A server with this shape is currently un-inspectable past the connect handshake. With the stream suppressed it becomes usable for everything that doesn't depend on server-initiated messages — which is most of what the Inspector does.
Notes
- Opening the stream is explicitly permitted rather than required by the Streamable HTTP transport (the client MAY open a GET SSE stream for server→client messages), so suppressing it keeps us spec-conformant. It should be clear in the UI that server→client notifications will not arrive while it is off.
- Scope is the per-server settings model (
InspectorServerSettings), so it needs to reach createTransportNode and be honored on the web, CLI and TUI paths alike.
- Worth checking whether the SDK's
StreamableHTTPClientTransport already exposes an option for this before adding one of our own.
Repro fixture
The SERIAL=1 fixture in this comment reproduces the blocked state locally with no credentials and no network, and the same fixture with SERIAL unset is the control. It is what this setting should be verified against: with the toggle off, the SERIAL=1 fixture should list tools.
Follow-up from the investigation on #2187.
Why
The MCP client opens the standalone
GET /mcpnotification stream immediately afterinitializeand before the firsttools/list. Against a server that cannot serve a second concurrent request from the same client, that stream permanently occupies the only slot:initializealways succeeds and every request after it hangs until the SDK's 60s per-request timeout fires.That is exactly what #2187 turned out to be, and it took building six variants of a fixture to establish it — because from inside the Inspector the symptom is a bare
Request timed outon a server that is, by every other measure, connected and healthy. A singlecurlagainst the same server answers instantly, precisely because curl never holds that stream open.There is currently no way to take the stream out of the picture, so there is no way for a user to test the hypothesis themselves. Today the only proof available is to leave the Inspector entirely and run two terminals of
curlby hand.What
A per-server setting that suppresses the standalone GET notification stream, leaving request/response traffic on POST only.
Two distinct payoffs:
Notes
InspectorServerSettings), so it needs to reachcreateTransportNodeand be honored on the web, CLI and TUI paths alike.StreamableHTTPClientTransportalready exposes an option for this before adding one of our own.Repro fixture
The
SERIAL=1fixture in this comment reproduces the blocked state locally with no credentials and no network, and the same fixture withSERIALunset is the control. It is what this setting should be verified against: with the toggle off, theSERIAL=1fixture should list tools.