Skip to content

Chromium processes leak on MCP client disconnect (macOS, VSCode) #41918

Closed as not planned

Description

@basje01

Chromium processes leak on MCP client disconnect (macOS, VSCode)

Environment

  • OS: macOS 14 (darwin 25.5.0)
  • MCP server: @playwright/mcp@latest invoked via npm exec @playwright/mcp@latest --isolated
  • MCP client: Claude Code VSCode extension
  • Node: v20.x (system)

Observed

After a normal day of coding sessions, ~82 Playwright-related processes were alive on the machine — a mix of npm exec @playwright/mcp wrappers, node …/playwright-mcp binaries, and Chromium processes under ~/Library/Caches/ms-playwright/. None were tied to an active MCP session; they had reparented to launchd.

$ pgrep -f '@playwright/mcp|playwright-mcp|ms-playwright' | wc -l
82

Killing them all was safe (no user session was using them) and immediately freed ~4 GB RAM.

Expected

When an MCP client disconnects, the @playwright/mcp server should tear down its browser context and exit, releasing its Chromium subprocess. --isolated should make this per-session cleanup automatic.

Actual

Some subset of disconnect paths leaves the Chromium child alive. Because the Chromium child inherits stdio pipes but is not otherwise session-bound, when the node parent dies (or is killed by the MCP client's cleanup) Chromium is reparented to launchd and lingers until reboot.

Not reliably reproducible on demand

The leak seems tied to abnormal disconnects (VSCode window closed with a session running, extension host restart, session compaction mid-tool-call). Clean end-of-session — where the model calls browser_close and then the client disconnects — does NOT appear to leak.

Ask

  1. Is the intended contract that clients MUST call browser_close before disconnect, or should --isolated auto-close on transport disconnect?
  2. If the former, is there a plan to add a --auto-close-on-disconnect flag or make it default under --isolated?
  3. If the latter, would you accept a repro-focused issue with a synthetic disconnect test?

Happy to package a minimal repro if item 3 is the answer — or if it's item 1, I'll update the caller's docs and close this out.

Workaround in place (in case useful to others)

A narrow-pattern reaper that matches ONLY Playwright's own footprint (@playwright/mcp, playwright-mcp, ms-playwright, @playwright+test, /playwright/test) — will not touch Chrome, Chromium, or IDE crashpad handlers. Runs on SessionStart via a Claude Code hook.

Activity

  1. pavelfeldman commented on Jul 22, 2026

    @pavelfeldman
    Member

    Is the intended contract that clients MUST call browser_close before disconnect, or should --isolated auto-close on transport disconnect?

    In the --isolated mode, the browser is created once and is shared across the clients. Each client gets a browser context that is torn down on client disconnect. When all the clients disconnect, browser is closed.

    If the latter, would you accept a repro-focused issue with a synthetic disconnect test?

    Of course.

  2. harshmathurx commented on Jul 25, 2026

    @harshmathurx
    Contributor

    Hi Pavel Feldman (@pavelfeldman), I can take this up and open a focused PR.

    I’ve read CONTRIBUTING.md; I’ll keep this scoped to the --isolated MCP disconnect lifecycle, first check that #41966 does not already close this leak path, then add a synthetic disconnect regression test around context/browser cleanup before changing code.

    If you prefer this wait for assignment before a PR, I’ll pause after the repro test.

  3. dgozman commented on Jul 27, 2026

    @dgozman
    Collaborator

    Harsh Mathur (@harshmathurx) Sure, give this a shot.

  4. Skn0tt commented on Aug 5, 2026

    @Skn0tt
    Contributor

    Knock knock, housekeeping's here. I'll sweep this out since it's been idling for a while. Harsh Mathur (@harshmathurx) feel free to still give it a shot, we're happy to reopen the issue if you send a PR.

  5. harshmathurx commented on Aug 5, 2026

    @harshmathurx
    Contributor

    Simon Knott (@Skn0tt) opened #42140 with focused regression coverage for the isolated MCP stdio disconnect path discussed here.

    I checked current main first: the stdio disconnect cleanup hook is already present, so the PR keeps this scoped to a regression test that closes the client transport directly and asserts the isolated browser/context are cleaned up.

    Local verification passed:

    • npm run test-mcp -- --project=chromium tests/mcp/launch.spec.ts -g "isolated stdio server closes browser on client transport disconnect"
    • npm run test-mcp -- --project=chromium tests/mcp/launch.spec.ts
    • npx eslint tests/mcp/fixtures.ts tests/mcp/launch.spec.ts
    • npm run tsc

    Could you reopen this issue against the PR? I tried reopening it directly, but I do not have permission.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions