Summary
Codex CLI appears to eagerly start configured MCP servers for every session/resume, even when the tools are not used. This creates a noisy lifecycle problem for headed browser MCP servers: each long-lived Codex session keeps its own visible browser/tool server processes alive.
This is most visible on macOS when a Python-based headed MCP server is configured globally, because every Codex session shows another Python app in the Dock.
Example Configuration
A global MCP setup with headed browser tools such as:
[mcp_servers.browser-use]
command = "browser-use"
args = ["--headed", "--profile", "Default", "--mcp"]
[mcp_servers.browser-use-cdp]
command = "browser-use"
args = ["--headed", "--cdp-url", "http://127.0.0.1:9222", "--mcp"]
Starting or resuming multiple Codex sessions results in each Codex process owning its own MCP child processes, for example:
codex resume ...
browser-use --headed --profile Default --mcp
browser-use --headed --cdp-url http://127.0.0.1:9222 --mcp
npm exec @playwright/mcp@latest --browser=chrome
Expected Behavior
One of these would avoid the accumulation:
- Lazy-start MCP servers only when a tool from that server is first used.
- Add a config option to mark MCP servers as lazy/on-demand vs eager.
- Avoid auto-starting headed/browser MCP servers until needed.
- Clearly shut down unused MCP servers after an idle timeout.
Actual Behavior
Each Codex session starts the configured MCP server processes and keeps them alive for the lifetime of that Codex session. If several old sessions remain open, the user sees many headed MCP processes, even if none of those sessions are actively using browser tooling.
The child processes are not necessarily orphaned: their parent is still the live Codex session. So this is not always a process leak in the OS sense. The problem is eager startup and session-lifetime retention of GUI-capable MCP tools.
Collision Notes
This does not appear to be primarily a Chrome profile or CDP port collision with current browser-use behavior:
browser-use --profile Default copies the Chrome profile into a temporary user data directory before launch.
- The local browser launcher chooses a free remote debugging port.
- A
browser_close_all style tool can close active browser sessions, but it does not necessarily terminate the MCP server process while Codex keeps that server connected.
So the confusing user-visible failure mode is many Dock/process-list entries, not necessarily profile corruption.
Why This Matters
Headed MCP browser tools are useful for auth-heavy/operator flows where isolated Playwright tests are the wrong model. But when configured globally, eager startup makes normal Codex usage feel like it is spawning unexplained GUI apps.
A lazy MCP lifecycle would make global browser-tool configuration much safer and less surprising.
Summary
Codex CLI appears to eagerly start configured MCP servers for every session/resume, even when the tools are not used. This creates a noisy lifecycle problem for headed browser MCP servers: each long-lived Codex session keeps its own visible browser/tool server processes alive.
This is most visible on macOS when a Python-based headed MCP server is configured globally, because every Codex session shows another Python app in the Dock.
Example Configuration
A global MCP setup with headed browser tools such as:
Starting or resuming multiple Codex sessions results in each Codex process owning its own MCP child processes, for example:
Expected Behavior
One of these would avoid the accumulation:
Actual Behavior
Each Codex session starts the configured MCP server processes and keeps them alive for the lifetime of that Codex session. If several old sessions remain open, the user sees many headed MCP processes, even if none of those sessions are actively using browser tooling.
The child processes are not necessarily orphaned: their parent is still the live Codex session. So this is not always a process leak in the OS sense. The problem is eager startup and session-lifetime retention of GUI-capable MCP tools.
Collision Notes
This does not appear to be primarily a Chrome profile or CDP port collision with current
browser-usebehavior:browser-use --profile Defaultcopies the Chrome profile into a temporary user data directory before launch.browser_close_allstyle tool can close active browser sessions, but it does not necessarily terminate the MCP server process while Codex keeps that server connected.So the confusing user-visible failure mode is many Dock/process-list entries, not necessarily profile corruption.
Why This Matters
Headed MCP browser tools are useful for auth-heavy/operator flows where isolated Playwright tests are the wrong model. But when configured globally, eager startup makes normal Codex usage feel like it is spawning unexplained GUI apps.
A lazy MCP lifecycle would make global browser-tool configuration much safer and less surprising.