Summary
The interactive Codex CLI starts a separate pair of bundled plugin helper processes for every subagent. When the subagent reports completion, those helper processes remain alive under the main Codex process.
For someone unfamiliar with these terms:
- A subagent is a parallel worker that Codex starts to handle part of a task.
- An MCP server is a local helper process that exposes plugin tools to Codex.
- In this reproduction, every subagent started two Node.js MCP servers: one for the OpenAI Developers plugin and one for the Data Analytics plugin.
- Three completed subagents therefore left six extra Node.js processes running.
- These were not independent user programs. Their parent was the main native Codex CLI process, and their start times matched the three subagent starts.
This is a plain interactive CLI reproduction. There was no Codex IDE integration or codex app-server in the affected process tree.
Environment
- Codex:
codex-cli 0.147.0
- Surface: interactive terminal CLI
- OS: Rocky Linux 8.10
- Kernel:
4.18.0-553.126.1.el8_10.x86_64
- Architecture:
x86_64
- Runtime: Slurm interactive allocation on a multi-user HPC cluster
- Multi-agent support: enabled
- Bundled plugin MCP servers involved:
openai-developers 1.2.3: node ./mcp/server.mjs
data-analytics 0.2.8-13ceeea1f599: node ./mcp/server.cjs --stdio
- The only user-configured top-level MCP server was remote HTTP; the leaking processes were bundled plugin MCP servers.
What happened
The main Codex session started at 18:07:19 UTC. Its normal baseline included one OpenAI Developers MCP process and one Data Analytics MCP process.
Three subagents started within ten seconds:
| Subagent start |
OpenAI Developers MCP |
Data Analytics MCP |
| 18:26:25 UTC |
PID 4017219 |
PID 4017220 |
| 18:26:30 UTC |
PID 4017259 |
PID 4017258 |
| 18:26:35 UTC |
PID 4017405 |
PID 4017406 |
The subagents returned completed results between 18:28:52 and 18:33:35 UTC. Codex's agent list showed all three as completed.
At 18:56:24 UTC, roughly 23 to 28 minutes after their last completed results, all six MCP processes were still alive:
PID PPID START ELAPSED STATE COMMAND
4017219 4007696 18:26:25 30:00 Sl node ./mcp/server.mjs
4017220 4007696 18:26:25 30:00 Sl node ./mcp/server.cjs --stdio
4017258 4007696 18:26:30 29:55 Sl node ./mcp/server.cjs --stdio
4017259 4007696 18:26:30 29:55 Sl node ./mcp/server.mjs
4017405 4007696 18:26:35 29:50 Sl node ./mcp/server.mjs
4017406 4007696 18:26:35 29:50 Sl node ./mcp/server.cjs --stdio
All six were direct children of the same live native Codex process, PID 4007696. Each helper also had its own process group.
The main session's expected baseline pair was separate:
4007811 4007696 node ./mcp/server.mjs
4007812 4007696 node ./mcp/server.cjs --stdio
Working directories confirmed the identity of every process:
server.mjs -> $CODEX_HOME/plugins/cache/openai-curated-remote/openai-developers/1.2.3
server.cjs -> $CODEX_HOME/plugins/cache/openai-curated-remote/data-analytics/0.2.8-13ceeea1f599
Two completed subagents were given a later follow-up turn. They reused their existing helper pair rather than starting another pair. After the follow-up completed, the pair still remained alive. The third subagent received no follow-up and its pair also remained alive.
The CLI surface in this session exposed spawn, follow-up, interrupt, list, and wait controls, but no close/dispose control for completed subagent threads.
Controlled cleanup
I sent SIGTERM only to the six processes associated with the three completed subagents:
kill -TERM 4017219 4017220 4017258 4017259 4017405 4017406
All six exited immediately. No SIGKILL was required.
A process-tree check seven seconds later showed:
- the main Codex CLI was still running;
- the main session's original two plugin MCP servers were still running;
- all six completed-subagent MCP servers were gone;
- the interactive session continued to work;
- the three agents still appeared as
completed in the agent list.
This isolates the extra six processes from the main session's required helper processes.
Reproduction steps
- Start
codex in an interactive Linux terminal with multi-agent support and bundled plugin MCP tools available.
- Record the native Codex PID and its baseline children:
ps -u "$USER" -o pid,ppid,lstart,etime,stat,args --forest
- Ask Codex to spawn three parallel subagents for bounded tasks.
- Wait until all three subagents return their final result and appear as
completed.
- Wait several minutes.
- Record the same process tree again.
- Resolve each
node ./mcp/server.mjs and node ./mcp/server.cjs --stdio process's working directory through /proc/<pid>/cwd.
- Observe one OpenAI Developers and one Data Analytics MCP process for each completed subagent, in addition to the main session's baseline pair.
Expected behavior
When a subagent finishes, Codex should do one of the following:
- terminate and reap that subagent's MCP child processes;
- share a bounded MCP process pool with the parent session; or
- stop the helpers after completion and restart them only if the subagent is resumed.
A completed subagent should not permanently add plugin processes to a long-running CLI session.
If retaining resources until explicit thread disposal is intentional, the CLI and agent API need an available close/dispose operation, and completed agents should not be presented as fully finished while their process resources remain allocated.
Actual behavior
Every subagent adds two plugin MCP processes. The processes remain alive after the subagent is marked completed, so process count grows linearly with the number of subagents used during a long CLI session.
These processes are not Unix orphans because the main Codex process remains their parent. That also means the operating system will not independently reap them while Codex stays open.
Impact
This is particularly harmful on multi-user Linux and HPC systems:
- long-running Codex sessions accumulate idle processes;
- repeated parallel-agent work can exhaust per-user process limits;
- leaked processes consume cluster resources after their work is finished;
- when Codex is run directly on a shared login node, the accumulation can degrade that shared node;
- users currently have to identify and kill only the stale plugin children or restart Codex.
Suggested fix
Tie each plugin MCP client to the owning subagent lifecycle and await complete child-process termination when the subagent completes or is disposed.
A bounded shared MCP pool would also solve the multiplication. If completed subagent threads must remain resumable, release their MCP processes while idle and initialize them again on resume.
It would also help if Codex diagnostics reported:
- owning parent thread/subagent for each MCP process;
- whether that owner is active, completed, or closed;
- MCP PID and uptime;
- an explicit command to dispose completed agent resources.
Related issues
This report is separate because it confirms the defect in the plain interactive Linux CLI on current 0.147.0, with bundled plugin MCPs, exact one-pair-per-subagent timing, and a controlled cleanup that left the parent CLI operational.
Summary
The interactive Codex CLI starts a separate pair of bundled plugin helper processes for every subagent. When the subagent reports completion, those helper processes remain alive under the main Codex process.
For someone unfamiliar with these terms:
This is a plain interactive CLI reproduction. There was no Codex IDE integration or
codex app-serverin the affected process tree.Environment
codex-cli 0.147.04.18.0-553.126.1.el8_10.x86_64x86_64openai-developers 1.2.3:node ./mcp/server.mjsdata-analytics 0.2.8-13ceeea1f599:node ./mcp/server.cjs --stdioWhat happened
The main Codex session started at 18:07:19 UTC. Its normal baseline included one OpenAI Developers MCP process and one Data Analytics MCP process.
Three subagents started within ten seconds:
The subagents returned completed results between 18:28:52 and 18:33:35 UTC. Codex's agent list showed all three as
completed.At 18:56:24 UTC, roughly 23 to 28 minutes after their last completed results, all six MCP processes were still alive:
All six were direct children of the same live native Codex process, PID 4007696. Each helper also had its own process group.
The main session's expected baseline pair was separate:
Working directories confirmed the identity of every process:
Two completed subagents were given a later follow-up turn. They reused their existing helper pair rather than starting another pair. After the follow-up completed, the pair still remained alive. The third subagent received no follow-up and its pair also remained alive.
The CLI surface in this session exposed spawn, follow-up, interrupt, list, and wait controls, but no close/dispose control for completed subagent threads.
Controlled cleanup
I sent
SIGTERMonly to the six processes associated with the three completed subagents:All six exited immediately. No
SIGKILLwas required.A process-tree check seven seconds later showed:
completedin the agent list.This isolates the extra six processes from the main session's required helper processes.
Reproduction steps
codexin an interactive Linux terminal with multi-agent support and bundled plugin MCP tools available.ps -u "$USER" -o pid,ppid,lstart,etime,stat,args --forestcompleted.node ./mcp/server.mjsandnode ./mcp/server.cjs --stdioprocess's working directory through/proc/<pid>/cwd.Expected behavior
When a subagent finishes, Codex should do one of the following:
A completed subagent should not permanently add plugin processes to a long-running CLI session.
If retaining resources until explicit thread disposal is intentional, the CLI and agent API need an available close/dispose operation, and completed agents should not be presented as fully finished while their process resources remain allocated.
Actual behavior
Every subagent adds two plugin MCP processes. The processes remain alive after the subagent is marked completed, so process count grows linearly with the number of subagents used during a long CLI session.
These processes are not Unix orphans because the main Codex process remains their parent. That also means the operating system will not independently reap them while Codex stays open.
Impact
This is particularly harmful on multi-user Linux and HPC systems:
Suggested fix
Tie each plugin MCP client to the owning subagent lifecycle and await complete child-process termination when the subagent completes or is disposed.
A bounded shared MCP pool would also solve the multiplication. If completed subagent threads must remain resumable, release their MCP processes while idle and initialize them again on resume.
It would also help if Codex diagnostics reported:
Related issues
This report is separate because it confirms the defect in the plain interactive Linux CLI on current
0.147.0, with bundled plugin MCPs, exact one-pair-per-subagent timing, and a controlled cleanup that left the parent CLI operational.