Subagents leak stdio MCP helper trees in Codex App; xcodebuildmcp and chrome-devtools-mcp accumulate indefinitely
What version of the Codex App are you using (From “About Codex” dialog)?
26.409.20454 (build 1462)
What subscription do you have?
Pro
What platform is your computer?
Darwin 25.3.0 arm64 arm
What issue are you seeing?
Codex App appears to leak stdio MCP helper process trees when subagents are spawned.
On my machine, every time Codex creates a subagent / thread spawn, it appears to initialize MCP again for the subagent session, including:
npm exec xcodebuildmcp@latest mcpnpm exec chrome-devtools-mcp@latest --isolated --no-usage-statistics --no-performance-crux
Those helpers are not being cleaned up reliably after the subagent/session closes. Over time they accumulate and drive memory pressure and swap usage extremely high.
Current process state I captured while Codex App was still running:
- Codex app-server PID:
67522 - stale/accumulated
npm exec ...parents:394 node ... xcodebuildmcp mcpchildren:198chrome-devtools-mcpchildren:199- total related processes:
791 - combined RSS of those related processes: about
13.5 GB
Breakdown:
npm exec ...parents: about6.9 GB RSSxcodebuildmcpchildren: about3.2 GB RSSchrome-devtools-mcpchildren: about3.4 GB RSS
This is large enough that macOS starts consuming tens of GB of swap.
The pattern I see in logs is:
spawn_agentthread_spawnsession_init.mcp_manager_init- Codex session closes almost immediately
- but the spawned MCP helper processes remain alive for tens of minutes or longer
So the issue looks like a lifecycle / teardown bug in Codex App rather than a bug inside xcodebuildmcp itself.
What steps can reproduce the bug?
I do not yet have a minimal deterministic repro, but this reproduces repeatedly during normal use in Codex App.
My environment includes:
- Codex App on macOS
build-ios-appsplugin enabled- global
chrome-devtoolsMCP enabled - frequent use of subagents /
spawn_agent
Rough repro pattern:
- Start Codex App.
- Work in a thread that uses subagents repeatedly.
- Have plugins / MCP-backed tools available, especially:
xcodebuildmcpchrome-devtools-mcp
- Continue using the app for a while, spawning multiple subagents over time.
- Inspect processes with
ps/ Activity Monitor.
Observed result:
- each subagent/thread spawn appears to trigger a fresh MCP manager init
- new
npm exec ...MCP parents and helper children are spawned - old helper trees are not cleaned up
- process count and memory usage keep growing
Relevant local observations:
- app-server parent PID was
67522 - I saw log sequences like:
spawn_agentthread_spawnsession_init.mcp_manager_init- immediate
codex: close - but corresponding
xcodebuildmcp/chrome-devtools-mcpprocesses remained alive
This may be related to or a regression adjacent to earlier MCP leak issues, but I am still seeing it on:
- Codex App
26.409.20454 - Codex CLI/core version family corresponding to current
0.120.0
I can provide logs, process snapshots, or uploaded thread/session details if needed.
What is the expected behavior?
Codex App should not leave stdio MCP helper trees running after a subagent or spawned session is finished.
Expected behavior:
- MCP helper processes should be reused safely or torn down reliably
- ending a subagent/session should clean up its entire MCP subprocess tree
- repeated
spawn_agentusage should not grow the number ofxcodebuildmcp/chrome-devtools-mcphelpers without bound - long-running Codex App usage should not consume tens of GB of swap because of stale MCP helpers
Additional information
Related symptoms seem close to issues #16895, #14950, and #17448, but I am reporting a current Codex App repro with concrete process counts and memory usage.
<img width="920" height="615" alt="Image" src="https://github.com/user-attachments/assets/1b13acb8-514c-49cb-bdfa-c8dffb03524c" />
6 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Same bug, different MCP server. We observed 213 leaked
@playwright/mcpprocess pairs (13.6 GB RSS) on v0.120.0. Filed as #17832.Your description of the
spawn_agent -> thread_spawn -> session_init.mcp_manager_init -> closelifecycle is accurate. We traced it through the source: eachSession::new()creates its ownMcpConnectionManager::new()with fresh child processes, buthandlers::shutdown()never calls cleanup on MCP.McpConnectionManagerhas noDropimpl, noshutdown(), noclose().Root cause analysis with proposed fix: #17832 (comment)
https://github.com/openai/codex/issues/17832#issuecomment-4247026597
The big clue here is that the leak is tied to session_init.mcp_manager_init on subagent spawn, not just raw process count. That suggests the missing lifecycle primitive is probably a session-scoped MCP ownership model: either helpers are shared and reference-counted across child sessions, or child-specific helpers get a guaranteed teardown receipt when the child closes. Right now it sounds like Codex has spawn receipts but not reliable close receipts for the helper tree. We have been hitting a similar boundary in MartinLoop whenever tool runtimes outlive the attempt they were admitted for. If helpful, happy to compare notes against the OSS run-record shape we are using for terminal halt and teardown accounting.
Adding one more reproduction signal from Codex Desktop while working in a real iOS product repo.
Observed behavior:
build-ios-apps@openai-curatedwas enabled in~/.codex/config.toml.xcodebuildmcpthrough:``
json
``{
"command": "npx",
"args": ["-y", "xcodebuildmcp@latest", "mcp"]
}
``
text
``npm exec xcodebuildmcp@latest mcp
node .../.bin/xcodebuildmcp mcp
npm exec xcodebuildmcp@latest mcpparents were direct children of the Codex app-server process.swift-frontend; later verification showed the MCP helpers remained as idle leaked residue after build workers were gone.pkill -f 'xcodebuildmcp'cleared the leak. After cleanup,xcodebuildmcp,xcodebuild, andswift-frontendwere all absent fromps.Impact:
xcodebuildmcp, the failure mode is especially expensive because a leaked/duplicated server can fan out intoxcodebuildandswift-frontendworkers.build-ios-apps@openai-curateddisabled unless actively using the iOS MCP workflow.This looks like a Codex Desktop/plugin MCP lifecycle issue rather than an app-project issue. Sharing because predictable MCP process cleanup matters for longer-running Codex sessions.
I can confirm closely related behavior, including on a remote Linux execution environment controlled from Codex Desktop on macOS.
Environment
26.707.31428(build5059), bundled Codex0.144.0-alpha.40.144.1build-ios-apps@openai-curated-remote, version0.1.2xcodebuildmcp2.6.2Original user-visible failure
With plugins enabled, Codex tasks running on my remote Linux machine would eventually stop responding completely. The live process table showed:
npm exec xcodebuildmcp@latest mcpsh -c xcodebuildmcp mcpnode .../xcodebuildmcp mcpThis happened even though XcodeBuildMCP is not useful on that Linux machine and I had explicit local disable entries for both the local and remote Build iOS plugin IDs.
codex mcp listcould look clean while the processes were still running. Returning the remote machine toplugins = false, killing the XcodeBuildMCP process trees, and starting a fresh task restored normal operation.Controlled reproduction
I reproduced the Desktop-selected plugin path directly through app-server using a real
selectedCapabilityRootsentry for Build iOS Apps.A single isolated thread behaved normally:
thread/startcompleted in approximately0.33s4.70sand4.01sSo this does not appear to require XcodeBuildMCP itself to fail during initialization. A single instance can initialize successfully on Linux.
The problem appeared when I repeated the selected-root lifecycle in one long-running app-server:
mcpServerStatus/listfor that thread.Observed process growth:
3XcodeBuildMCP-related processes (npm->sh->node)6processes12processes were observedmcpServerStatus/listrequest timed out after60sIn normal Desktop usage, the corresponding user-visible symptom was that my remote Codex tasks stopped responding.
When I terminated the isolated app-server itself, all XcodeBuildMCP process trees disappeared. That points to lifetime management within the long-running app-server/thread lifecycle rather than an unkillable child process.
Reproduction caveat
The controlled test used ephemeral threads.
thread/deletereturned:thread is not persisted and cannot be deletedTherefore those ephemeral threads remained loaded during the test. This does not by itself prove that every process was orphaned after a successful thread deletion, but it does demonstrate that repeated loaded/spawned threads create independent MCP process trees and can make the app-server unresponsive very quickly.
This seems consistent with the issue's broader lifecycle problem: MCP subprocess ownership is tied to individual thread/session initialization, while teardown or reuse is not reliably preventing process accumulation in a long-running Codex app-server.
Related selected-plugin behavior
In my remote setup, Desktop-selected capability roots also bypassed ordinary per-plugin
enabled = falseconfiguration. If the Build iOS plugin root was selected for the Linux environment, its MCP declaration was launched there regardless of the local disable entry.My current stable mitigation is:
apps = trueplugins = falseI can provide the JSONL app-server reproduction harness or additional process snapshots if useful.
Windows confirmation on a current
26.707build: completed subagent stacks still remain alive after the earlier shutdown fix.Environment
19045, x64OpenAI.Codex 26.707.3748.0codex-cli 0.144.0-alpha.4codex.exe app-servernode_repl, AgentMemory MCP, and three plugin MCP serversControlled completion-versus-process proof
I correlated one subagent rollout with the process burst created beneath the packaged
codex.exe app-server:session_metatimestamp was2026-07-17T06:17:13.549Z.node_repl, one AgentMemory launcher plus child, and three plugin MCP Node servers.task_completeat2026-07-17T06:22:22.760Z, and the collaboration UI/registry reported the subagent as completed.open.250.9 MiBworking set,152.7 MiBprivate memory,67threads, and893handles while idle.This makes the lifecycle boundary explicit: the model/subagent turn completes, but the subagent's stdio MCP client/process group is not drained.
Accumulated impact
Before restarting the app, the packaged ChatGPT/Codex tree had accumulated:
83descendants11node_replprocesses / persistent runtime stacks44plugin MCP Node processes4.24 GBworking set and3.64 GBprivate bytes1,241threads and17,607handlesWindows Error Reporting also contained recent ChatGPT hang and resource-leak events. System RAM, pagefile, disk activity/free space, network response, and GPU memory were not saturated.
A normal app restart immediately collapsed the runtime count from 11 stacks to one active stack. In a separate spawn, one subagent timestamp also produced two complete MCP stacks, suggesting duplicate initialization can amplify the leak.
Reproduction pattern
task_completeand the UI reports it done.codex.exe app-server.node_repl/ MCP process burst remains alive.Regression detail
The installed bundled CLI is newer than the merge of #19753, which added explicit MCP client shutdown/draining and process-group termination. The issue therefore appears to be a remaining Windows Desktop collaboration/subagent close path or a regression adjacent to that fix, rather than simply an older build missing it.
Normal inactive owner-thread unsubscribe is present and observable in the desktop logs, but it does not appear to close these completed subagent sessions. There is also no supported MCP idle lifetime, shutdown timeout, or process-limit configuration that prevents the accumulation.
Expected behavior
When the latest subagent turn reaches
task_complete, Codex should close/drain that subagent's MCP manager and terminate its owned stdio process group. Repeated completed subagents should not increase the persistent process count.I have retained sanitized process snapshots and timing evidence and can provide them privately if a maintainer needs additional details. I have intentionally not attached raw session transcripts, account data, or local paths to this public comment.