Codex CLI: MCP startup/tool discovery can block first turn when many MCP servers are configured
Problem
When many MCP servers are configured, Codex can become slow or appear stuck during startup or before the first turn. This is especially noticeable when some MCP servers are slow, unauthenticated, unreachable, or expensive to start.
The core issue appears to be that Codex treats MCP startup and tool discovery as part of the startup/first-turn critical path. As a result, optional MCP servers can delay the user from interacting with the TUI or sending the first prompt.
Expected behavior
Codex should remain responsive immediately after launch.
Optional MCP servers should connect and discover tools in the background. The first turn should proceed with currently available tools, and additional MCP tools should become available incrementally as servers finish initialization.
Only explicitly required MCP servers should be allowed to block startup or the first turn.
Actual behavior
With many MCP servers configured:
- The TUI can show MCP startup as an active task.
- Slash commands may be unavailable while MCP startup is still running.
- The first turn can wait for MCP tool discovery.
- Slow or broken optional MCP servers can delay the whole experience until timeout.
- Starting many stdio MCP servers at once can cause resource contention.
Relevant code paths
From reading the current implementation, the likely blocking paths are:
codex-rs/core/src/session/session.rs- Creates
McpConnectionManagerduring session setup.
codex-rs/codex-mcp/src/connection_manager.rs- Starts all enabled MCP servers concurrently.
list_all_tools()awaits listed tools from all clients.
codex-rs/codex-mcp/src/rmcp_client.rs- Server initialization uses the startup timeout.
tools/listappears to be performed as part of startup readiness.listed_tools()may wait for the client to finish initialization when no startup snapshot is available.
codex-rs/core/src/session/turn.rsbuilt_tools()awaitsmcp_connection_manager.list_all_tools()while building tools for the turn.
codex-rs/tui/src/chatwidget.rscodex-rs/tui/src/chatwidget/mcp_startup.rs- MCP startup is surfaced as a running task in the TUI.
Why this matters
MCP usage tends to grow over time. A user may have many configured MCP servers, but only need a small subset for any given session or first prompt.
If optional MCP servers block startup or first-turn tool construction, then one slow or unhealthy server can degrade the entire Codex experience.
Suggested direction
Consider making MCP startup and tool discovery more incremental:
- Do not await all optional MCP servers before the first turn.
- Let
built_tools()use only currently ready MCP tools. - Keep pending MCP servers in a background state and refresh the tool inventory as they become ready.
- Separate MCP
initializereadiness fromtools/list, or maketools/listlazy/background. - Add bounded startup concurrency, especially for local stdio MCP servers.
- Treat MCP startup as background status in the TUI unless a server is explicitly marked as required.
- Keep the current blocking behavior only for required MCP servers.
A comparable design would be: launch the TUI immediately, allow the first prompt to run with built-in tools plus already-ready MCP tools, and make remaining MCP tools appear in later turns as servers finish connecting.
Reproduction idea
- Configure 10-30 MCP servers.
- Include a few slow, broken, unauthenticated, or unreachable servers.
- Start Codex TUI.
- Try to immediately run a slash command or submit the first prompt.
- Observe whether the UI or first turn waits for MCP startup/tool discovery to settle.
Root cause hypothesis
The most likely root cause is that Codex currently models MCP as an eager global tool inventory that must be known before tool construction, instead of an eventually available background capability.
This makes optional MCP servers part of the critical path for startup or the first turn.
3 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
These are two separate issues. Please keep this issue open so both can be fully discussed.
Adding a concrete real-world data point from Codex Desktop on macOS (local
codex-cli 0.144.5).The project config has 6 MCP servers, with 3 additional MCP servers in the user-level Codex config. A direct concurrent
initialize+tools/listprobe for the 6 project servers measured:| Server | Time | Result |
|---|---:|---|
| project graph | 1.78s | 17 tools |
| sister graph | 1.81s | 11 tools |
| GitHub | 4.58s | 26 tools |
| Datadog | 4.71s | 23 tools |
| ConfigCat | 4.71s | 79 tools |
| Grafana (VPN-only endpoint unavailable) | 5.03s | connection failure |
The enabled project servers expose at least 156 tools. They already initialize concurrently, but Codex still appears stuck after the first message while waiting for the aggregated tool inventory. The same project feels substantially faster in Claude Code.
The preferred product behavior would be:
required = trueservers.Timeout tuning and locally pinning
npxpackages can reduce the delay, but they cannot solve the core issue: optional tools that are not needed for a given conversation still block the first interaction.