utilities
Windows-specific functionality for stdio client operations.
get_windows_executable_command
Resolves the command to a Windows executable path.
Tries the bare name first, then the common script extensions (.cmd, .bat, .exe, .ps1).
Source code in src/mcp/os/win32/utilities.py
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | |
FallbackProcess
Async wrapper around subprocess.Popen for SelectorEventLoop.
Windows event loops without async subprocess support get this Popen-backed fallback, with anyio file streams wrapping the pipes.
Source code in src/mcp/os/win32/utilities.py
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | |
wait
async
wait() -> int
Waits for exit by polling the Popen.
A thread blocked in Popen.wait() cannot be cancelled by anyio, which would defeat every timeout placed around this call.
Source code in src/mcp/os/win32/utilities.py
76 77 78 79 80 81 82 83 84 | |
terminate
terminate() -> None
Terminates the subprocess.
Source code in src/mcp/os/win32/utilities.py
86 87 88 | |
kill
kill() -> None
Kills the subprocess (on Windows the same hard kill as terminate).
Source code in src/mcp/os/win32/utilities.py
90 91 92 | |
returncode
property
returncode: int | None
The exit code, or None while the process is still running.
Polls the Popen so death is observable without anyone calling wait().
create_windows_process
async
create_windows_process(
command: str,
args: list[str],
env: dict[str, str] | None = None,
errlog: TextIO | None = stderr,
cwd: Path | str | None = None,
) -> Process | FallbackProcess
Creates a subprocess with Job Object support for tree termination.
Spawns via anyio's open_process; event loops without async subprocess support (notably the SelectorEventLoop) raise NotImplementedError, in which case the spawn falls back to a Popen-backed FallbackProcess. Either way the process is then assigned to a Job Object so its children can be terminated with it; children spawned before the assignment completes are not captured (see the inline note below).
Returns:
| Type | Description |
|---|---|
Process | FallbackProcess
|
Process | FallbackProcess: The spawned process with async stdin/stdout streams. |
Source code in src/mcp/os/win32/utilities.py
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | |
close_process_job
close_process_job(
process: Process | FallbackProcess,
) -> None
Closes the process's Job Object handle, if it still has one.
KILL_ON_JOB_CLOSE makes the close also kill any members still alive, deterministically rather than at GC time; a deliberate divergence from POSIX, where a graceful server's children are left alive.
Source code in src/mcp/os/win32/utilities.py
225 226 227 228 229 230 231 232 233 234 235 236 237 | |
terminate_windows_process_tree
async
terminate_windows_process_tree(
process: Process | FallbackProcess,
) -> None
Terminates the process's job, or just the process if it has no job.
Job termination is an immediate hard kill of every member. Windows has no tree-wide SIGTERM; the stdin-close grace period is the server's chance to exit cleanly.
Source code in src/mcp/os/win32/utilities.py
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | |