What version of Codex CLI is running?
codex-cli 0.121.0
What subscription do you have?
Enterprise
Which model were you using?
gpt-5.4
What platform is your computer?
Darwin 25.4.0 arm64 arm
What terminal emulator and version are you using (if applicable)?
Ghostty, Terminal.app
What issue are you seeing?
On macOS, starting Codex with a stdio MCP server can result in terminal job-control failure during startup, observed as zsh: suspended (tty input).
After tracing this locally, the issue appears to be in how stdio MCP child processes are spawned: they are moved into a separate process group, but remain attached to the controlling terminal session. If anything in that server process tree touches
the terminal, the shell can suspend it as a background TTY reader.
What steps can reproduce the bug?
Environment
- Platform: macOS
- Shell: zsh
- Codex CLI: codex-cli 0.121.0
- MCP transport:
stdio
- Example server that exposed the issue:
npx -y @blitzdev/iphone-mcp
- Configure a
stdio MCP server, for example:
[mcp_servers.blitz-iphone]
command = "npx"
args = ["-y", "@blitzdev/iphone-mcp"]
- Start interactive Codex normally.
- During MCP startup, Codex may get suspended by the shell with:
zsh: suspended (tty input) codex ...
What is the expected behavior?
Expected behavior
Codex should be able to start stdio MCP servers without exposing them to terminal job-control interactions.
stdio MCP children are pipe-based helpers and should not depend on or inherit a controlling TTY.
Actual behavior
A stdio MCP child can remain in the terminal session while being placed in a separate process group. That creates a job-control hazard on macOS/zsh if the child process tree performs terminal I/O.
The visible user symptom is shell suspension during Codex startup rather than a clean MCP startup or a clean MCP failure.
Additional information
Impact
- Interactive Codex startup can fail when specific stdio MCP servers are enabled.
- The failure is confusing because it appears shell-related or MCP-specific rather than a Codex process-launch issue.
- Optional MCP tools may silently disappear if users work around this by disabling servers.
- Required MCP servers can block the entire session.
Why this seems like a Codex-side issue
From inspection, Codex already treats stdio MCP servers as non-interactive, pipe-based children. There is also already precedent in the codebase for detaching non-interactive child processes from the controlling TTY before exec. The risky behavior appears to be specific to the stdio MCP spawn path rather than a general requirement of MCP servers.
Proposed fix
In the stdio MCP spawn path, detach the child from the controlling TTY/session before exec rather than only assigning a new process group.
That makes the child behave like a normal non-interactive helper process and avoids terminal job-control suspension.
I have a candidate implementation plus a regression test in my fork:
https://github.com/spqw/codex/pull/1
Validation
Locally, the candidate fix:
- detaches stdio MCP children from the controlling TTY
- preserves normal pipe-based stdio operation
- passes crate tests including a focused regression test for detached-session behavior
Additional info
I’m happy to reshape the PR if you’d prefer this handled in a different layer, but I wanted to open the issue first since docs/contributing.md suggests discussing behavior changes before expecting a PR review.
What version of Codex CLI is running?
codex-cli 0.121.0
What subscription do you have?
Enterprise
Which model were you using?
gpt-5.4
What platform is your computer?
Darwin 25.4.0 arm64 arm
What terminal emulator and version are you using (if applicable)?
Ghostty, Terminal.app
What issue are you seeing?
On macOS, starting Codex with a
stdioMCP server can result in terminal job-control failure during startup, observed aszsh: suspended (tty input).After tracing this locally, the issue appears to be in how
stdioMCP child processes are spawned: they are moved into a separate process group, but remain attached to the controlling terminal session. If anything in that server process tree touchesthe terminal, the shell can suspend it as a background TTY reader.
What steps can reproduce the bug?
Environment
stdionpx -y @blitzdev/iphone-mcpstdioMCP server, for example:What is the expected behavior?
Expected behavior
Codex should be able to start stdio MCP servers without exposing them to terminal job-control interactions.
stdio MCP children are pipe-based helpers and should not depend on or inherit a controlling TTY.
Actual behavior
A stdio MCP child can remain in the terminal session while being placed in a separate process group. That creates a job-control hazard on macOS/zsh if the child process tree performs terminal I/O.
The visible user symptom is shell suspension during Codex startup rather than a clean MCP startup or a clean MCP failure.
Additional information
Impact
Why this seems like a Codex-side issue
From inspection, Codex already treats stdio MCP servers as non-interactive, pipe-based children. There is also already precedent in the codebase for detaching non-interactive child processes from the controlling TTY before exec. The risky behavior appears to be specific to the stdio MCP spawn path rather than a general requirement of MCP servers.
Proposed fix
In the stdio MCP spawn path, detach the child from the controlling TTY/session before exec rather than only assigning a new process group.
That makes the child behave like a normal non-interactive helper process and avoids terminal job-control suspension.
I have a candidate implementation plus a regression test in my fork:
https://github.com/spqw/codex/pull/1
Validation
Locally, the candidate fix:
Additional info
I’m happy to reshape the PR if you’d prefer this handled in a different layer, but I wanted to open the issue first since
docs/contributing.mdsuggests discussing behavior changes before expecting a PR review.