[macOS] Codex Desktop creates hidden threads and leaks one MCP process pool approximately every 5 minutes while idle
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
What version of the Codex App are you using (From “About Codex” dialog)?
Codex Desktop: 26.901.51231
What subscription do you have?
pro 20x
What platform is your computer?
MacOS
What issue are you seeing?
After a clean restart, Codex Desktop repeatedly creates a new hidden thread while the application is idle. Each hidden thread starts a complete MCP process pool, including XcodeBuildMCP, Context7, Computer Use, node_repl, and app-tool servers. The previous pool is not terminated.
The behavior is unbounded: process count and memory usage grow continuously until the application is fully quit.
What steps can reproduce the bug?
Steps to reproduce
- Start Codex Desktop after fully quitting it.
- Open or resume one local Codex task.
- Leave the application open and do not interact with it.
- Periodically inspect the app log and the descendants of the Codex
app-serverprocess. - Observe that a new hidden
thread/startoccurs approximately every 5 minutes 20 seconds and starts another complete MCP pool.
No scheduled automation or user action is required to trigger the growth.
What is the expected behavior?
- An idle application should not continuously create new threads.
- If an internal draft, prewarm, or code-mode thread is periodically replaced, its MCP child processes should be shut down.
- MCP process counts and memory usage should stabilize while the application is idle.
Additional information
[macOS] Codex Desktop creates hidden threads and leaks one MCP process pool approximately every 5 minutes while idle
Summary
After a clean restart, Codex Desktop repeatedly creates a new hidden thread while the application is idle. Each hidden thread starts a complete MCP process pool, including XcodeBuildMCP, Context7, Computer Use, node_repl, and app-tool servers. The previous pool is not terminated.
The behavior is unbounded: process count and memory usage grow continuously until the application is fully quit.
Environment
- macOS 26.6.2 (25G83), Apple Silicon (
arm64) - Physical memory: 36 GiB
- Codex Desktop:
26.901.51231 - Bundled Codex CLI / app-server:
0.153.4 - One visible Codex task was open
- No scheduled Codex automations were configured
- Global
openclawMCP: disabled - Global
XcodeBuildMCP: disabled context7: enabled- The build-ios-apps plugin supplied the runtime
xcodebuildmcpserver
Steps to reproduce
- Start Codex Desktop after fully quitting it.
- Open or resume one local Codex task.
- Leave the application open and do not interact with it.
- Periodically inspect the app log and the descendants of the Codex
app-serverprocess. - Observe that a new hidden
thread/startoccurs approximately every 5 minutes 20 seconds and starts another complete MCP pool.
No scheduled automation or user action is required to trigger the growth.
Expected behavior
- An idle application should not continuously create new threads.
- If an internal draft, prewarm, or code-mode thread is periodically replaced, its MCP child processes should be shut down.
- MCP process counts and memory usage should stabilize while the application is idle.
Actual behavior
- The renderer sends
thread/startwithconversationId=nullapproximately every 5 minutes 20 seconds. - Each new thread starts the same MCP servers.
- These thread IDs do not have corresponding session files and do not appear as user-visible tasks.
- No MCP stop, shutdown, reap, or thread-close events were found in the app log.
- Every recorded XcodeBuildMCP startup still had a corresponding live server process several hours later.
Observed timeline
All timestamps below are UTC:
21:51:20 hidden thread/start; MCP pool started
21:56:22 hidden thread/start; another MCP pool started
22:01:36 hidden thread/start; another MCP pool started
22:06:54 hidden thread/start; another MCP pool started
...
01:24:59 hidden thread/start; another MCP pool started
01:30:23 hidden thread/start; another MCP pool started
During the idle interval, the number of live XcodeBuildMCP server instances increased from 3 to approximately 43. No matching shutdown events occurred.
Sanitized log excerpt
2026-09-09T01:24:59.190Z ... conversationId=null ... method=thread/start originWebcontentsId=1
2026-09-09T01:24:59.192Z ... server=context7 status=starting threadId=<ephemeral-thread-A>
2026-09-09T01:24:59.192Z ... server=node_repl status=starting threadId=<ephemeral-thread-A>
2026-09-09T01:24:59.192Z ... server=cua_repl status=starting threadId=<ephemeral-thread-A>
2026-09-09T01:24:59.192Z ... server=xcodebuildmcp status=starting threadId=<ephemeral-thread-A>
2026-09-09T01:30:23.852Z ... conversationId=null ... method=thread/start originWebcontentsId=1
2026-09-09T01:30:23.852Z ... server=xcodebuildmcp status=starting threadId=<ephemeral-thread-B>
2026-09-09T01:30:23.854Z ... server=node_repl status=starting threadId=<ephemeral-thread-B>
2026-09-09T01:30:23.854Z ... server=context7 status=starting threadId=<ephemeral-thread-B>
Process snapshot after several hours
After returning to the app and collecting diagnostics, the process table contained:
| Process group | Live processes | Summed RSS |
|---|---|---|
| XcodeBuildMCP | 48 npm launchers + 48 Node servers | about 5.46 GiB |
| Context7 | 49 npm launchers + 49 Node servers | about 4.86 GiB |
node_repl |
96 | about 1.16 GiB |
| Computer Use launchers | 47 | about 1.76 GiB |
App-tool server.mjs processes |
47 | about 1.88 GiB |
| All app-server descendants | 538 | about 20.8 GiB |
The summed RSS values are not equivalent to unique physical memory because shared pages may be counted more than once. The process-count growth and lack of cleanup are independent of that limitation.
Configuration control results
- Disabling global OpenClaw worked: no
openclaw mcp serveprocesses were created after restart. - Disabling global
XcodeBuildMCPremoved the duplicate global definition. - The lower-case
xcodebuildmcpsupplied by the build-ios-apps plugin still started once for every hidden thread. - Therefore, individual MCP configuration changes reduce the memory cost per leaked thread but do not stop the hidden-thread creation loop.
Impact
- Continuously increasing process count and memory use while the app is idle
- Heavy swap or memory pressure on long-running sessions
- Hundreds of orphaned MCP-related descendants after a few hours
- Full application restart required to recover resources
Workaround
- Fully quit and reopen Codex Desktop to reclaim the leaked process pools.
- Disabling heavy MCP servers or plugins reduces the growth rate, but it does not fix the lifecycle issue.
Suspected area
The evidence points to a renderer-initiated draft/prewarm or code-mode-host lifecycle path: a new internal thread is periodically created, but the previous thread and its MCP process pool are not disposed. This is an inference from the log sequence, not a confirmed implementation-level root cause.
Additional evidence available
Raw app logs are available locally, but they are not attached because they may contain task names, local paths, prompts, or other sensitive information. A further sanitized excerpt can be provided if needed.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start from the renderer-initiated thread/start path and the app-server MCP process lifecycle described in the issue. Reproduce the idle loop on macOS, then trace how hidden threads are created and whether their MCP pools receive shutdown or cleanup events. Done means idle sessions stop creating hidden threads and MCP process counts and memory usage stabilize.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- macos, rust
- Domain
- desktop, devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100