Repository navigation
Description
Summary
The v2 server never traps SIGTERM/SIGINT, so Effect scopes (including MCP stdio transports) are never closed on stop/restart/crash. Local docker run MCP servers orphan permanently — --rm doesn't save them since nothing ever stops the container. I accumulated ~95 orphaned postgres-mcp containers from normal restarts alone.
Environment
- opencode version: v2.0.14
- OS: Linux desktop 7.2.6-arch2-1 (x86_64, Arch)
- Terminal: xterm-256color
- Shell: /usr/bin/bash
- Install/channel: latest (curl install,
~/.opencode/bin)
Reproduction
- Configure a local MCP server using
docker run(e.g.crystaldba/postgres-mcp), open any project using it so the server connects. docker ps→ one container running for the connection.- Restart the server (
opencode service restart,systemctl stop, or crash it). docker ps→ the old container is still running; the new server generation spawns a fresh one. Repeat → unbounded pileup (I reached ~95).
Same leak via TUI flow, no restart involved:
- Attach a TUI to a running server (
opencode --server http://localhost:4096), open a repo with a docker MCP. docker ps→ container running.- Ctrl+C the TUI (session stays server-side by design).
- The container keeps running indefinitely — observed persisting 20h+, well past the 60-minute location idle-eviction window, so eviction either never fires for these locations or doesn't tear down the MCP scope.
Expected Behavior
Server shutdown closes MCP scopes gracefully (the stdio transport already implements SIGTERM → 2s grace → SIGKILL in packages/core/src/mcp/stdio.ts), terminating child processes. Likewise, fully-idle locations (no attached clients, no active sessions) should release their MCP processes instead of holding them past the eviction window.
Actual Behavior
No signal handler exists anywhere in the server path (only desktop lifecycle, non-interactive runs, and profilers trap signals). Node dies instantly on SIGTERM; scopes/finalizers never run; docker children are adopted and run forever. Location idle eviction (60 min) only helps live servers, never post-restart orphans — and in the TUI-detach flow the containers outlive the eviction window.
Additional Context
- Verified against
v2branch source (2026-09-22):packages/core/src/mcp/index.ts("Connections remain Location-scoped"),packages/core/src/location-activity.ts(60-min TTL sweeper),packages/core/src/mcp/stdio.ts(graceful close that never gets invoked on shutdown). - Workaround: manually
docker stopcontainers with no livedocker runclient process. - Related but distinct: Missing SIGHUP handler causes orphaned processes to leak ~4.7 GB each after terminal death #14504 (V1 TUI missing SIGHUP handler, closed).
Activity
github-actions commentedon Sep 23, 2026
This issue might be a duplicate of existing issues. Please check:
In particular, #50758 appears to be nearly identical to this report. Please review it and let a maintainer know if your report covers a meaningfully distinct scenario (e.g. the SIGTERM signal handler gap specifically, or the docker
--rminteraction) before we decide whether to consolidate.neriousy commentedon Oct 20, 2026
Thanks for the report. We're tracking the same MCP child-process cleanup problem on service restart in #50758, so I'm closing this as a duplicate. Please follow that issue for updates.