Skip to content

Commit 925a02b

Browse files
committed
fix(stdio): suppress BrokenResourceError on shutdown
1 parent 616476f commit 925a02b

2 files changed

Lines changed: 25 additions & 2 deletions

File tree

src/mcp/client/stdio.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ async def stdout_reader():
158158

159159
session_message = SessionMessage(message)
160160
await read_stream_writer.send(session_message)
161-
except anyio.ClosedResourceError: # pragma: lax no cover
161+
except (anyio.ClosedResourceError, anyio.BrokenResourceError):
162162
await anyio.lowlevel.checkpoint()
163163

164164
async def stdin_writer():

tests/client/test_stdio.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import anyio
99
import anyio.abc
10+
import anyio.lowlevel
1011
import pytest
1112

1213
from mcp.client.session import ClientSession
@@ -67,7 +68,29 @@ async def test_stdio_client():
6768

6869
assert len(read_messages) == 2
6970
assert read_messages[0] == JSONRPCRequest(jsonrpc="2.0", id=1, method="ping")
70-
assert read_messages[1] == JSONRPCResponse(jsonrpc="2.0", id=2, result={})
71+
assert read_messages[1] == JSONRPCResponse(jsonrpc="2.0", id=2, result={})
72+
73+
74+
@pytest.mark.anyio
75+
async def test_stdio_client_exits_cleanly_while_stdout_reader_is_blocked_in_send():
76+
server_script = textwrap.dedent(
77+
r"""
78+
import sys
79+
80+
sys.stdout.write('{"jsonrpc":"2.0","id":1,"result":{}}\n')
81+
sys.stdout.flush()
82+
83+
# Wait for stdin to close so the parent can exercise the shutdown path.
84+
for _line in sys.stdin:
85+
pass
86+
"""
87+
)
88+
server_params = StdioServerParameters(command=sys.executable, args=["-c", server_script])
89+
90+
async with stdio_client(server_params) as (read_stream, _write_stream):
91+
with anyio.fail_after(5.0):
92+
while read_stream.statistics().tasks_waiting_send == 0:
93+
await anyio.lowlevel.checkpoint()
7194

7295

7396
@pytest.mark.anyio

0 commit comments

Comments
 (0)