Skip to content

Duplicate MCP servers accumulate under one opencode process (5× mcp-reva, ~6GB RAM) #52965

Open

Description

@Bittimoruk

Description

Problem

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
  • MCP: reva (mcp-reva.exe), semgrep (pysemgrep), codegraph (node), jev

Plugins

External: opencode-orchestrator 2.0.13, oc-agent-router, magic-context 0.44.4, subagent-model, codegraph-bridge, tokenscope-adapter. | local: codegraph-autosetup, fast-jev, env-protection. | MCP (server, not a plugin): codegraph, jev, mslearn, semgrep, reva.

OpenCode version

OpenCode v2 (service 2.0.22)

Steps to reproduce

Steps to reproduce

  1. Configure several MCP servers (heavy ones reproduce fastest — e.g.
    Ghidra/ReVa mcp-reva.exe, semgrep, codegraph).
  2. 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.
  3. Open Task Manager → Details, or run:
    Get-CimInstance Win32_Process | Where-Object { $_.ParentProcessId -eq <opencode PID> }
  4. 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.

Screenshot and/or share link

No response

Operating System

Windows 10 Pro x64

Terminal

CMD

Activity

  1. github-actions commented on Oct 3, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    • #52410: MCP child processes accumulate because servers are not reaped on client reconnects.
    • #46174: Windows Desktop starts duplicate MCP processes while idle, causing multi-GB RAM usage.
    • #52741: An initial-reconciliation race can start duplicate stdio MCP servers.
  2. adhitya-tix commented on Oct 9, 2026

    @adhitya-tix

    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:

    • github-mcp-server → 2
    • codebase-memory-mcp → 2 (+1 shared --cbm-daemon-internal)
    • serena-ios and serena-android (two serena configs) → 4

    Opening a second session added exactly one process per config:

    46492 github-mcp-server
    46493 codebase-memory-mcp
    46494 serena-ios
    46495 serena-android
    

    → 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

    1. Configure any local stdio MCP server (optionally two configs, e.g. two Serena projects).
    2. opencode service restart; pgrep -fl <server> → 2 per config.
    3. Open a second session → +1 per config.
    4. 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 / restart does.

  3. kris-cloudaccess commented on Oct 14, 2026

    @kris-cloudaccess

    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:

    1. 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".
    2. 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.
    3. 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).
    4. 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).
    5. 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.

  4. CerisonAutomation commented on Oct 22, 2026

    @CerisonAutomation

    Confirmed on opencode 2.1.2 (Homebrew), macOS 27.0.1.

    Two caveman-mcp instances ran simultaneously under one opencode serve --service PID, one of them completely idle:

    2973  42685  32896KB  caveman-mcp
    2974  42685  32960KB  caveman-mcp
    

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions