Codex Desktop accumulates duplicate MCP/helper process trees and multi-GB RSS during UI/debugging workflows
Issue draft: Codex Desktop appears to leak MCP/helper process trees during UI debugging workflows
Title
Codex Desktop accumulates duplicate MCP/helper process trees and multi-GB RSS during UI/debugging workflows
Summary
I am seeing Codex Desktop accumulate many duplicate MCP/helper child-process trees during a recent UI debugging workflow involving browser/app automation, screenshots, and opening/closing app screens. The leak is visible outside the app with ps: a single Codex Desktop session currently has more than one hundred Codex-related processes in its process envelope, including repeated @playwright/mcp, xcodebuildmcp, context7-mcp, node_repl, and Computer Use helper processes.
At the latest sample, the Codex-related process envelope was using about 7.27 GiB RSS, with 105 helper/MCP processes using about 4.98 GiB RSS. This is high enough that I had to write an external local kill-switch monitor to prevent the machine from becoming unstable if the growth continues.
This looks related to, but not necessarily identical to, previously reported cleanup/leak issues around app-server, MCP tools, and Playwright MCP stdio processes:
- #12491
- #17574
- #17832
- #18881
Environment
- App: Codex Desktop for macOS
- Codex version:
26.422.71525 - Bundle version:
2210 - macOS:
26.2build25C56 - Architecture:
arm64 - Main app process observed:
/Applications/Codex.app/Contents/MacOS/Codex - App-server process observed:
/Applications/Codex.app/Contents/Resources/codex app-server --analytics-default-enabled
Workload that appears to trigger it
The recent task was primarily UI/debugging oriented:
- Use Codex Desktop for local development assistance.
- Invoke tools/plugins that spawn MCP/helper processes, especially browser/UI/simulator/debugging helpers.
- Open/close UI screens, run screenshot or browser-style automation, and inspect app state repeatedly.
- Continue in the same Codex Desktop session/thread for some time.
I do not yet have a minimal clean-room reproducer, but the process growth is visible in the live system state after this workflow.
Expected behavior
When a tool call, browser automation session, UI/screenshot inspection, simulator/debugging session, or Codex task finishes, Codex Desktop should clean up tool-specific MCP/helper processes that are no longer needed.
At steady state, I would expect:
- No unbounded growth in
npm exec ... mcpwrappers. - No unbounded growth in their child
node .../.bin/*-mcpprocesses. - No accumulation of stale helper process groups after UI/debugging tasks complete.
- Codex Desktop RSS and helper RSS to return close to baseline after work completes.
Actual behavior
A live sample taken on 2026-04-30 07:44:50 UTC showed:
Codex-related process count: 125
Focused Codex/MCP/helper ps rows: 111
Total Codex-envelope RSS: 7266.42 MiB
Helper/MCP process count: 105
Helper/MCP RSS: 4979.00 MiB
External guard decision in dry-run: kill_helpers
Guard reason: helper_count_limit
Representative largest processes from that sample:
PID PPID RSS MiB Age(s) Command
1106 653 453.52 1100 /Applications/Codex.app/.../Codex Helper (Renderer) --type=renderer ...
10766 653 271.89 30 /Applications/Codex.app/.../Codex Helper (Renderer) --type=renderer ...
653 1 227.03 1111 /Applications/Codex.app/Contents/MacOS/Codex
8987 4400 224.05 306 /Applications/Google Chrome.app/Contents/MacOS/Google Chrome ...
8998 8987 190.92 306 /Applications/Google Chrome.app/.../Google Chrome Helper (Renderer) ...
990 653 157.64 1101 /Applications/Codex.app/Contents/Resources/codex app-server --analytics-default-enabled
9964 9796 128.62 110 node .../.bin/xcodebuildmcp mcp
9908 9799 103.53 110 node .../.bin/playwright-mcp
6990 6867 97.02 427 node .../.bin/xcodebuildmcp mcp
5930 5828 94.58 513 node .../.bin/xcodebuildmcp mcp
9796 990 87.61 111 npm exec xcodebuildmcp@latest mcp
9800 990 86.45 111 npm exec @upstash/context7-mcp
9799 990 85.62 111 npm exec @playwright/mcp@latest
9285 9258 80.72 209 node .../.bin/playwright-mcp
4400 4289 79.70 730 node .../.bin/playwright-mcp
7450 7361 79.39 420 node .../.bin/xcodebuildmcp mcp
9904 9800 76.88 110 node .../.bin/context7-mcp
8594 8404 75.84 369 node .../.bin/xcodebuildmcp mcp
7467 7356 75.36 420 node .../.bin/playwright-mcp
7024 6862 75.34 427 node .../.bin/playwright-mcp
The important pattern is not one single large process. It is repeated process groups with the same shape, for example:
codex app-server
npm exec @playwright/mcp@latest
node .../.bin/playwright-mcp
codex app-server
npm exec xcodebuildmcp@latest mcp
node .../.bin/xcodebuildmcp mcp
codex app-server
npm exec @upstash/context7-mcp
node .../.bin/context7-mcp
Those groups appear many times in the same Desktop session.
Codex Desktop log observations
Recent logs were under:
~/Library/Logs/com.openai.codex/2026/04/30/codex-desktop-...-653-t0-i1-072628-0.log
Over the last 7 days, focused log scans found:
any_mcp=4835
workspace_dependencies_errors=4576
title_timeout=15
render_process_gone_mentions=3872
unresponsive_mentions=3872
xcodebuildmcp=0
playwright=1
Computer_Use=0
node_repl=0
A note on the render_process_gone_mentions / unresponsive_mentions counts: these are mentions inside serialized Electron event objects in repeated codex-home request log lines, not necessarily proof that those events fired. I am including them because those fields appear repeatedly while the process envelope is growing.
Representative recent log lines, with UUIDs redacted:
2026-04-30T07:36:16.281Z info [AppServerConnection] response_routed ... method=mcpServerStatus/list ... durationMs=3295 ...
2026-04-30T07:43:02.542Z info [AppServerConnection] response_routed ... method=mcpServerStatus/list ... durationMs=3927 ...
2026-04-30T07:44:20.744Z info [electron-fetch-handler] codex-home request hostId=undefined params={... "_events":{"render-process-gone":[...],"destroyed":[...],"unresponsive":[...]},"_eventsCount":32} ...
2026-04-30T07:44:20.744Z info [electron-fetch-handler] codex-home request hostId=local params={... "_events":{"render-process-gone":[...],"destroyed":[...],"unresponsive":[...]},"_eventsCount":32} ...
2026-04-30T07:44:50.570Z info [electron-fetch-handler] codex-home request hostId=undefined params={... "_events":{"render-process-gone":[...],"destroyed":[...],"unresponsive":[...]},"_eventsCount":32} ...
2026-04-30T07:44:50.571Z info [electron-fetch-handler] codex-home request hostId=local params={... "_events":{"render-process-gone":[...],"destroyed":[...],"unresponsive":[...]},"_eventsCount":32} ...
Earlier in the same log stream, there were repeated unsupported-feature errors:
unsupported feature enablement `workspace_dependencies`: currently supported features are apps, memories, plugins, tool_search, tool_suggest, tool_call_mcp_elicitation
I do not know if those feature-enable errors are causally related to the process leak. They are included only because they are frequent in the same recent desktop logs.
Commands used to collect evidence
Process sample:
ps -axo pid=,ppid=,rss=,etime=,command= \
| grep -E '/Applications/Codex.app|@playwright/mcp|playwright-mcp|xcodebuildmcp|context7-mcp|node_repl|SkyComputerUseClient|chrome-devtools-mcp'
App/bundle version:
/usr/libexec/PlistBuddy -c 'Print :CFBundleShortVersionString' /Applications/Codex.app/Contents/Info.plist
/usr/libexec/PlistBuddy -c 'Print :CFBundleVersion' /Applications/Codex.app/Contents/Info.plist
Log scan, simplified:
find ~/Library/Logs/com.openai.codex -type f -mtime -7 -name '*.log' -print0 \
| xargs -0 grep -hE 'mcp|workspace_dependencies|generate thread title|render-process-gone|unresponsive|xcodebuildmcp|playwright|Computer Use|node_repl'
Impact
The practical impact is that a long Codex Desktop session can accumulate enough helper processes and RSS to threaten overall system stability. In this session, helper processes alone were already near 5 GiB RSS. If the growth continues, the OS can become sluggish or run into memory pressure.
As a temporary mitigation, I wrote an external monitor that samples the Codex process envelope and, only after sustained threshold breaches, terminates Codex helper processes or the whole Codex tree. That is only a local safety net; ideally Codex Desktop should own this lifecycle cleanup internally.
Suggested investigation areas
- Whether MCP server lifecycle cleanup is tied to thread/session close but not to tool call completion.
- Whether repeated UI/browser/screenshot/debugger operations start new MCP server groups instead of reusing existing ones.
- Whether stdio MCP subprocesses survive when their owning renderer/tool invocation is done.
- Whether
app-serverretains references to old MCP server instances, preventing child cleanup. - Whether the repeated
mcpServerStatus/listcalls reflect many still-registered servers rather than only active servers. - Whether Desktop should enforce a maximum number of duplicate MCP helpers per server type and clean stale ones.
What would help confirm the fix
A fix would be easy to validate externally:
- Start Codex Desktop fresh.
- Run a UI/browser/screenshot/debugging workflow that invokes Playwright MCP, xcodebuild MCP, Context7 MCP, Computer Use, and node repl tools multiple times.
- Wait for the tool calls to complete.
- Check that stale
npm exec ... mcpwrappers and childnode .../.bin/*-mcpprocesses are cleaned up or reused. - Confirm process count and RSS return near baseline instead of growing monotonically.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗