Repository navigation
Description
Follow-up from the investigation on #2187.
Why
When a request times out, the Inspector says Request timed out and nothing else. For a debugging tool that is the least useful thing it could say: it names the symptom the user already sees and none of the state that would explain it.
#2187 is the worked example. The server was connected, initialize had succeeded, curl answered the identical tools/list in under 100ms, and the actual cause was a long-lived GET /mcp notification stream starving every subsequent POST on a concurrency-limited server. Every fact needed to suspect that was already in the Inspector's own process at the moment it gave up:
- the notification stream was open, and had been for the whole session without emitting a single event;
tools/listhad been outstanding for 60s;- nothing else had been answered since
notifications/initialized.
The reporter got none of it, and reasonably concluded the fault was in the Inspector's session handling. #2188 is plausibly the same shape wearing a different hat, and was filed separately for the same reason.
What
Surface the connection's outstanding state at the point of a timeout, rather than making the user reconstruct it from the Network tab. Roughly:
Request timed out after 60s. The notification stream (
GET /mcp) has been open for 4m12s and has emitted no events; 1 request is outstanding and no response has been received sincenotifications/initialized.
The specific signals worth having:
- whether the standalone GET stream is open, how long it has been open, and how many events it has delivered — a stream that has delivered zero events for the whole session is the tell;
- the count and age of outstanding requests;
- when the last response of any kind arrived.
Notes
- This is presentation over state we already hold: the fetch tracker sees the GET stream's lifetime (it already classifies it via
isLongLivedStreamResponseto avoid reading its body), and the message log knows what is outstanding and when the last response landed. - The timeout message is the highest-value placement, but the same summary would earn its keep on the Connection Info panel while a request is in flight.
- Keep it factual. It should report what the connection's state is and let the reader draw the conclusion — not assert a diagnosis the Inspector cannot actually verify from its own side.
Related
- Tools tab times out ("Request timed out") against a connected, OAuth-authenticated Streamable HTTP server running FastMCP's stateless_http=True mode #2187 — the case this comes from; the mechanism and a local fixture are in this comment.
- Server hangs forever at "Connecting..." when reconnecting with cached (still-valid) OAuth tokens #2188 — an unexplained hang against the same server, where the same diagnostics would likely have settled it immediately.
Activity
cliffhall commentedon Sep 11, 2026
Priority: Medium (total 6)
Board: #28, Status
Todo— filing it through the documented flow is the approval, so it skipsIncoming.fix: address Copilot review round 1 on #2318
fix: address Copilot review round 2 on #2318
fix: address Copilot review round 3 on #2318
fix: address Copilot review round 4 on #2318
fix: address Copilot review round 5 on #2318
fix: address Copilot review round 6 on #2318
Merge pull request #2364 from modelcontextprotocol/v2/feat/2318-timeo…
cliffhall commentedon Sep 14, 2026
Shipped in #2364 (merged to v2/main as ac01591).
feat(core): report connection state on a request timeout (modelcontex…
fix(web): put the SSE badge on the status variant so it clears the a1…
refactor(core): drive Tasks through @modelcontextprotocol/ext-tasks
refactor(core): gather the ext-tasks host adapter in core/extension/t…
feat(core): recognize HTTP 429 and surface the server's Retry-After