Skip to content

Comments

fix: wait for first result before closing stdin for SDK MCP servers#595

Open
gspeter-max wants to merge 1 commit intoanthropics:mainfrom
gspeter-max:claude-agent-sdk-python/issue_578
Open

fix: wait for first result before closing stdin for SDK MCP servers#595
gspeter-max wants to merge 1 commit intoanthropics:mainfrom
gspeter-max:claude-agent-sdk-python/issue_578

Conversation

@gspeter-max
Copy link

Summary

Fixes #578 - When using query() with a string prompt + SDK MCP servers, the SDK crashed with CLIConnectionError: ProcessTransport is not ready for writing.

Root Cause

The string prompt path in client.py closed stdin immediately after writing the user message (line 134). SDK MCP servers require bidirectional communication via the control protocol:

  1. Python → CLI: user message via stdin ✅
  2. CLI → Python: control_request (mcp_message) via stdout
  3. Python → CLI: control_response via stdin ❌ (stdin already closed)

Once stdin is closed, the SDK cannot send control_response messages back to the CLI, causing all subsequent writes to fail.

Changes

src/claude_agent_sdk/_internal/client.py

  • Added guard to check if sdk_mcp_servers or configured_options.hooks exist
  • If yes, wait for query._first_result_event before closing stdin
  • Use anyio.move_on_after with timeout (from query._stream_close_timeout)
  • Add debug logging for observability

Tests Added

  • Unit test: test_string_prompt_with_sdk_mcp_servers() - Verifies the fix with mocked components
  • E2E test: test_string_prompt_with_sdk_mcp_tool() - Verifies the fix with real CLI

Impact

  • ✅ String prompts with SDK MCP servers now work correctly
  • ✅ Hooks also fixed (same control protocol issue)
  • ✅ No impact on string prompts without SDK MCP servers/hooks
  • ✅ AsyncIterable prompts unchanged (already correct)
  • ✅ All 157 existing tests pass

Verification

# Run the new unit test
python -m pytest tests/test_sdk_mcp_integration.py::test_string_prompt_with_sdk_mcp_servers -v

# Run all tests
python -m pytest tests/ -v

References

🤖 Generated with Claude Code

ROOT CAUSE:
When using query() with a string prompt + SDK MCP servers, the SDK
crashes with CLIConnectionError because stdin is closed immediately
after writing the user message. SDK MCP servers require bidirectional
communication via the control protocol, which needs stdin to remain open.

CHANGES:
- Added guard in client.py to check for sdk_mcp_servers or hooks
- When present, wait for _first_result_event before closing stdin
- Use anyio.move_on_after with timeout for safety
- Add debug logging for observability

IMPACT:
- String prompts with SDK MCP servers now work correctly
- Hooks also fixed (same control protocol issue)
- No impact on string prompts without SDK MCP servers/hooks
- AsyncIterable prompts unchanged (already correct)

FILES MODIFIED:
- src/claude_agent_sdk/_internal/client.py
- tests/test_sdk_mcp_integration.py (added unit test)
- e2e-tests/test_sdk_mcp_tools.py (added E2E test)

Fixes anthropics#578

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.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.

CLIConnectionError: ProcessTransport is not ready for writing when using SDK MCP servers with string prompts

2 participants