openai / openai/codex

[Windows Desktop 26.810.7004] Thread-scoped STDIO MCP processes and local-proxy CLOSE_WAIT sockets accumulate

Open
#38,981 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

app app-server bug connectivity mcp performance windows-os
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

What version of the Codex App are you using?

ChatGPT/Codex Desktop 26.810.7004.0 (x64)

Platform

Windows 11 Pro, version 10.0.26200 (build 26200)

Summary

During normal use of Codex Desktop with several global local STDIO MCP servers, two forms of resource accumulation occur in the same app-server lifetime:

  1. A new set of local STDIO MCP process trees is started for many threads/tasks and old sets remain alive.
  2. The Codex app-server accumulates both established and CLOSE_WAIT TCP sockets to a local HTTP proxy.

The socket owner is the Codex app-server itself, not any individual MCP server. The two symptoms are correlated in the same long-lived Desktop session, but I have not established that MCP initialization causes the socket accumulation.

This report adds current Windows Desktop 26.810.7004.0 evidence and local-proxy socket ownership to the existing MCP lifecycle reports.

Configuration

Representative global local STDIO MCP servers:

  • CodeGraph: codegraph serve --mcp
  • Semble: semble.exe (stdio MCP mode)
  • FastCtx: fastctx.exe serve
  • Codex node_repl

HTTPS traffic is routed through a local proxy at 127.0.0.1:10888. The specific port should not be material; it is included to make the socket evidence reproducible.

Observed behavior

After continued normal use in one Desktop app-server lifetime:

Direct child/runtime Count
CodeGraph launchers 32
Semble launchers 32
FastCtx servers 31
node_repl 32

Including launcher and backend descendants:

Process family Processes Approx. working set
CodeGraph-related 117 5,277 MB
Semble-related 96 5,000 MB
FastCtx-related 31 1,317 MB
Other app-server descendants 49 1,265 MB
Codex app-server 1 442 MB

At the same time, the Codex app-server owned these connections to the local proxy:

State Count
ESTABLISHED 36
CLOSE_WAIT 39

An earlier sample from the previous app-server lifetime showed approximately 39 repeated MCP runtime sets and 46 established plus 51 CLOSE_WAIT connections to the same local proxy.

Fully restarting Codex removes the old process tree and sockets, but both counts grow again as threads are opened, resumed, or used.

Network ownership checks showed:

  • Connections to 127.0.0.1:10888 were owned by codex.exe app-server.
  • Semble held only loopback connections used by its own local process hierarchy.
  • CodeGraph and FastCtx did not own the accumulated proxy connections.
Steps to reproduce
  1. On Windows, configure multiple global local STDIO MCP servers.
  2. Configure Codex traffic to use a local HTTP proxy.
  3. Fully start Codex Desktop.
  4. Open, resume, or switch among multiple local tasks over time.
  5. Let completed or idle tasks remain in the task list.
  6. Inspect direct and indirect descendants of the Desktop app-server.
  7. Inspect TCP state for the app-server PID.

Example PowerShell checks:

$appServer = Get-CimInstance Win32_Process |
  Where-Object {
    $_.Name -eq 'codex.exe' -and
    $_.CommandLine -match 'app-server'
  } |
  Select-Object -First 1

Get-CimInstance Win32_Process |
  Where-Object ParentProcessId -eq $appServer.ProcessId |
  Group-Object CommandLine |
  Sort-Object Count -Descending |
  Select-Object Count, Name

Get-NetTCPConnection -OwningProcess $appServer.ProcessId |
  Where-Object {
    $_.RemoteAddress -eq '127.0.0.1' -and
    $_.RemotePort -eq 10888
  } |
  Group-Object State |
  Select-Object Count, Name
Expected behavior
  • MCP subprocess trees belonging to completed, closed, unloaded, or expired thread runtimes should be terminated.
  • Alternatively, compatible local MCP servers should be shared or pooled with a bounded lifetime across threads.
  • Half-closed proxy sockets should be closed promptly by the app-server instead of accumulating in CLOSE_WAIT.
  • Long-running Desktop use should have bounded process, memory, and socket counts.
Actual behavior
  • Each new/resumed thread appears to initialize another full set of local STDIO MCP servers.
  • Many old MCP process groups remain attached to the app-server.
  • Memory consumption grows into multiple gigabytes.
  • The app-server accumulates dozens of half-closed proxy sockets.
  • Restarting Codex is the practical temporary cleanup.
Suggested areas to investigate
  • Thread/session MCP manager disposal after completion, archive, unload, or idle timeout.
  • A supported shared / reuse / idle_timeout mode for compatible local MCP servers.
  • App-server HTTP connection-pool handling when a proxied peer has sent FIN.
  • Whether resumed/background threads retain both MCP runtimes and outbound HTTP clients longer than intended.
Related issues
  • #30408 — per-thread MCP processes never cleaned up
  • #33946 — multiple tasks duplicate MCP processes on Windows
  • #34658 — completed subagents leave STDIO MCP processes running
  • #38526 — current Windows Desktop local STDIO MCP process accumulation
  • #31376 — separate CLOSE_WAIT / pooled connection hang evidence in codex exec

The MCP process accumulation overlaps with those reports. The additional observation here is that, on current Windows Desktop, the app-server simultaneously accumulates local-proxy CLOSE_WAIT sockets, and those sockets are not owned by the MCP child processes.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the Windows Desktop behavior with the provided PowerShell process and TCP-state checks. Read the related issues, then trace the app-server's thread/session MCP manager disposal and HTTP connection-pool handling for proxied peers. Done means completed or idle runtimes and half-closed proxy sockets are cleaned up, with bounded process, memory, and socket counts during continued use.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
backend, networking
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.