Disabled plugin's cached MCP server still starts and hangs TUI startup indefinitely (openai-developers / openai-api-key-local-confirmation, no MCP startup timeout)

Resolved 💬 2 comments Opened Jul 20, 2026 by jakobtfaber Closed Jul 20, 2026

Summary

A fresh Codex TUI session (v0.144.6, macOS) stalled indefinitely (observed 14+ minutes, no timeout, Escape did not skip) at:

Starting MCP servers (17/18): openai-api-key-local-confirmation

That MCP server is not defined in ~/.codex/config.toml — it ships inside the openai-developers plugin (.mcp.json declares openai-api-key-local-confirmationnode ./mcp/server.mjs, cwd: "."). The plugin was disabled ([plugins."openai-developers@openai-curated"] enabled = false, and codex plugin list agreed: "installed, disabled"), yet Codex started the plugin's MCP server anyway.

Root cause chain (as diagnosed locally)

  1. Disabled flag and load path referenced different copies. Two cached copies of the plugin existed under different marketplace identities: ~/.codex/plugins/cache/openai-curated/openai-developers/<hash 11c74d6b> and ~/.codex/plugins/cache/openai-curated-remote/openai-developers/1.2.3. The enabled = false key (@openai-curated) did not cover the openai-curated-remote copy, whose .mcp.json was still loaded at session start.
  2. Registry pointed at a temp staging path. codex plugin list showed the install path as ~/.codex/.tmp/plugins/plugins/openai-developers — a half-finished remote install (the .tmp/plugins tree contained a full ~180-plugin marketplace mirror, 77 MB, plus a .codex-remote-plugin-install.json marker and a stray .tmpwIcWm7 file). This left the remote-cache copy loadable outside the enable/disable bookkeeping.
  3. Why it hangs rather than errors: server.mjs is a normal stdio JSON-RPC server and answers initialize fine when actually running. But the plugin's .mcp.json uses cwd: "." with a relative script path (node ./mcp/server.mjs). Launched via the stale cache identity, the relative path apparently resolves against the wrong cwd → node exits immediately (module not found) → Codex waits forever for an initialize response. There is evidently no per-server MCP startup timeout and no detection of a dead child process at this stage, and no way to skip from the TUI.

Bugs to fix

  1. A disabled plugin's cached .mcp.json servers should never start — plugin enable/disable should be enforced across all marketplace identities / cache copies, and a registry entry pointing into .tmp staging should be treated as invalid.
  2. MCP startup needs a per-server timeout (and/or child-exit detection) with a visible skip path; a single unresponsive server currently blocks the whole session and queued input indefinitely.
  3. Interrupted plugin installs should clean up ~/.codex/.tmp/plugins staging rather than leaving a loadable orphan that the registry points at.

Workarounds that worked

  • Explicit by-name gate in config.toml:

``toml
[mcp_servers.openai-api-key-local-confirmation]
command = "node"
args = ["./mcp/server.mjs"]
enabled = false
`
→ sessions start in seconds, headless
codex exec` clean.

  • Permanent fix: codex plugin remove openai-developers@openai-curated + purging the orphaned .tmp/plugins staging tree and the openai-curated-remote cache copy. After that the gate is unnecessary.

Environment

  • Codex CLI v0.144.6, macOS (arm64, macOS 27.0 beta)
  • Plugin: openai-developers 1.2.3 (openai-curated / openai-curated-remote)

View original on GitHub ↗

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