Skip to content

Web: closing or reloading a connected tab leaks the backend session and its spawned stdio server process #2824

Closed

Description

@CloneOfAlex

Which version line?

v2 — current (@modelcontextprotocol/inspector@latest)

Which client?

Web

Inspector version

2.13.0 (v2/main @ d7f6cee, built from source)

Node version

v22.23.4

Operating system (and browser, for the web client)

Linux (Debian), Chrome for Testing 153 (headless, via Playwright)

Transport

stdio

MCP server under inspection

The repo's own stdio test server, default config:
node test-servers/build/test-server-stdio.js (built with npm run test-servers:build in clients/web).

Steps to reproduce

  1. mcp-inspector --web node test-servers/build/test-server-stdio.js
  2. Open the printed URL, toggle the server to Connected.
  3. Close the tab (beforeunload runs) — or reload the page instead.
  4. Count the Inspector's child processes: ps -eo ppid,args | awk '$1==<inspector pid>' | grep -c test-server-stdio
  5. Repeat steps 2–4.

Expected behavior

When the browser goes away (tab closed, page reloaded, browser killed), the backend session is torn down after a short grace period and its stdio child process exits.

Actual behavior

The session and its child process live until the Inspector itself exits. Measured:

Action Server processes alive
Before 8
Connect, then close tab (beforeunload ran) 9
Connect, then reload page 10
20 s later 10

Cause, as far as I can tell: the web client sends nothing on pagehide/beforeunload, and when the SSE stream drops, /api/mcp/events calls session.clearEventConsumer() (core/mcp/remote/node/remote-session.ts), which only reports transportDead — the session is deleted only if the transport is already dead, never closed. Every later server message for that session is also pushed onto RemoteSession.eventQueue, which has no cap, so a chatty server grows memory without bound.

SIGTERM to the Inspector does reap all children, so the leak is bounded by the Inspector's lifetime.

Logs, errors, or screenshots

Suggested fix:

  • After the SSE consumer detaches, start a grace timer (e.g. 30 s) that closes the transport and deletes the session unless a consumer reattaches.
  • Send navigator.sendBeacon to a disconnect endpoint on pagehide.
  • Cap eventQueue (drop oldest with a notice).

Already prototyped a fix?

No response

Before you submit

  • I searched existing issues and this is not a duplicate.
  • This is not a security vulnerability report (those go through the private advisory process).

Activity

  1. cliffhall commented on Oct 29, 2026

    @cliffhall
    Member

    Triage: Priority Medium (total 7)

    • Severity 3 — a resource leak: each closed or reloaded tab leaves a backend session and its stdio child alive until the Inspector exits, with an unbounded event queue
    • Urgency 3 — affects every web user on the published 2.13 line, not just an edge configuration
    • Bonuses: +1 bug label (no milestone, assignee, epic, engagement or reporter-set priority)

    Board: #28, Status Incoming (awaiting maintainer review — no milestone yet).

  2. added this to the v2.14.0 milestone on Oct 29, 2026
  3. self-assigned this
    on Oct 29, 2026
  4. cliffhall commented on Oct 29, 2026

    @cliffhall
    Member

    Fixed by #2853, merged into v2/main; verified together with the rest of v2.14.0 in the rollup #2858.

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingv2Issues and PRs for v2

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions