[Windows][Codex Replay 1.0.128] MCP crashes at startup on POSIX-only `fcntl` import
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
Summary
The OpenAI-curated codex-replay plugin release 1.0.128 is installed and offered by Codex Desktop on Windows, but its MCP server cannot start on Windows because mcp/server.py unconditionally imports the POSIX-only Python module fcntl.
Codex Desktop therefore reports a generic MCP handshake failure on every thread where the plugin is initialized. Running the packaged server directly reproduces the underlying exception immediately.
This appears to need either a Windows-compatible implementation or an explicit platform/capability gate so the MCP is not launched on unsupported hosts.
Environment
- OS: Windows 11 x64, build 26200
- Codex Desktop package:
26.901.5003.0 - Desktop-managed Codex runtime:
codex-cli 0.153.3 - Curated plugin:
codex-replay 1.0.128 - Python selected by the plugin's
python3command: Windows CPython
Desktop symptom
Across multiple ordinary local threads, the app-server repeatedly reports:
server=codex-replay status=starting
MCP client for `codex-replay` failed to start: MCP startup failed:
handshaking with MCP server failed: connection closed: initialize response
server=codex-replay status=failed
The failure occurs before any Codex Replay tool is invoked.
Direct reproduction
From the installed plugin root, run the exact MCP command declared in .mcp.json:
python3 ./mcp/server.py
Actual result:
Traceback (most recent call last):
File ".../codex-replay/1.0.128/mcp/server.py", line 5, in <module>
import fcntl
ModuleNotFoundError: No module named 'fcntl'
The process exits immediately, which explains the app-server's connection closed: initialize response error.
Packaged definition
The plugin declares:
{
"mcpServers": {
"codex-replay": {
"command": "python3",
"args": ["./mcp/server.py"],
"cwd": "."
}
}
}
mcp/server.py begins with an unconditional:
import fcntl
Additional Windows blockers in the same server
A conditional fcntl import alone does not appear sufficient for Windows support. The same packaged server also relies on POSIX-specific or POSIX-oriented lifecycle primitives, including:
fcntl.flock(...)
os.killpg(...)
os.getpgrp()
signal.SIGTERM
signal.SIGKILL
subprocess.Popen(..., start_new_session=True, pass_fds=(...))
Examples include:
_state_guard()and_historical_review_guard()usingfcntl.flockfor cross-process state locks._terminate_process_group()usingos.killpgand POSIX signals.- controller launch passing a reserved socket FD to a child with
pass_fds. - coordinator cancellation comparing against
os.getpgrp()and signaling the process group.
The existing tests contain Windows-path redaction coverage, but I could not find equivalent Windows platform coverage for these MCP lifecycle paths.
Expected behavior
One of the following should hold:
codex-replaysupports Windows and uses Windows-compatible locking, child-process lifecycle, and controller/socket handoff; or- the plugin manifest / Codex plugin loader marks the MCP unsupported on Windows and does not launch it.
In either case, opening an unrelated Windows thread should not spawn an MCP process that deterministically crashes before initialize.
Suggested fix areas
- Add a platform/capability gate if Codex Replay is currently macOS/Linux-only.
- If Windows is intended to be supported:
- replace or abstract
fcntl.flockwith a cross-platform file-lock mechanism; - use a Windows-safe process-tree lifecycle rather than
killpg/POSIX process groups; - replace inherited-FD controller socket handoff with a Windows-supported mechanism;
- add Windows CI covering MCP initialize, controller startup, cancellation, and state locking.
- replace or abstract
- Surface the server's stderr/root exception in plugin diagnostics so this is not reduced to a generic handshake error.
Privacy
Local usernames, absolute project paths, account details, thread IDs, credentials, prompts, and private session data are intentionally omitted.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running python3 ./mcp/server.py from the plugin root and inspect mcp/server.py, especially _state_guard(), _historical_review_guard(), _terminate_process_group(), coordinator cancellation, and controller launch. Review .mcp.json and the existing Windows-path redaction tests; done means Windows either completes MCP initialization with lifecycle and locking coverage, or the loader prevents unsupported startup without a generic handshake failure.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- cli, devtools
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100