Repository navigation
Description
Describe the bug
When an MCP server's stdio transport drops a connection mid-session (the child process closes its stdout, the connection emits a close/error, or the transport's underlying pipe is recycled), opencode surfaces a MCP connection closed server=<name> WARN once and then leaves the transport in a permanently "failed" state. Tools registered by that MCP server stay unavailable for the rest of the session unless the user manually restartarts opencode — even when the MCP server is a self-healing daemon that would happily accept a fresh connection on the next call.
This is most visible with the lsp server from the oh-my-openagent plugin, which proxies tool calls to a per-user shared LSP daemon over a unix socket. The daemon kills its backing language server after a 5-minute idle timeout (intentional, to reclaim memory). The MCP stdio bridge between opencode and the daemon survives that, but when an in-flight tool call lands on the socket just as the daemon closes it, the resulting transport error is propagated to opencode as a fatal transport failure rather than as a recoverable per-call error.
Expected behavior
When an MCP transport reports a connection drop, opencode should at minimum:
- mark the transport as degraded (not failed),
- lazily attempt to re-establish the transport on the next tool call from the same MCP server,
- continue to accept other tool calls while the reconnect is in flight.
The MCP client SDK already exposes reconnect primitives; the gap is that opencode treats the first close as terminal for the lifetime of the session.
Actual behavior
MCP connection closed server=lspWARN appears in~/.local/share/opencode/log/opencode.log.- Subsequent tool calls against the same MCP server return "client not found" until opencode is restarted.
- Plugin-registered tools effectively disappear for the rest of the session, forcing the AI to fall back to alternative tools (grep/read loops, etc.) — measurable as a behavior drift even though the daemon itself is healthy.
Measured baseline on this host: ~1.47 WARN events/day across 17 days (25 events between 2026-07-03 and 2026-07-19), with the daemon itself always recoverable on the next call.
Steps to reproduce
- Install opencode (1.18.x) with the
oh-my-openagentplugin, which registers anlspMCP server that proxies tool calls to a shared LSP daemon. - Make a successful
lsp_diagnosticstool call. - Wait 5+ minutes (idle shutdown of the backing language server).
- Make another
lsp_diagnosticscall. The daemon closes the per-call socket mid-handshake. - Observe the
MCP connection closed server=lspWARN. - Make a third
lsp_diagnosticscall. It returns an error like "client not found" instead of lazily reconnecting.
Context
- The plugin-side root cause (the daemon client treated
requestWritten=trueas terminal and never retried) is being fixed upstream at fix(lsp-daemon): retry mid-request socket close/error instead of bailing out code-yeongyu/oh-my-openagent#6256 — that PR makes the daemon client retry mid-request close, which independently recovers most occurrences. - This issue is about a separate gap on the opencode side: even after the plugin retries successfully, opencode's own MCP transport layer does not recover from a transient connection drop. If both sides recover, users never see the WARN; today only the plugin side is fixing itself.
Possible solution
Lazily re-run the transport's connect() on the next tool call after a close, instead of caching the failed state for the whole session. The existing managed reconnect work (#37570 / #37586) covers TUI↔server reconnection but does not appear to cover MCP plugin transports, which is the layer this issue lives in.
Logs
WARN MCP connection closed server=lsp
Host: opencode 1.18.x on Linux, oh-my-openagent 4.13.0 (observed) / 4.18+ (also affected before the plugin-side fix lands).
Activity
github-actions commentedon Jul 21, 2026
This issue might be a duplicate of existing issues. Please check:
failedafter a connection error with no retry/reconnect logic, including a suggested fix inconvertMcpTool.onelpawarai commentedon Jul 21, 2026
https://github.com/onelpawarai/ZYRAXON-AI.git Please support my project."
jaepo01 commentedon Jul 21, 2026
Closing as duplicate of #25287 (canonical tracker, OPEN). Same root cause: MCP transport stays
failedafter a transient socket/connection close with no retry/reconnect logic inconvertMcpTool.Our PR code-yeongyu/oh-my-openagent#6256 addresses the same symptom from the plugin side (oh-my-openagent LSP daemon-client: reset
requestWritten=falseon socket close/error so the next call retries) and is complementary to the opencode-core fix proposed in #25287 — they are different layers:packages/opencode/src/mcp/index.ts(convertMcpTooltransport-aware retry) — opencode core, not yet landeddaemon-client.tsclose/error handlers — oh-my-openagent plugin, under reviewOnce #25287 lands at the core, the plugin-side retry becomes a defense-in-depth layer rather than the primary recovery path, but both are independently useful until the upstream fix ships.