Skip to content

[codex] Fix ctx_shell MCP command hangs#132

Closed
xsploit wants to merge 1 commit into
yvgude:mainfrom
xsploit:codex/fix-ctx-shell-git-hang
Closed

[codex] Fix ctx_shell MCP command hangs#132
xsploit wants to merge 1 commit into
yvgude:mainfrom
xsploit:codex/fix-ctx-shell-git-hang

Conversation

@xsploit
Copy link
Copy Markdown

@xsploit xsploit commented Apr 20, 2026

Summary

  • Prevent ctx_shell child processes from inheriting MCP stdio, which can block commands like Git inside MCP sessions.
  • Disable Git prompts/pagers for shell execution so non-interactive calls return deterministically.
  • Add a bounded command timeout plus regression tests for stdin closure and git --version.

Root cause

The MCP server uses stdin for JSON-RPC. Commands launched by ctx_shell inherited that stdin, so interactive or stdin-aware tools could block on the protocol stream instead of receiving EOF.

Validation

  • cargo test --locked execute_command -- --nocapture
  • cargo test --locked git_version_returns -- --nocapture
  • git diff --check
  • Manual MCP smoke: ctx_shell returned git --version and git status --short --branch immediately after reinstalling the patched binary.

yvgude pushed a commit that referenced this pull request Apr 20, 2026
fix: UTF-8 text corrupted on Windows PowerShell (#131)
fix: MCP ctx_shell commands hang on stdin (#132, credit: @xsploit)
feat: MCP command timeout (120s default, configurable)
test: stdin closure + git version regression tests
Made-with: Cursor
@yvgude
Copy link
Copy Markdown
Owner

yvgude commented Apr 20, 2026

Thank you @xsploit for this excellent contribution! 🙌

The core fixes from this PR have been manually merged into v3.2.9 with the following additions:

What was adopted from your PR:

  • stdin(Stdio::null()) — the critical fix preventing JSON-RPC pipe inheritance
  • GIT_TERMINAL_PROMPT=0, GIT_PAGER=cat, PAGER=cat env vars
  • Bounded command timeout with try_wait polling loop (120s default, configurable via LEAN_CTX_SHELL_TIMEOUT_MS)
  • mpsc::channel pattern with recv_timeout for reader threads
  • Both regression tests (execute_command_closes_stdin, git_version_returns_when_git_is_available)

Additional change on top of your PR:

Released in v3.2.9. You're credited in the CHANGELOG. Thanks for the thorough analysis and clean PR!

@yvgude
Copy link
Copy Markdown
Owner

yvgude commented Apr 20, 2026

Merged manually in v3.2.9. See comment above for details.

@yvgude yvgude closed this Apr 20, 2026
yvgude pushed a commit that referenced this pull request May 29, 2026
Pure robustness hardening from the codebase review (no behavior change for
successful paths, no UX impact):

- config set: return Err instead of panicking when an intermediate config.toml
  key holds a non-table value (#130)
- shell exec (Windows): fall back to inline PowerShell if the temp script file
  cannot be created instead of .expect panic (#131)
- proxy: fall back to Ctrl-C if the SIGTERM handler cannot be installed (#132)
- bm25_cache + ctx_compose: isolate background-thread panics with catch_unwind
  so a worker panic can't silently die / leak state (#133)
- session / cost-attribution / semantic-index / agent-registry: log save()
  failures via tracing::warn! instead of swallowing them (#134)

Co-authored-by: Cursor <cursoragent@cursor.com>
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.

2 participants