@@ -83,7 +83,7 @@ class StdioServerParameters(BaseModel):
8383
8484
8585@asynccontextmanager
86- async def stdio_client (server : StdioServerParameters ):
86+ async def stdio_client (server : StdioServerParameters , startup_wait_time : float = 0.0 ):
8787 """
8888 Client transport for stdio: this will connect to a server by spawning a
8989 process and communicating with it over stdin/stdout.
@@ -97,11 +97,17 @@ async def stdio_client(server: StdioServerParameters):
9797 read_stream_writer , read_stream = anyio .create_memory_object_stream (0 )
9898 write_stream , write_stream_reader = anyio .create_memory_object_stream (0 )
9999
100- process = await anyio .open_process (
101- [server .command , * server .args ],
102- env = server .env if server .env is not None else get_default_environment (),
103- stderr = sys .stderr ,
104- )
100+ try :
101+ process = await anyio .open_process (
102+ [server .command , * server .args ],
103+ env = server .env or get_default_environment (),
104+ stderr = sys .stderr ,
105+ )
106+ except OSError as exc :
107+ raise RuntimeError (
108+ f"Failed to spawn process: { server .command } { server .args } . "
109+ f"Check that the binary exists and is executable."
110+ ) from exc
105111
106112 async def stdout_reader ():
107113 assert process .stdout , "Opened process is missing stdout"
@@ -144,10 +150,21 @@ async def stdin_writer():
144150 except anyio .ClosedResourceError :
145151 await anyio .lowlevel .checkpoint ()
146152
147- async with (
148- anyio .create_task_group () as tg ,
149- process ,
150- ):
153+ async def watch_process_exit ():
154+ returncode = await process .wait ()
155+ if returncode != 0 :
156+ raise RuntimeError (
157+ f"Subprocess exited with code { returncode } . "
158+ f"Command: { server .command } , { server .args } "
159+ )
160+
161+ async with anyio .create_task_group () as tg , process :
151162 tg .start_soon (stdout_reader )
152163 tg .start_soon (stdin_writer )
164+ tg .start_soon (watch_process_exit )
165+
166+ if startup_wait_time > 0 :
167+ with anyio .move_on_after (startup_wait_time ):
168+ await anyio .sleep_forever ()
169+
153170 yield read_stream , write_stream
0 commit comments