ChromeDevTools / ChromeDevTools/chrome-devtools-mcp
Browser hangs / crashes when MCP connects to Chrome with many tabs
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 52.3k
- Forks
- 4.3k
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 83
Description
Description of the bug
When chrome-devtools-mcp connects to a Chrome instance with a very large number of open tabs (about 2000 or so for me), the browser becomes unresponsive and then crashes on the first tool call. list_pages is the simplest trigger, but any tool call that constructs McpContext pays the same startup cost.
The MCP does a substantial amount of eager per-tab work when the context is initialized and then redoes per-tab work on every response that sets includePages (which is most navigation / tab-management tools). A comment in McpContext.ts notes that page count is "typically 2-10", which... is not the case for me and potentially other power users.
Notes on the specific places that scale with tab count are below. I wanted to file one investigation issue first rather than splitting into multiple bugs, since most of the findings could be resolved with the same design change. Happy to scope this however maintainers prefer.
Related but distinct
I searched through related issues, and I believe that #1230 and #1918 are adjacent failure modes (frozen/discarded tabs; single-bad-tab hangs). The Chromium fix in #1230 (https://crrev.com/c/7772775) addresses one specific bad-tab failure mode but does not change the MCP's eager-load architecture. #1918 was closed as Edge-specific, but my issue reproduces with Chrome.
Reproduction
- Start (or have running) a Chrome instance with ~2000 tabs on one profile.
- Enable remote debugging via
chrome://inspect/#remote-debugging. (Note: this disables the HTTP discovery endpoint, so/json/version404s. The WebSocket is available atws://127.0.0.1:9222/devtools/browserwith no browser-id suffix.) - Configure the MCP to connect to that instance.
- Invoke any tool (
list_pagesis simplest).
Observed: Chrome UI becomes unresponsive within seconds and the browser process is killed/crashes. The tool call does not return.
Reproduced both via a normal MCP client and by piping JSON-RPC directly into the MCP server's stdin.
Expectation
list_pages and other tools work against large profiles without hanging or crashing the browser.
MCP configuration
{
"mcpServers": {
"chrome-devtools": {
"command": "npx",
"args": [
"chrome-devtools-mcp@latest",
"--wsEndpoint=ws://127.0.0.1:9222/devtools/browser"
]
}
}
}
Investigation
Cold start (McpContext#init, once per session)
-
UniverseManager.initatsrc/DevtoolsUtils.ts:71-90+:129-157creates a second CDP session per page viapage.createCDPSession(), then constructs a DevTools-frontendUniversewith a TargetManager and DebuggerModel, and sendsDebugger.setSkipAllPausesper model. At 2000 tabs this is ~2000 additional CDP sessions on top of the Puppeteer ones, plus 2000 DebuggerModel enables. -
browser.pages(...)atsrc/McpContext.ts:568attaches Puppeteer to every page-type target, triggering the usualPage.enable/Runtime.enable/Network.enable/Log.enable/Performance.enablecascade per session. Each enable emits initial events (frame tree, execution contexts, existing console entries) back over the wire. -
ConsoleCollector.initatsrc/PageCollector.ts:223-358installs aPageEventSubscriberper page (Runtime.exceptionThrown handler, framenavigated and issue listeners, a DevTools.IssueAggregator instance). Low cost per page, persistent memory cost across the session.
Every tool call with includePages set
-
McpResponsecallscontext.createPagesSnapshot()unconditionally when#includePagesis true (src/McpResponse.ts:433-434).setIncludePages(true)is set bylist_pages,select_page,close_page,new_page,navigate_page,resize_page, andhandle_dialog. -
detectOpenDevToolsWindowsatsrc/McpContext.ts:636-656runsawait Promise.all(pages.map(async page => { ... await page.hasDevTools() ... }))with no concurrency cap, and is called fromcreatePagesSnapshot:558. So Item #4 drives an unbounded parallel CDP fan-out across all pages on every tool call. -
Every response that sets
includePagesdumps each page's URL as text (src/McpResponse.ts:782-795). This is fine from the browser POV, but most models will quickly blow through their context token budget.
Every tab change
-
newPageandclosePageatsrc/McpContext.ts:260,276each re-runcreatePagesSnapshot(), which re-runs Item #5 across all tabs. -
Three handlers register for
targetcreated:NetworkCollectorandConsoleCollector(src/PageCollector.ts:78-79) andUniverseManager(src/DevtoolsUtils.ts:83-84). Each doesawait target.page()(Puppeteer attach) and its own setup. Scales with rate of tab change.
Suggested directions
Small, mechanical, independently mergeable:
- Cap concurrency on
detectOpenDevToolsWindows(Item #5) with something like a semaphore or a worker pool. - Add
limit/queryparams tolist_pagesand truncate the URL dump (Item #6). Orthogonal; helps model-context pressure on smaller profiles too.
Architectural, larger:
- Lazy attach.
list_pagesenumerates viabrowser.targets()metadata only, andMcpContextconstructs Puppeteer Pages and DevTools Universes only when a page is actually selected or operated on. Addresses Items #1, #2, #3, #7, #8.
Question for maintainers
Do you have any preference between:
a) one issue tracking the overall scaling bottleneck, with small PRs (concurrency cap, list_pages pagination) sent first while the architectural direction is discussed,
b) splitting into separate issues per item above, or
c) something else?
Happy to start with the concurrency cap and pagination patches as first PRs if that fits, though we would want to align on the architectural direction before spending time on a larger change.
Chrome DevTools MCP version
0.18.1
Chrome version
147.0.7727.101
Coding agent version
N/A. Reproduced by piping JSON-RPC directly into the MCP server's stdin.
Model version
N/A
Chat log
N/A (no chat client involved).
Node version
v22
Operating system
macOS 15.7.5
Extra checklist
- I want to provide a PR to fix this bug
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading UniverseManager.init in src/DevtoolsUtils.ts, browser.pages in src/McpContext.ts, and createPagesSnapshot in src/McpResponse.ts; reproduce the listed tool call with a large-tab Chrome profile if available. Trace the per-page setup and response snapshot work, then verify that list_pages and related tools complete without hanging or crashing Chrome at high tab counts.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100