fix(mcp): connection hangs with non-standard SSE/HTTP servers which causes opencode to hang
Description
When connecting to non-standard MCP servers over SSE or StreamableHTTP, OpenCode can hang indefinitely if the server:
- Returns HTTP 200 but sends malformed SSE stream
- Accepts connection but never completes MCP initialize handshake
- Stalls during message exchange
The existing withTimeout wrapper only times out the promise but doesn't cancel the underlying HTTP/SSE connection, leaving resources
hanging.
Expected Behavior
Connection attempts should timeout gracefully and clean up resources, even if the server doesn't respond properly.
Current Behavior
OpenCode hangs waiting for server response, blocking startup or reconnection attempts.
Proposed Solution
Add AbortController support to remote MCP transports:
- Pass
AbortSignalto transportrequestInit(native fetch API) - Call
abort()on timeout to forcefully close connections - Ensure cleanup in all error paths
Environment
- OpenCode version: latest (dev branch)
- MCP server: Custom/non-standard SSE server
This issue might be a duplicate of existing issues. Please check:
- #3273: MCP client failing makes
opencodehang - Similar hanging/blocking behavior when MCP fails - #5371: Support MCP servers that require POST-based or non-standard SSE handshake - Related to non-standard SSE servers
- #8058: Add HTTP Streamable transport support for remote MCP servers - Related to HTTP/SSE transport issues
- #8212: MCP was interrupted during runtime by a timeout warning - Related to MCP timeout handling
- #8171: MCP Docker servers fail to connect after upgrade - Similar connection failure patterns
- #6633: MCP processes not terminated after session ends - Related to resource cleanup issues
Feel free to ignore if none of these address your specific case.
Not a Duplicate - Different Root Cause
Our Issue: Network-level hang when MCP servers send HTTP 200 but malformed/incomplete responses. The withTimeout wrapper rejects the promise but doesn't cancel the underlying fetch() request, leaving connections open indefinitely.
Unique technical gap: We're adding AbortController to forcefully terminate fetch requests on timeout, which none of the above issues
address.
Our fix complements #8212 (handles connection timeout) and prevents scenarios like #3273 (app freezing) by failing gracefully.
Hi @rekram1-node, Can you please take a look at this issue? We're currently blocked on shipping an MCP feature due to the connection hanging behavior described here.
@anandka has already raised PR with the fix: #8413. Would appreciate a review when you get a chance.
Thanks!