Skip to content
Closed
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ dependencies = [
"sse-starlette>=1.6.1",
"pydantic-settings>=2.5.2",
"uvicorn>=0.23.1; sys_platform != 'emscripten'",
"psutil>=5.9.0"
]

[project.optional-dependencies]
Expand Down
38 changes: 30 additions & 8 deletions src/mcp/client/stdio/win32.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from typing import TextIO

import anyio
import psutil
from anyio.abc import Process


Expand Down Expand Up @@ -87,8 +88,17 @@ async def create_windows_process(
)
return process


async def terminate_windows_process(process: Process):
"""
Terminate a process and subprocesses.
"""
parent = psutil.Process(process.pid)
children = parent.children(recursive=True)
await terminate_psutil_process(children)
await terminate_psutil_process([parent])


async def terminate_psutil_process(processes: list[psutil.Process]):
"""
Terminate a Windows process.

Expand All @@ -100,10 +110,22 @@ async def terminate_windows_process(process: Process):
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()
for process in processes:
try:
process.terminate() # Send SIGTERM (or equivalent on Windows)
except psutil.NoSuchProcess:
pass
except Exception:
pass
# Allow some time for children to terminate gracefully
_, alive = psutil.wait_procs(processes, timeout=2.0)
for child in alive:
try:
child.kill() # Force kill if still alive
except psutil.NoSuchProcess:
pass # Already gone
except Exception:
pass



15 changes: 15 additions & 0 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading