Skip to content

feat: add multi-session support for concurrent Chrome instances#899

Open
RobertWsp wants to merge 4 commits intoChromeDevTools:mainfrom
RobertWsp:feat/multi-session-support
Open

feat: add multi-session support for concurrent Chrome instances#899
RobertWsp wants to merge 4 commits intoChromeDevTools:mainfrom
RobertWsp:feat/multi-session-support

Conversation

@RobertWsp
Copy link

Summary

Add multi-session support allowing multiple independent Chrome browser instances to run simultaneously, each identified by a unique sessionId. This enables parallel browser automation workflows (e.g., testing multiple pages side-by-side, comparing environments) without needing multiple MCP server processes.

Motivation

The current architecture supports only a single Chrome browser instance per server. This limits use cases where an MCP client needs to interact with multiple browser contexts concurrently — for example, comparing two web pages, running parallel test suites, or managing multiple authenticated sessions.

Changes

New files

  • src/SessionManager.ts — Core session lifecycle manager with per-session Mutex, auto-purge on browser disconnect, orphan prevention, and graceful shutdown
  • src/tools/session.ts — Three new tools: create_session, list_sessions, close_session
  • tests/SessionManager.test.ts — 17 E2E tests covering creation, retrieval, listing, closing, parallel isolation, mutex serialization, auto-purge, and shutdown rejection

Modified files

  • src/main.ts — Replaced singleton browser/context with SessionManager. Added registerBrowserTool() wrapper that transparently injects sessionId into every existing tool's Zod schema and resolves the correct session's McpContextoriginal tool handlers remain unmodified
  • src/tools/categories.ts — Added SESSION category
  • src/tools/tools.ts — Registered session tools, exported sessionToolNames set

Design decisions

  • Transparent injection: Existing tool handlers are NOT modified. registerBrowserTool() wraps each tool, injecting sessionId into the schema and resolving the correct McpContext before calling the unmodified handler
  • isolated: true forced: All sessions use isolated Chrome profiles to prevent conflicts
  • Per-session Mutex: Tools within the same session are serialized; different sessions run in parallel
  • In-memory state: Zero disk state — sessions are tracked in a Map<string, SessionInfo>
  • Safety check: Throws at startup if any tool defines its own sessionId schema (prevents conflicts)

Error handling

  • Orphan Chrome processes prevented: if McpContext.from() fails after launch(), the browser is closed
  • Race condition on close: closeSession() acquires the session mutex before closing
  • Signal handling: process.once('SIGINT'/'SIGTERM') with #shuttingDown guard and 10s timeout
  • Disconnected sessions auto-purge via browser.on('disconnected')
  • All catch blocks use instanceof Error (no unsafe err?.message)

Test results

▶ SessionManager (17 tests)
  ✔ creates a session and returns session info
  ✔ assigns label when provided
  ✔ generates unique session IDs
  ✔ rejects creation when shutting down
  ✔ returns session by ID
  ✔ throws for unknown session ID
  ✔ throws and purges for disconnected browser
  ✔ returns empty list when no sessions
  ✔ returns all active sessions
  ✔ closes and removes session
  ✔ throws for unknown session ID
  ✔ handles already-disconnected browser gracefully
  ✔ closes all sessions
  ✔ two sessions can navigate to different URLs independently
  ✔ closing one session does not affect another
  ✔ per-session mutex serializes within session but allows cross-session parallelism
  ✔ removes session when browser disconnects unexpectedly
✔ 17 pass, 0 fail

Breaking changes

All existing browser tools now require a mandatory sessionId parameter. Clients must call create_session first to obtain a session ID before using any other tool.

Introduce SessionManager class that manages multiple isolated Chrome
browser instances, each identified by a unique sessionId. Add three
new session tools: create_session, list_sessions, and close_session.

- Per-session Mutex ensures tool serialization within a session while
  allowing cross-session parallelism
- Orphan prevention: browser is closed if McpContext creation fails
- Auto-purge via browser 'disconnected' event listener
- Graceful shutdown with #shuttingDown guard
- SESSION category added to ToolCategory enum
Replace singleton browser/context with SessionManager. All existing
browser tools now receive a mandatory sessionId parameter injected
transparently via registerBrowserTool() wrapper — original tool
handlers remain unmodified.

- registerBrowserTool(): injects sessionId into Zod schema, resolves
  correct session's McpContext, acquires per-session mutex
- registerSessionTool(): full implementations for create/list/close
- Signal handling with process.once() and 10s shutdown timeout
- Safety check rejects tools that define their own sessionId schema
17 tests covering session creation, retrieval, listing, closing,
parallel session isolation, per-session mutex serialization,
auto-purge on browser disconnect, and shutdown rejection.
@google-cla
Copy link

google-cla bot commented Feb 5, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@RobertWsp
Copy link
Author

I have signed the CLA. Please re-check.

@OrKoN
Copy link
Collaborator

OrKoN commented Feb 6, 2026

Thanks for the PR but we do not plan to support multiple sessions right now. Could you please file a feature request to help us better understand scenarios you plan to use it for?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants