Merge PR #5894: fix(mcp): process-group kill and SIGKILL escalate on stdio transport close (@Mathews-Tom)

This commit is contained in:
can1357
2026-07-18 19:57:45 +02:00
2 changed files with 10 additions and 1 deletions
+1
View File
@@ -41,6 +41,7 @@
## [17.0.3] - 2026-07-17
- Fixed orphaned detached MCP stdio server process trees surviving session dispose by escalating stdin-EOF → group SIGTERM → group SIGKILL on close() (#5578)
### Changed
- `omp usage` and the in-session `/usage` view now show the Anthropic organization next to the account for org-scoped credentials (with `--redact` masking applied per part in the CLI, falling back to the org id when no display name is available), attribute "no usage data" rows per organization, and match the "in use by this session" marker by organization so only the active subscription is flagged. The OAuth login success message names the account and organization that was stored — a login landing on an unintended subscription is visible immediately.
@@ -153,13 +153,21 @@ describe.skipIf(process.platform === "win32")("StdioTransport request write stal
}, 8000);
});
// `kill(pid, 0)` succeeds for a zombie too: a grandchild whose parent (the
// killed leader) is gone sits as <defunct> until whatever reaps orphans
// (init/subreaper) gets around to it — which can lag on some hosts. A
// zombie already received and honored the group SIGKILL; it is just not
// harvested yet, so treating it as "still alive" would make the group-kill
// assertions below flaky rather than testing what they claim to test.
function processExists(pid: number): boolean {
try {
process.kill(pid, 0);
return true;
} catch {
return false;
}
const result = Bun.spawnSync(["ps", "-o", "stat=", "-p", String(pid)]);
const state = result.stdout.toString().trim();
return result.exitCode === 0 && state.length > 0 && !state.startsWith("Z");
}
// Regression for #5578: `close()` used a bare `this.#process.kill()` (direct