Problem
Remote MCP servers (using SSEClientTransport or StreamableHTTPClientTransport) may have their connections closed by the remote server during idle periods due to server-side timeout policies. Currently, OpenCode:
- No keepalive mechanism - There's no heartbeat/ping to keep connections alive during idle periods
- No automatic reconnection - When a connection drops, OpenCode doesn't automatically attempt to reconnect
- No pre-use connection check - When an agent runs and needs MCP tools, OpenCode doesn't verify if connections are still alive before attempting to use them
- Reactive failure handling only - Connection failures are only detected when a tool call fails, at which point the client is marked as "failed" and removed from the active clients pool
Current Behavior
From `packages/opencode/src/mcp/index.ts`:
```typescript
// Tool fetching fails if connection is dead
const toolsResult = await client.listTools().catch((e) => {
log.error("failed to get tools", { clientName, error: e.message })
s.status[clientName] = { status: "failed", error: e.message }
delete s.clients[clientName]
return undefined
})
```
The current flow:
- MCP servers connect at startup
- Connection sits idle (no keepalive)
- Remote server closes connection due to inactivity
- User runs an agent that tries to use MCP tool
- Tool call fails → client marked as "failed"
- User must manually reconnect via `opencode mcp connect ` or restart OpenCode
Expected Behavior
- Keepalive mechanism - Periodic ping/heartbeat to keep remote connections alive (configurable interval)
- Auto-reconnection - When connection drops, automatically attempt to reconnect with exponential backoff
- Pre-use health check - Before an agent session starts, verify all configured MCP servers are connected and attempt reconnection for failed ones
- Connection state monitoring - Detect disconnections proactively (e.g., SSE close events) rather than waiting for tool call failures
Suggested Solution
- Add a configurable `keepalive` interval for remote MCP servers (e.g., `mcp.keepaliveInterval` in config)
- Implement periodic health checks using `client.ping()` or similar mechanism
- Listen for transport close/error events to detect disconnections immediately
- Add auto-reconnect logic with exponential backoff (configurable max retries)
- Before agent execution, check all MCP statuses and attempt to reconnect failed/disconnected servers
Workaround
Currently, users need to:
- Manually reconnect: `opencode mcp connect `
- Restart OpenCode to re-establish all MCP connections
- Use a proxy/load balancer that keeps connections alive
Impact
This affects reliability when using remote MCP servers, especially:
- Cloud-hosted MCP services with aggressive idle timeouts
- MCP servers behind corporate firewalls/proxies
- Long-running OpenCode sessions with sporadic MCP usage
Problem
Remote MCP servers (using
SSEClientTransportorStreamableHTTPClientTransport) may have their connections closed by the remote server during idle periods due to server-side timeout policies. Currently, OpenCode:Current Behavior
From `packages/opencode/src/mcp/index.ts`:
```typescript
// Tool fetching fails if connection is dead
const toolsResult = await client.listTools().catch((e) => {
log.error("failed to get tools", { clientName, error: e.message })
s.status[clientName] = { status: "failed", error: e.message }
delete s.clients[clientName]
return undefined
})
```
The current flow:
Expected Behavior
Suggested Solution
Workaround
Currently, users need to:
Impact
This affects reliability when using remote MCP servers, especially: