- reduces the token usage.
- makes emulation and script compatible with CLI.
- documents .nullable() and .object() restrictions for the future.
- the emulation tools do not have nullable anymore and undefined would
clear the emulation instead. The model is thus required to provide all
emulation settings at once.
Closes https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/918
`type_text` is useful for pages that do not have a11y and, thus, uid is
not known. It's also useful for testing user-like keyboard input and
testing the focus state changes. The `fill` tools force the focus change
and require an uid and therefore are not suitable for these tasks.
## Summary
Enhances wait_for to support waiting on multiple possible texts and
resolve when any one appears.
This addresses long-running flows that can end in different UI outcomes
(for example, "Complete" or "Error"), avoiding unnecessary 300s waits
when only one expected string is provided.
Closes#916.
## Tool Update
### wait_for
Waits for text on the selected page, now with any-match support.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| text | string \| string[] | yes | A single text or a non-empty list of
texts. Resolves when any value appears. |
| timeout | integer | no | Maximum wait in ms (0 keeps default
behavior). |
---
## Design / Implementation
- Kept backward compatibility: existing single-string text calls
continue to work unchanged.
- Added schema support for string | string[] with non-empty array
validation.
- Updated context API to accept string | string[].
- Matching logic now normalizes to an array and races all candidates
across all frames using both:
- aria/<text>
- text/<text>
- Added clearer response output for array input:
- Element matching one of ["Complete","Error"] found.
- Updated generated tool docs for the new wait_for contract.
- Improved docs generation to render ZodUnion types (so union params are
documented correctly, not as unknown).
---
## Tests
Added/updated coverage for:
- Schema acceptance of:
- single string
- non-empty string array
- rejection of empty array
- Any-match array success case
- Any-match array when matching text appears later (async/delayed
content)
- Existing wait_for behavior remains covered for single-text usage
Executed relevant test suites:
- tests/tools/snapshot.test.ts
- tests/McpContext.test.ts
- tests/index.test.ts
Confirmation after the change applied:
https://opncd.ai/share/8m6I4r4a
## Summary
Adds storage-isolated browser contexts via an optional `isolatedContext`
parameter on the `new_page` tool, following the simplified design
proposed by @OrKoN in #926.
Pages created with the same `isolatedContext` name share cookies,
localStorage, and storage. Pages in different isolated contexts (or the
default context) are fully isolated — ideal for testing multi-user
real-time features like chat, notifications, or collaborative editing.
## Changes
### `new_page` tool
- New optional `isolatedContext: string` parameter
- If specified, creates/reuses a named `BrowserContext` and opens a page
in it
- If omitted, uses the default browser context (existing behavior
unchanged)
### `McpContext`
- `#isolatedContexts` Map: LLM-provided names → Puppeteer
`BrowserContext` instances
- `#pageToIsolatedContextName` WeakMap: GC-safe page → context name
reverse lookup
- Auto-discovery: externally created browser contexts get
`isolated-context-1`, `isolated-context-2`, etc.
- `getIsolatedContextName(page)`: returns the isolated context name for
a page (used by response formatting)
- `page.browserContext()` used for context membership detection (no
custom target event forwarding needed)
- No context cleanup in `dispose()` or `closePage()` — either the entire
browser is closed or we disconnect without destroying state
### `McpResponse`
- Page list includes `isolatedContext=${name}` labels (both text and
structured JSON output)
### `ToolDefinition`
- `Context` interface extended with `getIsolatedContextName(page)`
method
## What's NOT included (by design)
- **No `TargetEventEmitter`**: Puppeteer forwards target events from
`BrowserContext` → `Browser` internally
- **No context cleanup**: Browser contexts are not closed on `dispose()`
or page close, per maintainer guidance
- **No `about:blank` cleanup**: Default context and isolated contexts
coexist side-by-side
## Example
```
> new_page url="https://app.example.com/chat" isolatedContext="userA"
> new_page url="https://app.example.com/chat" isolatedContext="userB"
> list_pages
Page 1: [app.example.com/chat] isolatedContext=userA
Page 2: [app.example.com/chat] isolatedContext=userB [selected]
```
Pages in different isolated contexts have fully independent cookies,
localStorage, IndexedDB, and WebSocket connections.
## Tests
- 6 new tests covering `isolatedContext` feature in
`tests/tools/pages.test.ts`
- All existing tests pass (333+)
- Zero type errors, lint clean
Closes#926
---------
Co-authored-by: Alex Rudenko <alexrudenko@chromium.org>
Added workarounds for using chrome-devtools-mcp in WSL.
Drive-by: moved known issues from readme to troubleshooting.
Drive-by: updated skill to link to troubleshooting.
Drive-by: rephrased for clarity.
Docs-only change: add a troubleshooting note for macOS Web Bluetooth
chooser crashes in MCP-launched Chrome and the Bluetooth permission
workaround.
Fixes#917
## Summary
- Add `background` boolean parameter to the `new_page` tool
- When set to `true`, the new page opens in the background without
bringing it to the front
- Uses Puppeteer's existing `background` option for `browser.newPage()`
Fixes#826
---------
Co-authored-by: Alex Rudenko <OrKoN@users.noreply.github.com>
Co-authored-by: Alex Rudenko <alexrudenko@chromium.org>
bringToFront() not only brings the tab to front in the browser but also
the browser window itself. This PR fixes the issue by making the call to
bringToFront() optional allowing agents to bring a tab to the user's
attention if needed but not always. To mitigate the risk of selected
page that is in the background being throttled, this PR implements
emulation of the focused page to make background tabs run as usual.
If you manually inspect a network request in the DevTools UI, the Chrome
DevTools MCP server is now able to detect it and allow you to refer to
the selected request. The approach was tested in a couple of models.
In the list of the network requests we have a short indication about
which request is selected in DevTools UI. We refer to the DevTools as
"DevTools UI" to disambiguate from the DevTools MCP server.