Symptom
In stdio MCP mode, every connection auto-creates a lane (`mcp:`) on `SESSION_START`. When the client disconnects, the lane stays around — by design — so HTTP MCP clients can reconnect with the same session id and rejoin their lane.
For stdio MCP, every connection is genuinely fresh — there's no reconnect case. A wrapper that opens a fresh `ClientSession` for each call (the canonical pattern when the agent doesn't want long-lived MCP state, e.g., HKUDS/CLI-Anything's non-daemon mode) leaves one orphan tab group per call.
Surfaced 2026-05-29 in HKUDS/CLI-Anything PR #308 review by Codex (P2 finding on commit b897659):
In the non-daemon path this still creates and initializes a fresh MCP client for every wrapper call. DOMShell 2's server creates an isolated lane for each MCP client and documents that disconnected clients leave their lane open; when session.domshell_lane_id is already set, the command is then routed to the old lane via group_id, leaving the newly-created default lane unused after every fs ls, act click, etc.
Reproduction
- From a non-daemon MCP client, open N stdio connections in sequence (each one a fresh `ClientSession`)
- On each connection, route the actual command to a known lane via `group_id`
- Observe Chrome's tab groups: N orphan groups accumulate even though no commands ran in their default lanes
Why HTTP and stdio differ
| Transport |
Reconnect possible? |
Should default lane survive disconnect? |
| HTTP MCP |
Yes (session id in header — client can rejoin) |
Yes — current behavior is correct |
| Stdio MCP |
No (every `stdio_client` is a fresh process pair) |
No — orphan is pure leak |
Fix directions
- Detect non-stdio session at disconnect. When a stdio transport's MCP session disconnects, close its auto-assigned lane unless the client used it for at least one command. Preserves HTTP reconnect semantics.
- Lazy lane materialization. Don't create `mcp:` lane on `SESSION_START`; create it on first command that doesn't specify `group_id`. Connections that route every command via `group_id` (the HKUDS pattern) never materialize a default lane.
- Explicit close-on-disconnect. Server-side: when stdio disconnect happens for a session whose lane has zero command activity, close the lane.
(2) is the cleanest — it's purely additive ("create lane only when needed") and doesn't change behavior for any existing flow.
Workaround on the integrator side
HKUDS/CLI-Anything can refactor to use a persistent `ClientSession` per harness session (their post-merge follow-up). Once a single connection serves all calls, the default lane materializes once and is reused. The DOMShell-side fix would make this refactor unnecessary.
Priority
Not blocking — the agent's documented best-practice ("CLEAN UP YOUR LANES WHEN YOU FINISH") prevents the leak when followed, and the Chrome tab-group count is generally bounded by user attention. But for wrappers that open many short-lived MCP sessions per workflow, the accumulation is real.
P2 / next-patch candidate.
Symptom
In stdio MCP mode, every connection auto-creates a lane (`mcp:`) on `SESSION_START`. When the client disconnects, the lane stays around — by design — so HTTP MCP clients can reconnect with the same session id and rejoin their lane.
For stdio MCP, every connection is genuinely fresh — there's no reconnect case. A wrapper that opens a fresh `ClientSession` for each call (the canonical pattern when the agent doesn't want long-lived MCP state, e.g., HKUDS/CLI-Anything's non-daemon mode) leaves one orphan tab group per call.
Surfaced 2026-05-29 in HKUDS/CLI-Anything PR #308 review by Codex (P2 finding on commit b897659):
Reproduction
Why HTTP and stdio differ
Fix directions
(2) is the cleanest — it's purely additive ("create lane only when needed") and doesn't change behavior for any existing flow.
Workaround on the integrator side
HKUDS/CLI-Anything can refactor to use a persistent `ClientSession` per harness session (their post-merge follow-up). Once a single connection serves all calls, the default lane materializes once and is reused. The DOMShell-side fix would make this refactor unnecessary.
Priority
Not blocking — the agent's documented best-practice ("CLEAN UP YOUR LANES WHEN YOU FINISH") prevents the leak when followed, and the Chrome tab-group count is generally bounded by user attention. But for wrappers that open many short-lived MCP sessions per workflow, the accumulation is real.
P2 / next-patch candidate.