Codex app-server retains stdio MCP process pairs after task/thread teardown on 0.145.0-alpha.18

Resolved 💬 2 comments Opened Jul 20, 2026 by m-brady Closed Jul 20, 2026

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 initialized events across 20 thread IDs
  • 16 child exited events 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:

  1. Configure a local stdio MCP server.
  2. Use Codex desktop across multiple tasks/subagents for several hours.
  3. Count matching descendants without printing command arguments.
  4. 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.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗