Codex app-server retains stdio MCP process pairs after task/thread teardown on 0.145.0-alpha.18
Environment
- macOS 26.5.2 (25F84), arm64
- ChatGPT desktop app 26.715.52143 (build 5591)
- Embedded
codex-cli 0.145.0-alpha.18 - One local stdio MCP server launched through
uvx agents.max_threads = 12,agents.max_depth = 1
What happened
During normal Codex desktop usage, local stdio MCP launcher/server pairs accumulated beneath the long-lived codex app-server.
Two credential-redacted snapshots:
- Around 16:40 local: 150 matching processes (75 launcher/server pairs)
- At 16:45 local: 170 matching processes (85 complete pairs)
- 75 pairs / 150 processes were descendants of the same still-running
codex app-server - 10 pairs / 20 processes belonged to other live Codex workers
- every launcher had one server child
- none were zombies or PPID-1 orphans
The process ages spanned minutes to hours, consistent with steady per-task/per-thread accumulation rather than one burst.
A targeted SIGTERM of only the matching MCP launcher/server processes reduced the count from 170 to 2 while leaving the app-server alive. One fresh launcher/server pair respawned immediately for the active task and remained stable, so the MCP server itself can restart cleanly; the issue is retention of prior instances.
Log evidence
I queried the local Codex SQLite log DB read-only over a fixed pre-investigation window and sanitized all bodies/arguments.
For this MCP server in that window:
- 37 successful
service initializedevents across 20 thread IDs - 16
child exitedevents across 11 thread IDs - all 16 exits were status 143 (SIGTERM) and paired with cancellation logs
- net recorded imbalance: +21 initializations without a matching exit in the window
- 11 thread IDs had initialization without an exit
The logs have no child PID/connection ID, so they cannot prove a 1:1 mapping to the live processes, but the lifecycle imbalance is consistent with the process-tree evidence.
Expected behavior
When a Codex task/thread/session is completed or torn down, its owned stdio MCP process group should terminate and be reaped. Normal use should converge to the active-session baseline rather than grow indefinitely.
Actual behavior
Complete, sleeping stdio MCP launcher/server pairs remain parented beneath the live app-server and accumulate over time.
Reproduction
I have not yet isolated a one-thread deterministic minimal repro. This occurred during normal desktop use with multiple tasks and subagents:
- Configure a local stdio MCP server.
- Use Codex desktop across multiple tasks/subagents for several hours.
- Count matching descendants without printing command arguments.
- Observe many old, complete launcher/server pairs retained beneath the live app-server.
Related upstream work
- #12491 tracks the broader Codex.app MCP child lifecycle bug; a maintainer requested new reports for current-version recurrences.
- #19845 describes duplicate stdio MCP processes retained beneath a live app-server and was closed as a duplicate of #12491.
- #19753 added explicit RMCP shutdown/manager draining and stdio process-group termination before the version reproduced here.
This looks like a remaining app-server session/thread teardown path after #19753, not a timeout configuration issue. The current config reference exposes startup/tool timeouts but no shared/persistent stdio process scope or lifecycle/reap setting.
I can provide additional sanitized queries or perform a bounded open/close-thread repro if maintainers identify the most useful lifecycle event to isolate. No MCP account identifiers, paths, command arguments, environment values, or credentials are included here.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗