Skip to content

fix(windows): pass stdin=DEVNULL to git/svn subprocesses to prevent MCP hang (closes #401)#425

Open
dannymn wants to merge 1 commit intotirth8205:mainfrom
dannymn:fix/windows-mcp-stdin-hang
Open

fix(windows): pass stdin=DEVNULL to git/svn subprocesses to prevent MCP hang (closes #401)#425
dannymn wants to merge 1 commit intotirth8205:mainfrom
dannymn:fix/windows-mcp-stdin-hang

Conversation

@dannymn
Copy link
Copy Markdown

@dannymn dannymn commented May 3, 2026

Closes #401

Problem

On Windows, when CRG runs as an MCP server (stdio transport, e.g. via Claude Code or Cursor), the git/svn subprocesses spawned by tools/context.py, changes.py, and incremental.py inherit the parent's stdin — which is bound to the MCP request pipe. The child blocks reading from this pipe (Windows console-handle behavior) and never exits. The MCP tool call (get_minimal_context_tool, detect_changes_tool, get_changed_files, etc.) hangs indefinitely. From the user's view Claude Code freezes; only ESC breaks out. claude doctor itself times out spawning CRG for the same reason.

Repro

Reproduces on Claude Code 2.1.126 + CRG 2.3.2 + FastMCP 2.14.7 + Windows 11.

Direct server-side stdio test (printf '<init>\n<list>\n' | code-review-graph serve) returns the full tools list in ~1.5s — the subprocess hang is invisible at that level because the bare initialize handshake fires no git call. Only when an actual MCP tool calls get_minimal_context_tool → _has_git_changes → subprocess.run(["git", ...]) does the inherited stdin pipe deadlock the child.

Fix

Add stdin=subprocess.DEVNULL to every subprocess.run([...git...]) and subprocess.run([...svn...]) call so the child gets an empty stdin instead of inheriting the MCP pipe. POSIX-safe — DEVNULL works identically on Linux/macOS (no behavioural change there).

14 call sites patched across 3 files:

  • code_review_graph/tools/context.py (2 git calls)
  • code_review_graph/changes.py (1 git, 1 svn)
  • code_review_graph/incremental.py (6 git, 4 svn)

Verified

After this patch:

  • mcp__code-review-graph__get_minimal_context_tool returns in <2s with full graph context on Windows 11 + Claude Code 2.1.126.
  • Before: hangs >60s, user must ESC.

Likely also addresses related Windows hang reports: #46, #136, #189.

Why now

The issue was reported 2026-04-29 (#401). I hit it head-on while integrating CRG with Claude Code on a real project (DreamJob.AI) and traced it through:

  1. Server-side stdio test passes in 1.5s ✓
  2. Tool call from Claude Code hangs forever ✗
  3. claude doctor also hangs (exit 143)
  4. tasklist shows multiple zombie git/code-review-graph processes after each hang attempt
  5. Reading tools/context.py revealed the missing stdin=subprocess.DEVNULL on the subprocess.run calls

Happy to iterate on review feedback. Tested locally for 30+ MCP tool calls without a single hang after the patch.

…CP hang

Closes tirth8205#401.

PROBLEM
On Windows, when CRG runs as an MCP server (stdio transport, e.g. via Claude
Code or Cursor), the git/svn subprocesses spawned by tools/context.py,
changes.py, and incremental.py inherit the parent's stdin — which is bound to
the MCP request pipe. The child process blocks reading from this pipe (Windows
console-handle behavior) and never exits. The MCP tool call
(get_minimal_context_tool, detect_changes_tool, get_changed_files, etc.) hangs
indefinitely. From the user's view Claude Code freezes; only ESC breaks out.
`claude doctor` itself times out spawning CRG for the same reason.

REPRO
Reproduces on Claude Code 2.1.126 + CRG 2.3.2 + FastMCP 2.14.7 + Windows 11.
Server-side test (printf init+list | code-review-graph serve) returns
correctly in ~1.5s — the subprocess hang is invisible at that level because
no git call fires for the bare initialize handshake.

FIX
Add stdin=subprocess.DEVNULL to every subprocess.run([...git...]) and
subprocess.run([...svn...]) call so the child gets an empty stdin instead of
inheriting the MCP pipe. POSIX-safe — DEVNULL works identically on
Linux/macOS (no behavioural change there).

14 call sites patched across 3 files:
- code_review_graph/tools/context.py    (2 git calls)
- code_review_graph/changes.py          (1 git, 1 svn)
- code_review_graph/incremental.py      (6 git, 4 svn)

VERIFIED
After this patch:
  mcp__code-review-graph__get_minimal_context_tool returns in <2s with full
  graph context on Windows 11 + Claude Code 2.1.126.
  Before: hangs >60s, user must ESC.

Likely also addresses related Windows hang reports: tirth8205#46, tirth8205#136, tirth8205#189.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Windows stdio MCP: git subprocesses inherit stdin and hang get_minimal_context_tool / detect_changes_tool

1 participant