fix(mcp): use DetachedStdioTransport to fix Chromium orphan process leak#173
Open
hernandez42 wants to merge 1 commit into
Open
fix(mcp): use DetachedStdioTransport to fix Chromium orphan process leak#173hernandez42 wants to merge 1 commit into
hernandez42 wants to merge 1 commit into
Conversation
Root cause: StdioClientTransport spawns tsx with default detached=false, making tsx a child of PilotDeck's process group. When McpClient.close() calls kill(-pid, SIGKILL), the target is PilotDeck's group (not tsx's), so the signal misses — Chromium grandchild processes survive as orphans. Fix: Replace StdioClientTransport with DetachedStdioTransport which spawns the child with detached:true. Now PID == PGID, so kill(-pid, SIGKILL) atomically wipes the entire process tree (tsx → node playwright-mcp → Chromium). Also update BackgroundTaskRuntime.stop() to use killChildProcessGroup() instead of child.kill() for consistent process-group semantics. Changes: - src/mcp/client/DetachedStdioTransport.ts: NEW — drop-in replacement for StdioClientTransport with detached:true + proper env inheritance - src/mcp/client/McpClient.ts: use DetachedStdioTransport, lazy _transportPid capture, atomic process-group SIGKILL in close() - src/task/runtime/BackgroundTaskRuntime.ts: killChildProcessGroup in stop()
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fix Chromium/Playwright orphan process leak caused by incorrect process group semantics in McpClient.
Root Cause
StdioClientTransportspawns tsx withdetached=false(default), making tsx a child of PilotDeck's process group (PGID = PilotDeck PID). WhenMcpClient.close()callskill(-pid, SIGKILL):Fix
New
DetachedStdioTransport.ts: Drop-in replacement forStdioClientTransportthat spawns the child withdetached: true. Now the child becomes its own process group leader (PID = PGID), sokill(-pid, SIGKILL)atomically wipes the entire tree.McpClient.ts:StdioClientTransportwithDetachedStdioTransport_transportPidcapture aftertransport.start()SIGKILLinclose()(no graceful SIGTERM cascade)BackgroundTaskRuntime.ts: UsekillChildProcessGroup()instead ofchild.kill()instop()for consistent process-group semantics.Changes
src/mcp/client/DetachedStdioTransport.tsdetached: truetransport with proper env inheritancesrc/mcp/client/McpClient.tsDetachedStdioTransport, atomic PGID kill inclose()src/task/runtime/BackgroundTaskRuntime.tskillChildProcessGroupinstop()Severity
High — causes memory leak (Chromium processes never exit), eventually triggers OOM and kills PilotDeck.