diff --git a/src/mcp/client/stdio/__init__.py b/src/mcp/client/stdio/__init__.py index a75cfd764..09455229b 100644 --- a/src/mcp/client/stdio/__init__.py +++ b/src/mcp/client/stdio/__init__.py @@ -16,7 +16,6 @@ from .win32 import ( create_windows_process, get_windows_executable_command, - terminate_windows_process, ) # Environment variables to inherit by default @@ -180,13 +179,15 @@ async def stdin_writer(): finally: # Clean up process to prevent any dangling orphaned processes try: - if sys.platform == "win32": - await terminate_windows_process(process) - else: - process.terminate() + process.terminate() + with anyio.fail_after(2.0): + await process.wait() except ProcessLookupError: # Process already exited, which is fine pass + except TimeoutError: + # Force kill if it doesn't terminate + process.kill() await read_stream.aclose() await write_stream.aclose() await read_stream_writer.aclose() diff --git a/src/mcp/client/stdio/win32.py b/src/mcp/client/stdio/win32.py index 7246b9dec..bfc88e6c8 100644 --- a/src/mcp/client/stdio/win32.py +++ b/src/mcp/client/stdio/win32.py @@ -8,9 +8,7 @@ from pathlib import Path from typing import BinaryIO, TextIO, cast -import anyio from anyio import to_thread -from anyio.abc import Process from anyio.streams.file import FileReadStream, FileWriteStream @@ -158,25 +156,5 @@ async def create_windows_process( cwd=cwd, bufsize=0, ) - return FallbackProcess(popen_obj) - - -async def terminate_windows_process(process: Process | FallbackProcess): - """ - Terminate a Windows process. - - Note: On Windows, terminating a process with process.terminate() doesn't - always guarantee immediate process termination. - So we give it 2s to exit, or we call process.kill() - which sends a SIGKILL equivalent signal. - Args: - process: The process to terminate - """ - try: - process.terminate() - with anyio.fail_after(2.0): - await process.wait() - except TimeoutError: - # Force kill if it doesn't terminate - process.kill() + return FallbackProcess(popen_obj)