opencode
opencode copied to clipboard
fix(mcp): abort hanging connections to non-standard servers
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:
- Created AbortController instances for each transport (StreamableHTTP, SSE)
-
Passed
signaltorequestInit- uses native fetch abort mechanism -
Abort on timeout -
setTimeoutcallsabort()at configured timeout -
Cleanup in all paths - ensures
abort()called on error/timeout
Changes
- Modified
packages/opencode/src/mcp/index.ts:- Added
AbortControllerinstances for each transport - Passed
signalto transportrequestInit - Added timeout handler that calls
abort() - Added cleanup in
.catch()and error paths
- Added
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)