Normalize reporting of failed connection.
Originally posted by @halter73 in https://github.com/modelcontextprotocol/inspector/pull/339#pullrequestreview-2789087665
I tested this with the sample Streamable HTTP server at https://github.com/modelcontextprotocol/csharp-sdk/tree/v0.1.0-preview.11/samples/AspNetCoreSseServer (it has yet to be renamed from "Sse"), and things seem to work pretty well. I tested sampling using the "sampleLLM" tool, and that worked nicely.
Unfortunately, the Streamable HTTP transport also does not immediately report a connection error and ask "Connection Error, is your MCP server running?" when the connection is refused because there's no server listening like the SSE transport does. It just stays in the "Disconnected" state not indicating that it's connecting or that it even registered you clicking the connect button until about a minute later when it shows an error.
SSE ECONREFUSED logs
[1] New SSE connection. NOTE: The sse transport is deprecated and has been replaced by streamable-http
[1] Query parameters: [Object: null prototype] {
[1] url: 'http://localhost:3001/',
[1] transportType: 'sse'
[1] }
[1] SSE transport: url=http://localhost:3001/, headers=Accept
[1] Error in /sse route: SseError: SSE error: TypeError: fetch failed: connect ECONNREFUSED ::1:3001, connect ECONNREFUSED 127.0.0.1:3001
[1] at EventSource._eventSource.onerror (H:\modelcontextprotocol\inspector\node_modules\@modelcontextprotocol\sdk\src\client\sse.ts:133:23)
[1] at EventSource.scheduleReconnect_fn (H:\modelcontextprotocol\inspector\node_modules\eventsource\src\EventSource.ts:557:5)
[1] at <anonymous> (H:\modelcontextprotocol\inspector\node_modules\eventsource\src\EventSource.ts:441:5)
[1] at process.processTicksAndRejections (node:internal/process/task_queues:105:5) {
[1] code: undefined,
[1] event: {
[1] type: 'error',
[1] message: 'TypeError: fetch failed: connect ECONNREFUSED ::1:3001, connect ECONNREFUSED 127.0.0.1:3001',
[1] code: undefined,
[1] defaultPrevented: false,
[1] cancelable: false,
[1] timeStamp: 2422561.2383
[1] }
[1] }
Streamable HTTP ECONREFUSED logs
[1] New streamable-http connection
[1] Query parameters: [Object: null prototype] {
[1] url: 'http://localhost:3001/',
[1] transportType: 'streamable-http'
[1] }
[1] Connected to Streamable HTTP transport
[1] Connected MCP client to backing server transport
[1] Created streamable web app transport e020a675-58df-4165-bc34-a20b4ba4763c
[1] Error from MCP server: TypeError: fetch failed
[1] at node:internal/deps/undici/undici:13502:13
[1] at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
[1] at async StreamableHTTPClientTransport.send (H:\modelcontextprotocol\inspector\node_modules\@modelcontextprotocol\sdk\src\client\streamableHttp.ts:394:24) {
[1] [cause]: AggregateError [ECONNREFUSED]:
[1] at internalConnectMultiple (node:net:1139:18)
[1] at afterConnectMultiple (node:net:1712:7) {
[1] code: 'ECONNREFUSED',
[1] [errors]: [ [Error], [Error] ]
[1] }
[1] }
Can we close this one now?
Can we close this one now?
@olaservo I think @halter73 was right and this could be handled better. I think the message in the Inspector is fine, but we could clean up the console output for this kind of error, since it's common. Seeing the stack trace of an ECONNREFUSED isn't really helpful. We can detect that in the error message and output a single message that's not so messy. I'll make a PR for it.
@olaservo I created #478 to address this.