opencode icon indicating copy to clipboard operation
opencode copied to clipboard

fix(mcp): connection hangs with non-standard SSE/HTTP servers which causes opencode to hang

Open ch-anandka opened this issue 3 weeks ago • 3 comments

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 AbortSignal to transport requestInit (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

ch-anandka avatar Jan 14 '26 08:01 ch-anandka

This issue might be a duplicate of existing issues. Please check:

  • #3273: MCP client failing makes opencode hang - 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.

github-actions[bot] avatar Jan 14 '26 08:01 github-actions[bot]

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.

anandka avatar Jan 14 '26 09:01 anandka

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!

sandipwane avatar Jan 14 '26 11:01 sandipwane