Skip to content

Commit 0704a0b

Browse files
committed
fix: prevent orphaned processes via stdin/ppid/onclose lifecycle guards
Adds 4 missing lifecycle guards to main() that caused orphaned node processes to accumulate (~27GB RAM from 41 orphans on a 32GB machine): - stdin end/close listeners: detect client exit via pipe closure - server.onclose: handle graceful MCP protocol disconnect - PPID polling (5s, unref'd): cross-platform parent death detection - SIGHUP handler: terminal close on Unix + Windows console close
1 parent a814b24 commit 0704a0b

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

src/index.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1612,9 +1612,32 @@ async function main() {
16121612
}
16131613
}
16141614

1615+
// Parent death guard — catches SIGKILL, crashes, terminal close on ALL platforms.
1616+
// process.kill(pid, 0) throws ESRCH when the process no longer exists.
1617+
const parentPid = process.ppid;
1618+
if (parentPid > 1) {
1619+
const parentGuard = setInterval(() => {
1620+
try {
1621+
process.kill(parentPid, 0);
1622+
} catch {
1623+
process.exit(0);
1624+
}
1625+
}, 5_000);
1626+
parentGuard.unref();
1627+
}
1628+
16151629
const transport = new StdioServerTransport();
16161630
await server.connect(transport);
16171631

1632+
// Detect stdin pipe closure — the primary signal that the MCP client is gone.
1633+
// StdioServerTransport only listens for 'data'/'error', never 'end'.
1634+
process.stdin.on('end', () => process.exit(0));
1635+
process.stdin.on('close', () => process.exit(0));
1636+
1637+
// Handle graceful MCP protocol-level disconnect.
1638+
// Fires after SDK internal cleanup when transport.close() is called.
1639+
server.onclose = () => process.exit(0);
1640+
16181641
if (process.env.CODEBASE_CONTEXT_DEBUG) console.error('[DEBUG] Server ready');
16191642

16201643
await refreshKnownRootsFromClient();
@@ -1651,6 +1674,10 @@ async function main() {
16511674
stopAllWatchers();
16521675
process.exit(0);
16531676
});
1677+
process.once('SIGHUP', () => {
1678+
stopAllWatchers();
1679+
process.exit(0);
1680+
});
16541681
}
16551682

16561683
// Export server components for programmatic use

0 commit comments

Comments
 (0)