opencode icon indicating copy to clipboard operation
opencode copied to clipboard

fix(mcp): abort hanging connections to non-standard servers

Open anandka opened this issue 2 days ago • 1 comments

Issue

Fixes #8406

Problem

When connecting to non-standard MCP servers, OpenCode can hang indefinitely if the server returns HTTP 200 but:

  • Sends malformed SSE stream
  • Never completes MCP initialize handshake
  • Stalls during message exchange

The existing withTimeout wrapper rejects the promise but doesn't cancel the underlying network request, leaving connections hanging.

Solution

Add AbortController support to remote MCP transports using native Web APIs:

  1. Created AbortController instances for each transport (StreamableHTTP, SSE)
  2. Passed signal to requestInit - uses native fetch abort mechanism
  3. Abort on timeout - setTimeout calls abort() at configured timeout
  4. Cleanup in all paths - ensures abort() called on error/timeout

Changes

  • Modified packages/opencode/src/mcp/index.ts:
    • Added AbortController instances for each transport
    • Passed signal to transport requestInit
    • Added timeout handler that calls abort()
    • Added cleanup in .catch() and error paths

Before: OpenCode hung indefinitely After: Connection aborted after 30s timeout, clean error message

Implementation Notes

  • Follows team style: uses .catch() over try/catch
  • Minimal changes: ~27 lines added
  • Uses native Web APIs (AbortController/AbortSignal)
  • No new abstractions or files
  • Matches existing cleanup patterns (see #8253)

anandka avatar Jan 14 '26 08:01 anandka