11import os
2- import shutil
3- import subprocess
42import sys
53from contextlib import asynccontextmanager
64from pathlib import Path
1412
1513import mcp .types as types
1614
15+ from .win32 import create_windows_process , get_windows_executable_command
16+
1717# Environment variables to inherit by default
1818DEFAULT_INHERITED_ENV_VARS = (
1919 [
@@ -115,7 +115,7 @@ async def stdio_client(server: StdioServerParameters, errlog: TextIO = sys.stder
115115 else get_default_environment ()
116116 ),
117117 errlog = errlog ,
118- cwd = server .cwd
118+ cwd = server .cwd ,
119119 )
120120
121121 async def stdout_reader ():
@@ -172,9 +172,9 @@ async def stdin_writer():
172172 try :
173173 process .terminate ()
174174 if sys .platform == "win32" :
175- # On Windows, terminating a process with process.terminate() doesn't
176- # always guarantee immediate process termination.
177- # So we give it 2s to exit, or we call process.kill()
175+ # On Windows, terminating a process with process.terminate() doesn't
176+ # always guarantee immediate process termination.
177+ # So we give it 2s to exit, or we call process.kill()
178178 # which sends a SIGKILL equivalent signal.
179179 try :
180180 with anyio .fail_after (2.0 ):
@@ -196,28 +196,9 @@ def _get_executable_command(command: str) -> str:
196196 Returns:
197197 str: Platform-appropriate command
198198 """
199-
200- try :
201- if sys .platform != "win32" :
202- return command
203- else :
204- # For Windows, we need more sophisticated path resolution
205- # First check if command exists in PATH as-is
206- if command_path := shutil .which (command ):
207- return command_path
208-
209- # Check for Windows-specific extensions
210- for ext in [".cmd" , ".bat" , ".exe" , ".ps1" ]:
211- ext_version = f"{ command } { ext } "
212- if ext_path := shutil .which (ext_version ):
213- return ext_path
214-
215- # For regular commands or if we couldn't find special versions
216- return command
217- except Exception :
218- # If anything goes wrong, just return the original command
219- # shutil.which() could raise exceptions if there are permission
220- # issues accessing directories in PATH
199+ if sys .platform == "win32" :
200+ return get_windows_executable_command (command )
201+ else :
221202 return command
222203
223204
@@ -232,28 +213,8 @@ async def _create_platform_compatible_process(
232213 Creates a subprocess in a platform-compatible way.
233214 Returns a process handle.
234215 """
235-
236- process = None
237-
238216 if sys .platform == "win32" :
239- try :
240- process = await anyio .open_process (
241- [command , * args ],
242- env = env ,
243- # Ensure we don't create console windows for each process
244- creationflags = subprocess .CREATE_NO_WINDOW # type: ignore
245- if hasattr (subprocess , "CREATE_NO_WINDOW" )
246- else 0 ,
247- stderr = errlog ,
248- cwd = cwd ,
249- )
250-
251- return process
252- except Exception :
253- # Don't raise, let's try to create the process without creation flags
254- process = await anyio .open_process (
255- [command , * args ], env = env , stderr = errlog , cwd = cwd
256- )
217+ process = await create_windows_process (command , args , env , errlog , cwd )
257218 else :
258219 process = await anyio .open_process (
259220 [command , * args ], env = env , stderr = errlog , cwd = cwd
0 commit comments