You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Duplicate MCP servers accumulate under one opencode process (5× mcp-reva, ~6GB RAM) #52965
A single opencode process accumulates duplicate MCP server processes
that are never reaped. Observed on Windows: 5× mcp-reva.exe (400MB–1.2GB
each), 6× pysemgrep.exe, 30+ node.exe, all parented to one live opencode.exe. Total: ~110 processes, ~6.3GB RAM (python 3.6GB + node
2.1GB). Parent chain verified alive via Win32_Process — these are
duplicates, not orphans.
Repro
Use several MCP servers (esp. heavy ones like Ghidra/ReVa), run many
sessions/CLI invocations against the same server. Each reconnect spawns
a new server; old ones stay.
Expected
One MCP server instance per configured server per opencode process
(or cleanup on session end / reconnect replacing the old instance).
Environment
OpenCode v2 (service 2.0.22), Windows 10 x64/Windows 11 x64
Configure several MCP servers (heavy ones reproduce fastest — e.g.
Ghidra/ReVa mcp-reva.exe, semgrep, codegraph).
Use the same opencode server across many sessions and CLI
invocations (opencode run, opencode mcp list, subagent tasks).
Restart the TUI a few times without killing child processes.
Open Task Manager → Details, or run: Get-CimInstance Win32_Process | Where-Object { $_.ParentProcessId -eq <opencode PID> }
Observe: multiple instances of the same MCP server
(e.g. 5× mcp-reva.exe, 6× pysemgrep.exe) under one opencode process,
totaling several GB RAM. Old instances are never reaped.
Confirmed on macOS, opencode desktop 2.0.25 (opencode v2.0.25, install channel latest), Darwin 25.6.0 arm64. Two reproducible behaviors, both about local stdio MCP servers.
1. ~2 stdio processes per local MCP server config, +1 per config per additional session.
After a clean opencode service restart (no extra sessions), each local MCP config had 2 processes:
→ counts became 3 per config. So per config: base 2 + 1/session.
2. Children are not cleaned up when the app is quit. Cmd+Q left the opencode-cli serve --service daemon and all 13 MCP children alive (verified from a terminal after quit). Only opencode service stop/restart cleared them — a service restart did replace the whole tree, so the children are tied to the daemon, not the app.
Impact: the duplicated processes each start their own language servers. For Serena that means extra sourcekit-lsp and jdtls/Gradle-daemon JVMs, so RAM/CPU scales with the duplication.
Repro
Configure any local stdio MCP server (optionally two configs, e.g. two Serena projects).
opencode service restart; pgrep -fl <server> → 2 per config.
3. Closing a session does not clean up its MCP processes either.
Closing the second session left every process alive — the PID list was byte-for-byte unchanged (still 3 per config; 0 gone). So none of app-quit, session-close, or config-reload frees the children; only opencode service stop / restart does.
Confirming this on Linux with OpenCode 2.0.29 (also observed on 2.0.28) — it matches the macOS report above closely, including the "base 2 + 1/session" pattern.
Environment: CachyOS (Arch-based), KDE Plasma on Wayland. Local stdio MCP servers: codebase-memory-mcp, donsetch (node wrapper), serena (python, spawns LSP children), sqz-mcp; two remote servers (context7, gh_grep). Memory measured as PSS from /proc/<pid>/smaps_rollup.
Observations:
After a clean opencode service restart with a single TUI session, each local MCP config had 2 processes (two complete sets), both spawned in the same second (14:01:14). Matches "base 2 per config".
With 3 TUI sessions open, the sets rebuilt to 4 within ~75 min: 14:57:07 (service/first session), 15:29:12 (third session start), plus two extra re-inits at 15:58:06 and 16:00:06 with no new session — i.e. one set per session start plus activity re-inits.
Growth: the total OpenCode stack went from ~1.0 GB to ~1.66 GB in 75 minutes (service 421 MB + MCP 734 MB across 31 processes + TUI clients 505 MB). Earlier in the day on 2.0.28 with 3 sessions we measured 5 sets ≈ 1 GB PSS for the MCP processes alone, and the service log showed 12 full-set reconnect bursts in one day (~every 10–45 min) with no error/crash lines preceding them (one burst was preceded 0.3 s earlier by a watcher subscribe on a plugin source directory — session wake-up, not a crash).
Used sets grow: the oldest set's donsetch child had grown to 401 MB PSS after a day of use (fresh instances are 7–17 MB each).
Nothing is reaped on session close or app quit — only service stop / restart clears the tree, same as the macOS report.
This looks consistent with #52741 (initial reconciliation can duplicate stdio servers) and the per-location caching in #37844/#52410. Happy to provide service logs or run a OPENCODE_LOG_LEVEL=DEBUG repro if that helps.
opencode mcp list reported caveman connected and the tools worked normally, so the duplicate is invisible from the client side — the only symptom is the RSS.
Attribution method (this matters, because killing the wrong one breaks the live session): snapshot per-PID CPU time, issue one tool call that does real work through the server, snapshot again, and diff. The instance whose CPU time moved is the one actually serving the session. In my case PID 42692 moved +0.23 s of CPU on a 1.4 MB compress call while 30834 and 42696 stayed flat — I terminated only the two idle ones.
The duplication is a consequence of the per-location spawn described in #51003, which is why the 5x figure in this issue reproduces reliably: the count scales with the number of directories opencode has loaded, not with the number of sessions.
Activity
github-actions commentedon Oct 3, 2026
This issue might be a duplicate of existing issues. Please check:
adhitya-tix commentedon Oct 9, 2026
Confirmed on macOS, opencode desktop 2.0.25 (
opencode v2.0.25, install channellatest), Darwin 25.6.0 arm64. Two reproducible behaviors, both about local stdio MCP servers.1. ~2 stdio processes per local MCP server config, +1 per config per additional session.
After a clean
opencode service restart(no extra sessions), each local MCP config had 2 processes:github-mcp-server→ 2codebase-memory-mcp→ 2 (+1 shared--cbm-daemon-internal)serena-iosandserena-android(two serena configs) → 4Opening a second session added exactly one process per config:
→ counts became 3 per config. So per config: base 2 + 1/session.
2. Children are not cleaned up when the app is quit.
Cmd+Qleft theopencode-cli serve --servicedaemon and all 13 MCP children alive (verified from a terminal after quit). Onlyopencode service stop/restartcleared them — aservice restartdid replace the whole tree, so the children are tied to the daemon, not the app.Impact: the duplicated processes each start their own language servers. For Serena that means extra
sourcekit-lspandjdtls/Gradle-daemon JVMs, so RAM/CPU scales with the duplication.Repro
opencode service restart;pgrep -fl <server>→ 2 per config.Cmd+Q;ps -p <recorded pids>→ still ALIVE.Related: #53992, #50363, #50758.
3. Closing a session does not clean up its MCP processes either.
Closing the second session left every process alive — the PID list was byte-for-byte unchanged (still 3 per config; 0 gone). So none of app-quit, session-close, or config-reload frees the children; only
opencode service stop/restartdoes.kris-cloudaccess commentedon Oct 14, 2026
Confirming this on Linux with OpenCode 2.0.29 (also observed on 2.0.28) — it matches the macOS report above closely, including the "base 2 + 1/session" pattern.
Environment: CachyOS (Arch-based), KDE Plasma on Wayland. Local stdio MCP servers:
codebase-memory-mcp,donsetch(node wrapper),serena(python, spawns LSP children),sqz-mcp; two remote servers (context7, gh_grep). Memory measured as PSS from/proc/<pid>/smaps_rollup.Observations:
opencode service restartwith a single TUI session, each local MCP config had 2 processes (two complete sets), both spawned in the same second (14:01:14). Matches "base 2 per config".watcher subscribeon a plugin source directory — session wake-up, not a crash).donsetchchild had grown to 401 MB PSS after a day of use (fresh instances are 7–17 MB each).service stop/restartclears the tree, same as the macOS report.This looks consistent with #52741 (initial reconciliation can duplicate stdio servers) and the per-location caching in #37844/#52410. Happy to provide service logs or run a
OPENCODE_LOG_LEVEL=DEBUGrepro if that helps.CerisonAutomation commentedon Oct 22, 2026
Confirmed on opencode 2.1.2 (Homebrew), macOS 27.0.1.
Two
caveman-mcpinstances ran simultaneously under oneopencode serve --servicePID, one of them completely idle:opencode mcp listreportedcaveman connectedand the tools worked normally, so the duplicate is invisible from the client side — the only symptom is the RSS.Attribution method (this matters, because killing the wrong one breaks the live session): snapshot per-PID CPU time, issue one tool call that does real work through the server, snapshot again, and diff. The instance whose CPU time moved is the one actually serving the session. In my case PID 42692 moved +0.23 s of CPU on a 1.4 MB compress call while 30834 and 42696 stayed flat — I terminated only the two idle ones.
The duplication is a consequence of the per-location spawn described in #51003, which is why the 5x figure in this issue reproduces reliably: the count scales with the number of directories opencode has loaded, not with the number of sessions.