文件历史

提交图

399 次代码提交

作者 SHA1 备注 提交日期
Wolfgang Beyer ed02047ae9 fix: Reset toolGroups before gathering toolGroups (#2200)
`getToolGroups` can be called multiple times. We want to reset the
`window.__dtmcp.toolGroups` array each time to prevent duplications.
2026-06-12 11:47:43 +00:00
Dominik Inführ 4f8eb7ad6b feat: Add the get_heapsnapshot_edges MCP tool (#2180)
This PR adds the get_heapsnapshot_edges MCP tool. Agents can use it to
look at the outgoing edges for a specifc object.

Co-authored-by: Dominik Inführ <dinfuehr@chromium.org>
2026-06-09 19:58:43 +00:00
Serhii Zghama b646feb4f3 feat: include page title in list_pages output (#2166)
## Motivation

`list_pages` shows each page's URL but not its title, which is painful
when multiple pages share a host — e.g. several tabs under
`app.example.com/u/0/`, `/u/1/`, `/u/2/`. There's no way to tell which
is which without visiting each one, even though every page has a usable
`document.title`.

Fixes #2156.
Closes #2175

## What this changes

- `list_pages` text output now shows the title before the URL when
available: `1: My Page (https://example.com) [selected]`. If the page
has no title (e.g. `about:blank`), the format is unchanged.
- The structured content entry for each page now includes a `title`
field alongside `id`, `url`, and `selected`.
- `page.title()` is awaited with a `.catch(() => '')` so a closed or
erroring page silently falls back to the URL-only format.
- `format()` is made `async` to support the `await` inside the page
loop; `createStructuredPage()` likewise becomes `async`.

## Testing

Start the MCP server with multiple tabs open. Call `list_pages` — pages
with titles now display as `id: Title (url)`. Pages without titles
(`about:blank`, data URLs) display as before.

---------

Co-authored-by: Piotr Paulski <31672205+zyzyzyryxy@users.noreply.github.com>
2026-06-09 16:04:12 +00:00
Nikolay Vitkov 834b259eb2 chore: expose loadResouce HostBinding (#2194)
This makes sure that if any resource that is loaded via the HostBinding
will be correctly checked agains the roots object.
2026-06-09 15:11:39 +00:00
Dominik Inführ a97c642d43 feat: Add retaining paths MCP tool (#2187)
This PR adds the `get_heapsnapshot_retaining_paths` MCP tool. This can
be used to find the paths from the target object to the GC roots which
keep that object alive.

Co-authored-by: Dominik Inführ <dinfuehr@chromium.org>
2026-06-09 12:53:30 +00:00
Nikolay Vitkov bede4fbdfa chore: install HostBindingAdapter (#2186)
This PR introduces the HostBindingAdapter to utilize the functions
usually available to DevTools.
Additionally I moved all the DevTools related files under a `devtools`
directory to better separate the extractor logic.
The patch scripts for DevTools were moved under a function to remove the
side-effect nature of the file.
Now gets called in a the creation of the McpContext (and a before hook
in test.)
2026-06-09 12:18:25 +00:00
Piotr Paulski aa33bff19f feat: add experimental TOON support for structured content output (#2042)
Adds `--experimentalToonFormat` boolean flag, controlling how structured
content is formatted in text response.
By default, custom shorthand format is used. With this flag, TOON format
(see https://github.com/toon-format/toon) is used instead.

TOON format is supposed to be more token-efficient and less error-prone
for agents to understand than json, but it's not clear if it will be
better on those metrics than the custom format used so far. (Evals
pending)

One clear benefit over custom format would be less code to maintain if
we decide to fully switch to TOON, due to dropping custom formatters and
reusing json formatters used for structuredContent anyways.

Co-authored-by: Piotr Paulski <piotrpaulski@chromium.org>
2026-06-08 13:41:58 +00:00
Nicholas Roscino 29e389848f feat: implement extension service worker logs (#1915)
This PR introduces the possiblity to collect console messages from
service workers.
2026-06-08 12:30:37 +00:00
Natasha Gorshunova 02b4492ca6 feat: support allowedUrlPattern & blockedUrlPattern Options (#2037)
## Support for Network Blocklists and Allowlists
(`--blocked-url-pattern` & `--allowed-url-pattern` arguments)

This PR adds support for CLI options to restrict network access in the
browser session via URL patterns.

### Key Features & How It Works

- **Pattern Matching:** Utilizes the [URLPattern
Standard](https://urlpattern.spec.whatwg.org/) for pattern matching.
- **Target Detachment:** Silently detaches from targets (pages/tabs)
whose URLs match blocked patterns (or do not match allowed patterns)
upon connection.
- **Runtime Blocking:** Prevents navigations and blocks runtime requests
(such as fetch/XHR and subresources) if they violate the pattern rules.
- **Mutual Exclusivity:** `--blocked-url-pattern` and
`--allowed-url-pattern` conflict with each other and cannot be
configured simultaneously.
- **Browser Requirements:**
  - **`--allowed-url-pattern`**: Requires **Chrome 149+**.
- **`--blocked-url-pattern`**: Works on Chrome versions older than 149,
but **Chrome 149+ is highly recommended**.

### Important Limitations & Side Effects

- **Network Emulation/Throttling Conflict:** Network throttling is
disabled when a network blocklist/allowlist is configured, to avoid
conflicting with Puppeteer's underlying blocking mechanisms.
- Using the `emulate` tool to modify `networkConditions` (e.g. setting
to `Offline`) will throw an error: *`Network throttling is not supported
when network blocking (allowlist/blocklist) is configured.`*
- Other emulation settings (e.g., `cpuThrottlingRate`, `geolocation`,
`viewport`) are unaffected and remain fully functional.

---

### Configuration Examples

#### 1. Blocking specific domains or endpoints (Blocklist)
Add the `--blocked-url-pattern` options to the `args` list in your MCP
settings file:

```json
{
  "mcpServers": {
    "chrome-devtools": {
      "command": "npx",
      "args": [
        "chrome-devtools-mcp@latest",
        "--blocked-url-pattern=*://*.blocked-example.com/*",
        "--blocked-url-pattern=*://*.another-blocked-example.com/*"
      ]
    }
  }
}
```

#### 2. Restricting access to authorized domains (Allowlist)
Add the `--allowed-url-pattern` options to restrict the browser to
permitted hosts (requires Chrome 149+):

```json
{
  "mcpServers": {
    "chrome-devtools": {
      "command": "npx",
      "args": [
        "chrome-devtools-mcp@latest",
        "--allowed-url-pattern=https://*.allowed-example.com/*",
        "--allowed-url-pattern=https://*.another-allowed-example.com/*"
      ]
    }
  }
}
```

---------

Co-authored-by: Natallia Harshunova <nharshunova@chromium.org>
Co-authored-by: Alex Rudenko <alexrudenko@chromium.org>
2026-06-08 09:20:00 +00:00
Nikolay Vitkov 0217397257 feat: memory debugging tools (#2169)
Updates the flag for the memory tooling to remove the experimental bit
(keep alias for backwards compatibility).
And updates the SKILLs to reflected the update names and point to the
available tools.

Q: Should it be called `take_heapsnapshot` or `take_heap_snapshot`?
2026-06-05 13:17:53 +00:00
Dominik Inführ 8713b93b41 feat: Adds close_heapsnapshot MCP tool (#2174)
This commit adds the close_heapsnapshot MCP tool such that the coding
agent can close heap snapshots again.

Co-authored-by: Dominik Inführ <dinfuehr@chromium.org>
Co-authored-by: Nicholas Roscino <nroscino@google.com>
2026-06-05 12:56:34 +00:00
Wolfgang Beyer 30d59a7872 feat: Handle multiple providers of third-party developer tools (#2168)
This allows a page to have multiple providers of third-party developer
tools, which each respond to the `devtoolstooldiscovery` event.

- Multiple `ToolGroup`s
- MCP tool responses only mention third-party developer tools, if there
are any. Otherwise this part of the output is skipped.
2026-06-02 15:07:32 +00:00
Nikolay Vitkov 2e039c09e1 refactor: use validate files on the tool level (#2152)
Fixes https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/2138
Closes #2150
2026-05-28 17:13:02 +00:00
Nicholas Roscino b39131172b chore: reflect emulated device in CrUX data (#2131)
CrUX data returned with the performance tool now reflects the emulated
device

Closes: #1813
2026-05-27 14:49:41 +00:00
Alex Rudenko f8fb2a9236 test: drop node20 code in tests (#2146) 2026-05-27 11:12:22 +00:00
dependabot[bot] f3ef0fb1ee chore(deps-dev): bump puppeteer from 25.0.4 to 25.1.0 in the bundled group (#2130)
Bumps the bundled group with 1 update:
[puppeteer](https://github.com/puppeteer/puppeteer).

Updates `puppeteer` from 25.0.4 to 25.1.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/puppeteer/puppeteer/releases">puppeteer's
releases</a>.</em></p>
<blockquote>
<h2>puppeteer-core: v25.1.0</h2>
<h2><a
href="https://github.com/puppeteer/puppeteer/compare/puppeteer-core-v25.0.4...puppeteer-core-v25.1.0">25.1.0</a>
(2026-05-26)</h2>
<h3>🎉 Features</h3>
<ul>
<li>roll to Chrome 149.0.7827.2 (<a
href="https://github.com/puppeteer/puppeteer/commit/af1b9be6b6a178f7ea6e197f738ca3cf99d786f7">af1b9be</a>)</li>
<li>roll to Firefox 151.0 (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/15013">#15013</a>)
(<a
href="https://github.com/puppeteer/puppeteer/commit/767ea549da1510f0838987f250b5d6be4e0f8960">767ea54</a>)</li>
</ul>
<h3>🛠️ Fixes</h3>
<ul>
<li>roll to Chrome 148.0.7778.178 (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/15014">#15014</a>)
(<a
href="https://github.com/puppeteer/puppeteer/commit/59764acccc9e1c7bca75a60472b288595d3f6cbf">59764ac</a>)</li>
</ul>
<h3>📄 Documentation</h3>
<ul>
<li>use ESM and top level await (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/15030">#15030</a>)
(<a
href="https://github.com/puppeteer/puppeteer/commit/34ecc62957bdd2c83820a51d5d1a6acb81e2957d">34ecc62</a>)</li>
</ul>
<h3>🏗️ Refactor</h3>
<ul>
<li>remove debug dependency (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/15023">#15023</a>)
(<a
href="https://github.com/puppeteer/puppeteer/commit/94d1e1c3dc84ed102d2e801a4e6343cd9fd4a9af">94d1e1c</a>)</li>
</ul>
<h3>Dependencies</h3>
<ul>
<li>The following workspace dependencies were updated
<ul>
<li>dependencies
<ul>
<li><code>@​puppeteer/browsers</code> bumped from 3.0.3 to 3.0.4</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>puppeteer: v25.1.0</h2>
<h2><a
href="https://github.com/puppeteer/puppeteer/compare/puppeteer-v25.0.4...puppeteer-v25.1.0">25.1.0</a>
(2026-05-26)</h2>
<h3>🎉 Features</h3>
<ul>
<li>roll to Chrome 149.0.7827.2 (<a
href="https://github.com/puppeteer/puppeteer/commit/af1b9be6b6a178f7ea6e197f738ca3cf99d786f7">af1b9be</a>)</li>
</ul>
<h3>🛠️ Fixes</h3>
<ul>
<li>improve progress bar and install (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/15042">#15042</a>)
(<a
href="https://github.com/puppeteer/puppeteer/commit/51db32a5bb48f40cc635ac3eaa2ebb60e6f5bfd5">51db32a</a>)</li>
<li>support concurrency in progress bars (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/15045">#15045</a>)
(<a
href="https://github.com/puppeteer/puppeteer/commit/ab0171d8f4206bdb9dd4e93c2db8d28530bf3fb9">ab0171d</a>)</li>
</ul>
<h3>🏗️ Refactor</h3>
<ul>
<li>replace cosmiconfig with lilconfig (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/15031">#15031</a>)
(<a
href="https://github.com/puppeteer/puppeteer/commit/4a1c2fffe634d430228cac3f8bc7a72f4b5a4a29">4a1c2ff</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/puppeteer/puppeteer/blob/main/CHANGELOG.md">puppeteer's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/puppeteer/puppeteer/compare/puppeteer-v25.0.4...puppeteer-v25.1.0">25.1.0</a>
(2026-05-26)</h2>
<h3>🎉 Features</h3>
<ul>
<li>roll to Chrome 149.0.7827.2 (<a
href="https://github.com/puppeteer/puppeteer/commit/af1b9be6b6a178f7ea6e197f738ca3cf99d786f7">af1b9be</a>)</li>
<li>roll to Firefox 151.0 (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/15013">#15013</a>)
(<a
href="https://github.com/puppeteer/puppeteer/commit/767ea549da1510f0838987f250b5d6be4e0f8960">767ea54</a>)</li>
</ul>
<h3>🛠️ Fixes</h3>
<ul>
<li>roll to Chrome 148.0.7778.178 (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/15014">#15014</a>)
(<a
href="https://github.com/puppeteer/puppeteer/commit/59764acccc9e1c7bca75a60472b288595d3f6cbf">59764ac</a>)</li>
</ul>
<h3>🏗️ Refactor</h3>
<ul>
<li>remove debug dependency (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/15023">#15023</a>)
(<a
href="https://github.com/puppeteer/puppeteer/commit/94d1e1c3dc84ed102d2e801a4e6343cd9fd4a9af">94d1e1c</a>)</li>
</ul>
<h3>Dependencies</h3>
<ul>
<li>The following workspace dependencies were updated
<ul>
<li>dependencies
<ul>
<li><code>@​puppeteer/browsers</code> bumped from 3.0.3 to 3.0.4</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3>📄 Documentation</h3>
<ul>
<li>use ESM and top level await (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/15030">#15030</a>)
(<a
href="https://github.com/puppeteer/puppeteer/commit/34ecc62957bdd2c83820a51d5d1a6acb81e2957d">34ecc62</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/ede66693bc0a6d9a8029f66288d13e26966173ce"><code>ede6669</code></a>
chore: release main (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/15056">#15056</a>)</li>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/7bc09e7d30e98687668dfe33089b9a3a633cece7"><code>7bc09e7</code></a>
chore(deps): bump the all group with 5 updates (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/15052">#15052</a>)</li>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/8c8117047020a49d61f1dff5e302f05ab672951d"><code>8c81170</code></a>
chore(deps): bump the all group in /website with 3 updates (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/15051">#15051</a>)</li>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/09eced565903369338ff7537b20727b24a284495"><code>09eced5</code></a>
chore: update lock</li>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/53b9fdadc131449377ed6de59162426140d29db6"><code>53b9fda</code></a>
chore(deps): bump the dependencies group with 2 updates (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/15049">#15049</a>)</li>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/d8424116590afac99369c0e996e0dfaf9029b34c"><code>d842411</code></a>
chore(deps): bump node from <code>050bf2b</code> to <code>8530f76</code>
in /docker in the all grou...</li>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/1d2a5696d3c7b592b8d65327d76cc2264f9fba9f"><code>1d2a569</code></a>
docs: document read-only Docker directories (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/15048">#15048</a>)</li>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/ab0171d8f4206bdb9dd4e93c2db8d28530bf3fb9"><code>ab0171d</code></a>
fix: support concurrency in progress bars (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/15045">#15045</a>)</li>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/51db32a5bb48f40cc635ac3eaa2ebb60e6f5bfd5"><code>51db32a</code></a>
fix: improve progress bar and install (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/15042">#15042</a>)</li>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/d32384baa5ef8bcd81319ee698e9d46edba1e957"><code>d32384b</code></a>
chore(deps): bump qs and express in /website (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/15040">#15040</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/puppeteer/puppeteer/compare/puppeteer-v25.0.4...puppeteer-v25.1.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=puppeteer&package-manager=npm_and_yarn&previous-version=25.0.4&new-version=25.1.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Alex Rudenko <alexrudenko@chromium.org>
2026-05-26 14:05:27 +00:00
Alex Rudenko 5ee13b3f21 test: improve webmcp tests (#2139) 2026-05-26 14:02:31 +00:00
Diego Ballesteros Villamizar 43b934cd98 fix: exit on stdin EOF and SIGTERM/SIGINT/SIGHUP, closing the browser cleanly (#2117)
Fixes #2116.

`chrome-devtools-mcp-main.ts` currently has no shutdown handler. After a
session calls `navigate_page` (or anything else that launches Chrome),
the Chrome subprocess keeps the Node event loop ref'd, so closing stdin
(the stdio MCP convention for "I'm done") doesn't make the server exit.
Callers that close stdin to terminate the server have to fall back to
SIGTERM / SIGKILL on every page-loaded session — deterministically, not
flakily.

This change:

1. Adds `closeBrowser()` in `browser.ts` that calls `browser.close()`
for launched instances (reaps the Chrome subprocess) and
`browser.disconnect()` for attached instances (leaves the user's Chrome
alive). No-op if no browser is active or the connection has already been
dropped.

2. Registers shutdown handlers in `chrome-devtools-mcp-main.ts` for:
   - `stdin.on('end' | 'close')` — stdio MCP transport convention
- `SIGTERM` / `SIGINT` / `SIGHUP` — clients that signal instead of
closing stdin (`SIGHUP` for parity with `src/daemon/daemon.ts`)

The handler is idempotent (guarded `shuttingDown` flag), and has an
unref'd 10s timeout backstop in case Chrome teardown hangs (slow
`beforeunload` handlers, many tabs, etc.).

### Note on scope

This complements (does not replace) the client-side fixes filed against
#1765, e.g. google-gemini/gemini-cli#13391 and
anthropics/claude-code#42300. The MCP stdio convention is that closing
stdin signals shutdown; a server that doesn't honor that forces every
client to special-case it. The watchdog sub-process
(`src/telemetry/watchdog/main.ts:145-146`) and the daemon
(`src/daemon/daemon.ts:224-230`) both already implement this for the
same reason — this PR extends the same pattern to the main entry point
so all three execution paths behave consistently.

### Measurement

Repro script in #2116, same env (chrome-devtools-mcp@1.0.1, Chrome
148.0.7778.178, Node v24.11.1, Linux), 10 iterations:

| Scenario | Before | After |
|---|---|---|
| `tools/list only` (no navigation) | 10/10 clean, 30-37 ms | 10/10
clean, 29-40 ms |
| `navigate example.com` | 10/10 SIGTERM at ~5080 ms | 10/10 clean at
145-180 ms |

### Notes

- I didn't add a subprocess-based test for this; the existing
`tests/utils.ts:runCli` infrastructure targets the `chrome-devtools`
CLI, not the stdio MCP server, and a shutdown-timing test would
introduce non-trivial Chrome-startup flakiness in CI. Happy to add one
if maintainers want it — pointer to the right test directory
appreciated.
2026-05-26 13:36:15 +00:00
Alex Rudenko 176eb69513 fix: use realpath for MCP roots validation (#2127) 2026-05-26 13:04:43 +00:00
Alex Rudenko 1b51a520f2 fix(cli): address pid file creation issues (#2124) 2026-05-26 09:28:46 +00:00
Wolfgang Beyer 57f32b0cd4 fix: Fix throttling info in performance trace output (#2096)
This addresses #1955.

Throttling information needs to be passed to the parser for the output
to be correct.
2026-05-22 08:08:56 +00:00
Wolfgang Beyer 3ade962a8d fix: Apply CPU throttling to secondary CDP session (#2092)
This addresses #1955 

CPU throttling needs to be applied to both the primary puppeteer session
and the secondary CDP session from the DevTools universe to have an
effect.

For network throttling this does not seem to be the case, I can see a
slowdown with the current implementation which only applies the network
throttling to the primary CDP session.

I also had to increase the navigation timeout to prevent timeout errors.
2026-05-22 07:17:30 +00:00
Pedro Durek 6992106d1c feat: add extraHttpHeaders emulation to emulate tool (#1176)
## Summary

Extend the existing `emulate` tool with an `extraHTTPHeaders` parameter
that calls Puppeteer's `page.setExtraHTTPHeaders()` (which uses CDP
`Network.setExtraHTTPHeaders` under the hood).

Closes #1175

## Approach

Per [feedback from
@natorion](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1175#issuecomment-4097587153),
this integrates into the existing `emulate` tool rather than adding a
standalone tool. The `emulate` tool is already the central hub for
page-level state modifications (userAgent, viewport, networkConditions,
geolocation, colorScheme), and custom HTTP headers fit naturally
alongside them. This also avoids increasing the MCP tool count and LLM
token overhead.

## Changes

- **`src/types.ts`** — Added `extraHTTPHeaders?: Record<string, string>`
to `EmulationSettings`
- **`src/tools/emulation.ts`** — Added `extraHTTPHeaders` as an optional
zod parameter on the `emulate` tool
- **`src/McpContext.ts`** — Added handler logic in the `emulate()`
method:
- Calls `page.setExtraHTTPHeaders()` when `extraHTTPHeaders` is provided
  - Clears from settings when an empty `{}` is passed
- Preserves existing headers when the param is **omitted** (unlike other
emulation settings that reset when omitted) — prevents
`emulate({colorScheme: "dark"})` from accidentally clearing
previously-set headers
- **`tests/tools/emulation.test.ts`** — Added 5 test cases:
  1. Sets extra headers on requests
  2. Clears headers with `{}`
  3. Headers persist across navigations
  4. Does not affect other emulation settings
  5. Reports correctly per-page (new page has no headers)

## Use Case

This enables setting custom HTTP headers on **all** requests — including
the initial document navigation and `<script>` tag loads — which
`initScript` cannot do since it runs after the document is already
fetched.

## Usage

```js
// Set headers
emulate({ extraHTTPHeaders: { "X-Custom": "value", "Authorization": "Bearer token" } })

// Clear headers
emulate({ extraHTTPHeaders: {} })

// Combine with other emulation settings
emulate({ extraHTTPHeaders: { "X-Branch": "feature-1" }, userAgent: "MyBot/1.0" })
```

---------

Co-authored-by: Alex Rudenko <alexrudenko@chromium.org>
Co-authored-by: Nicholas Roscino <nroscino@google.com>
2026-05-20 09:37:27 +00:00
Nikolay Vitkov 32dc50d59b chore(memory): update names and exposed information (#2079)
Update the tools to all include the `heapsnapshot` term for easier
handling.
Renames UID to ID to reduce confusion with the snapshot UIDs.
Renames Id to NodeId to better differentiate from the base Id.
Remove EdgeIndex as it was not useful.

Closes:
https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1970
2026-05-18 16:49:41 +00:00
lmlm a9fb555c80 fix: include saved image paths in CLI JSON output (#2070)
Fixes #1910

Summary:
- save image content before returning structured CLI JSON output
- include saved image metadata in `structuredContent.images`
- add coverage for JSON output with image content

Tests:
- `npm test -- tests/daemon/client.test.ts`
- `npx eslint src/daemon/client.ts tests/daemon/client.test.ts && npx
prettier --check src/daemon/client.ts tests/daemon/client.test.ts`

Co-authored-by: Nicholas Roscino <nroscino@google.com>
2026-05-18 13:46:41 +00:00
yulunz d0e6539ef4 fix: disable NetworkManager in DevTools (#1834)
Co-authored-by: Alex Rudenko <alexrudenko@chromium.org>
2026-05-18 12:31:52 +00:00
Alex Rudenko 213720b69c fix: improve geolocation emulation (#2036)
- add a message about successful configuration
- add a message about the currently emulated geolocation
- switch to comma separate format instead of `x` separator.

Tested with https://www.audero.it/demo/geolocation-api-demo.html
2026-05-18 12:13:12 +00:00
Nikolay Vitkov b2b05a0670 chore(memory): expose retainer logic (#2056)
Allows the LLM to query the heapsnapshot further to understand what the
retainer path logic.
2026-05-18 09:54:00 +00:00
dependabot[bot] 20021469dc chore(deps-dev): bump puppeteer from 24.43.0 to 25.0.2 in the bundled group across 1 directory (#2045)
Bumps the bundled group with 1 update in the / directory:
[puppeteer](https://github.com/puppeteer/puppeteer).

Updates `puppeteer` from 24.43.0 to 25.0.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/puppeteer/puppeteer/releases">puppeteer's
releases</a>.</em></p>
<blockquote>
<h2>puppeteer-core: v25.0.2</h2>
<h2><a
href="https://github.com/puppeteer/puppeteer/compare/puppeteer-core-v25.0.1...puppeteer-core-v25.0.2">25.0.2</a>
(2026-05-15)</h2>
<h3>🛠️ Fixes</h3>
<ul>
<li>update docs text (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14992">#14992</a>)
(<a
href="https://github.com/puppeteer/puppeteer/commit/36527b8b9dd856e11a372b46cba23409e5613573">36527b8</a>)</li>
</ul>
<h3>Dependencies</h3>
<ul>
<li>The following workspace dependencies were updated
<ul>
<li>dependencies
<ul>
<li><code>@​puppeteer/browsers</code> bumped from 3.0.1 to 3.0.2</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>puppeteer: v25.0.2</h2>
<h2><a
href="https://github.com/puppeteer/puppeteer/compare/puppeteer-v25.0.1...puppeteer-v25.0.2">25.0.2</a>
(2026-05-15)</h2>
<h3>♻️ Chores</h3>
<ul>
<li><strong>puppeteer:</strong> Synchronize puppeteer versions</li>
</ul>
<h3>Dependencies</h3>
<ul>
<li>The following workspace dependencies were updated
<ul>
<li>dependencies
<ul>
<li><code>@​puppeteer/browsers</code> bumped from 3.0.1 to 3.0.2</li>
<li>puppeteer-core bumped from 25.0.1 to 25.0.2</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>puppeteer-core: v25.0.1</h2>
<h2><a
href="https://github.com/puppeteer/puppeteer/compare/puppeteer-core-v25.0.0...puppeteer-core-v25.0.1">25.0.1</a>
(2026-05-13)</h2>
<h3>🛠️ Fixes</h3>
<ul>
<li>enabled features should take precedence over disabled features (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14985">#14985</a>)
(<a
href="https://github.com/puppeteer/puppeteer/commit/f6fd7c29f92e6183b2fd48f0571957306c58d440">f6fd7c2</a>)</li>
<li>roll to Chrome 148.0.7778.167 (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14980">#14980</a>)
(<a
href="https://github.com/puppeteer/puppeteer/commit/84c46fede6b02a1e9a00104b97b28c263f0c84df">84c46fe</a>)</li>
<li>roll to Firefox 150.0.3 (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14983">#14983</a>)
(<a
href="https://github.com/puppeteer/puppeteer/commit/872f77822d6b6b9b6510752d838107a967241bdb">872f778</a>)</li>
</ul>
<h3>Dependencies</h3>
<ul>
<li>The following workspace dependencies were updated
<ul>
<li>dependencies
<ul>
<li><code>@​puppeteer/browsers</code> bumped from 3.0.0 to 3.0.1</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>puppeteer: v25.0.1</h2>
<h2><a
href="https://github.com/puppeteer/puppeteer/compare/puppeteer-v25.0.0...puppeteer-v25.0.1">25.0.1</a>
(2026-05-13)</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/puppeteer/puppeteer/blob/main/CHANGELOG.md">puppeteer's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/puppeteer/puppeteer/compare/puppeteer-v25.0.1...puppeteer-v25.0.2">25.0.2</a>
(2026-05-15)</h2>
<h3>♻️ Chores</h3>
<ul>
<li><strong>puppeteer:</strong> Synchronize puppeteer versions</li>
</ul>
<h3>Dependencies</h3>
<ul>
<li>The following workspace dependencies were updated
<ul>
<li>dependencies
<ul>
<li><code>@​puppeteer/browsers</code> bumped from 3.0.1 to 3.0.2</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3>🛠️ Fixes</h3>
<ul>
<li>update docs text (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14992">#14992</a>)
(<a
href="https://github.com/puppeteer/puppeteer/commit/36527b8b9dd856e11a372b46cba23409e5613573">36527b8</a>)</li>
</ul>
<h2><a
href="https://github.com/puppeteer/puppeteer/compare/puppeteer-v25.0.0...puppeteer-v25.0.1">25.0.1</a>
(2026-05-13)</h2>
<h3>♻️ Chores</h3>
<ul>
<li><strong>puppeteer:</strong> Synchronize puppeteer versions</li>
</ul>
<h3>Dependencies</h3>
<ul>
<li>The following workspace dependencies were updated
<ul>
<li>dependencies
<ul>
<li><code>@​puppeteer/browsers</code> bumped from 3.0.0 to 3.0.1</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3>🛠️ Fixes</h3>
<ul>
<li>enabled features should take precedence over disabled features (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14985">#14985</a>)
(<a
href="https://github.com/puppeteer/puppeteer/commit/f6fd7c29f92e6183b2fd48f0571957306c58d440">f6fd7c2</a>)</li>
<li>roll to Chrome 148.0.7778.167 (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14980">#14980</a>)
(<a
href="https://github.com/puppeteer/puppeteer/commit/84c46fede6b02a1e9a00104b97b28c263f0c84df">84c46fe</a>)</li>
<li>roll to Firefox 150.0.3 (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14983">#14983</a>)
(<a
href="https://github.com/puppeteer/puppeteer/commit/872f77822d6b6b9b6510752d838107a967241bdb">872f778</a>)</li>
</ul>
<h2><a
href="https://github.com/puppeteer/puppeteer/compare/puppeteer-v24.43.1...puppeteer-v25.0.0">25.0.0</a>
(2026-05-12)</h2>
<h3>⚠ BREAKING CHANGES</h3>
<ul>
<li>remove deprecated Puppeteer.product (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14977">#14977</a>)</li>
<li>bump min NodeJS to 22 (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14973">#14973</a>)</li>
<li>return a Promise for executablePath, defaultArgs (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14965">#14965</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/3aadc38c533caa8df87f381868291ede870883e2"><code>3aadc38</code></a>
chore: release main (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14993">#14993</a>)</li>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/36527b8b9dd856e11a372b46cba23409e5613573"><code>36527b8</code></a>
fix: update docs text (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14992">#14992</a>)</li>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/3ea7bd54b97965fb0e1b83a2c017720162785c92"><code>3ea7bd5</code></a>
fix: capitalize &quot;Chrome&quot; in troubleshooting.md (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14991">#14991</a>)</li>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/ae72fdbec9720c982fc2ed818036d7be9b2aa1dc"><code>ae72fdb</code></a>
chore: Tiny punctuation update in troubleshooting.md (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14990">#14990</a>)</li>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/1597fde55de1e7b3c31032aa43dce0607b4307d3"><code>1597fde</code></a>
chore: release main (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14982">#14982</a>)</li>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/f6fd7c29f92e6183b2fd48f0571957306c58d440"><code>f6fd7c2</code></a>
fix: enabled features should take precedence over disabled features (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14985">#14985</a>)</li>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/bf05fb9bf5bac997e365eda2e31c6067e5ec1677"><code>bf05fb9</code></a>
fix: update browsers to trigger release (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14984">#14984</a>)</li>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/872f77822d6b6b9b6510752d838107a967241bdb"><code>872f778</code></a>
fix: roll to Firefox 150.0.3 (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14983">#14983</a>)</li>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/84c46fede6b02a1e9a00104b97b28c263f0c84df"><code>84c46fe</code></a>
fix: roll to Chrome 148.0.7778.167 (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14980">#14980</a>)</li>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/ee655d8292f37cc33f279746ef72613e5ccb5db8"><code>ee655d8</code></a>
chore(main): release ng-schematics 0.8.0 (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14978">#14978</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/puppeteer/puppeteer/compare/puppeteer-v24.43.0...puppeteer-v25.0.2">compare
view</a></li>
</ul>
</details>
<br />

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Alex Rudenko <alexrudenko@chromium.org>
2026-05-17 06:34:22 +00:00
lmlm 041b208378 fix: report unknown tool arguments (#2064)
## Summary
- register tool input schemas as passthrough so extra named arguments
reach ToolHandler validation
- report unknown arguments with an explicit error that names the unknown
and expected arguments
- stop before invoking tool handlers when unknown arguments are present
- add ToolHandler coverage for reporting an extra argument

Fixes #1940

## Tests
- `npm run check-format`
- `npx tsc --noEmitOnError false` *(emits build artifacts but still
reports the existing `chrome-devtools-frontend` type conflict in
`ModelImpl.ts`)*
- `node --experimental-strip-types --no-warnings=ExperimentalWarning
scripts/post-build.ts`
- `NODE_TEST_REPORTER=spec npm run test:no-build --
tests/ToolHandler.test.ts`
2026-05-15 15:52:57 +00:00
yulunz e14a74c859 chore: disallow underscores followed by numbers in metrics names (#2058)
Underscore followed by numbers is not encouraged in the proto style
guide. See "Underscores in Identifiers" in
https://protobuf.dev/programming-guides/style/.

This recently became an issue because we have `list_3p_developer_tools`
and `execute_3p_developer_tool` which would have been dis-allowed. This
change replaces them with `list3p_developer_tools` and
`execute3p_developer_tool` respectively, as suggested by the style
guide.

This only affects the logged version. The tool name is still the
existing one.

This transformation is also applied to other similar places, like flag
names, tool name in error logging, and tool args.

The `tool_name_metrics.json` was manually updated because we never
landed the server side change because it was disallowed by proto style
check.
2026-05-14 20:31:44 +00:00
@masamaru0513 90d368d343 feat: support filePath in evaluate_script (#2054)
## Summary

Adds an optional `filePath` parameter to `evaluate_script` that saves
the script output to a file instead of returning it inline.

Refs #153

## Motivation

Issue #153 requested `filePath` support for `take_snapshot` and
`evaluate_script`. `take_snapshot` was addressed in #463. PR #248
previously attempted this but was closed due to conflicts. This PR
implements the same feature on the current codebase, completing the
remaining piece.

## Changes

- Add optional `filePath` parameter to the `evaluate_script` schema
- Add `context.validatePath(filePath)` call for path validation
- Pass `{filePath, context}` options to `performEvaluation()`
- In `performEvaluation()`: when `filePath` is provided, save output via
`context.saveFile()` with `.json` extension; otherwise return inline as
before
- Update `docs/tool-reference.md` via `npm run docs:generate`
- Add unit test for file output

## Key design decisions

- **Same pattern as existing tools**: Follows the `context.saveFile()`
pattern established by `take_snapshot` (#463), `take_screenshot`,
`get_network_request` (#795), and performance tools (#686).
- **Minimal change surface**: Only `performEvaluation()` gains an
optional `options` parameter. No new interfaces or abstractions.
- **Backwards compatible**: `filePath` is optional. When omitted,
behavior is identical to before.

## Testing

**Unit test added** (`tests/tools/script.test.ts`):
- Call `evaluate_script` with `filePath` set to a temp file
- Assert response contains "Output saved to"
- Assert file content matches the JSON-serialized return value
- Clean up temp file in `finally` block

**Manual testing performed**:
- `() => document.title` with `filePath: /tmp/test.json` → file contains
`"Example Domain"`
- `() => document.title` without `filePath` → inline ```json block
returned (no regression)
- `() => Array.from({length: 100}, ...)` with `filePath` → 100-item
array saved correctly
- `filePath` pointing to non-existent directory → directory
auto-created, file saved
- Relative path (`test.json`) → resolved to CWD, absolute path shown in
response
- Function that throws → error returned, no partial file created
- Existing file as `filePath` → file overwritten completely

---------

Co-authored-by: Alex Rudenko <alexrudenko@chromium.org>
2026-05-14 08:33:27 +00:00
yulunz 71ccdb0dbf chore: better organize telemetry utilities (#2057)
There is no behavior change. 

This groups utilities into two modules:
- `transformation.ts`: for any logic related to mutating / filtering of
the names, values of telemetry entries.
- `metricsRegistry.ts`: for any logic that related to the maintenance of
metrics.json files.
2026-05-14 05:33:40 +00:00
Nikolay Vitkov f6a12be091 refactor: waitForResult helpers (#2041) 2026-05-13 12:31:33 +00:00
yulunz 9a1ebc724b chore: log read / write errors when persisting the telemetry state file (#2016)
This adds logging to the read & write operations to the telemetry state
file. In particular,

- for read, no error is logged if the state file doesn't exist, which is
expected to happen when the user is new. An error is logged otherwise
(e.g. file format error, errors when reading an existing file like
permission issue).
- for write, any error in the path will be logged.

This commit also puts the instantiation of the `Persistence` object out
of the `ClearcutLogger` object to avoid circular dependency.
2026-05-12 21:23:05 +00:00
Roger b5948582a0 feat: report new URL after actions that trigger navigation (#1853)
## Summary

- Input tools (`click`, `fill`, `press_key`, `hover`, `drag`,
`type_text`, `fill_form`, `click_at`) and `evaluate_script` now append a
`Page navigated to <url>.` line to the response when the action triggers
a cross-document navigation.
- `WaitForHelper.waitForEventsAfterAction` returns `{navigated:
boolean}` instead of `void`, surfacing the navigation signal that was
already being detected internally.
- No change to `navigate_page` or `new_page` since they already report
the URL explicitly.

Fixes #243

## Why

Today, if a `click` causes a page navigation, the response says
*"Successfully clicked on the element"* with no indication that the page
URL changed. The agent has to make an extra `list_pages` call to
discover where it landed. This saves that round-trip for every
navigation-triggering action.

## Design

The existing `waitForNavigationStarted` in `WaitForHelper` already knows
whether a cross-document navigation started. We propagate that signal as
`{navigated: boolean}` through the return value of
`waitForEventsAfterAction` → `McpPage` → `ContextPage` interface, and
let each handler append the URL line when `navigated` is true.

Same-document (history API) navigations remain filtered out by the
existing `waitForNavigationStarted` logic, matching current behavior.
Click-opens-new-tab is a separate concern (#367).

## Test plan

- [x] New test: click on a link that causes navigation → response
includes `Page navigated to <url>.`
- [x] New test: click on a button that doesn't navigate → no navigation
line in response
- [x] Full test suite (563 tests) passes
- [x] TypeScript typecheck clean
- [x] ESLint + Prettier clean
2026-05-12 15:06:21 +00:00
Alex Rudenko 85f935b2be fix: do not use getSelectedMcpPage (#2039)
Drive-by: clean up formatting and arg use.

Refs: https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/2033
2026-05-12 11:56:52 +00:00
Alex Rudenko 178b790493 refactor: extract ToolHandler (#2032)
Follow-up for
https://github.com/ChromeDevTools/chrome-devtools-mcp/pull/2030
2026-05-11 14:56:47 +00:00
dependabot[bot] aa5e21cd02 chore(deps): bump fast-uri from 3.1.0 to 3.1.2 (#2024)
Bumps [fast-uri](https://github.com/fastify/fast-uri) from 3.1.0 to
3.1.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/fastify/fast-uri/releases">fast-uri's
releases</a>.</em></p>
<blockquote>
<h2>v3.1.2</h2>
<h2>⚠️ Security Release</h2>
<ul>
<li>Fix for <a
href="https://github.com/fastify/fast-uri/security/advisories/GHSA-v39h-62p7-jpjc">https://github.com/fastify/fast-uri/security/advisories/GHSA-v39h-62p7-jpjc</a></li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>Handle malformed fragment decoding as a parse error by <a
href="https://github.com/mcollina"><code>@​mcollina</code></a> in <a
href="https://redirect.github.com/fastify/fast-uri/pull/171">fastify/fast-uri#171</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/fastify/fast-uri/compare/v3.1.1...v3.1.2">https://github.com/fastify/fast-uri/compare/v3.1.1...v3.1.2</a></p>
<h2>v3.1.1</h2>
<h2>⚠️ Security Release</h2>
<ul>
<li>Fix for <a
href="https://github.com/fastify/fast-uri/security/advisories/GHSA-q3j6-qgpj-74h6">https://github.com/fastify/fast-uri/security/advisories/GHSA-q3j6-qgpj-74h6</a></li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>build(deps-dev): bump tsd from 0.32.0 to 0.33.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/fastify/fast-uri/pull/148">fastify/fast-uri#148</a></li>
<li>build(deps): bump actions/checkout from 4 to 5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/fastify/fast-uri/pull/149">fastify/fast-uri#149</a></li>
<li>chore(.npmrc): ignore scripts by <a
href="https://github.com/Fdawgs"><code>@​Fdawgs</code></a> in <a
href="https://redirect.github.com/fastify/fast-uri/pull/150">fastify/fast-uri#150</a></li>
<li>build(deps-dev): remove <code>@​fastify/pre-commit</code> by <a
href="https://github.com/Fdawgs"><code>@​Fdawgs</code></a> in <a
href="https://redirect.github.com/fastify/fast-uri/pull/151">fastify/fast-uri#151</a></li>
<li>build(deps): bump actions/setup-node from 4 to 5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/fastify/fast-uri/pull/152">fastify/fast-uri#152</a></li>
<li>ci(ci): add concurrency config by <a
href="https://github.com/Fdawgs"><code>@​Fdawgs</code></a> in <a
href="https://redirect.github.com/fastify/fast-uri/pull/153">fastify/fast-uri#153</a></li>
<li>build(deps): bump actions/setup-node from 5 to 6 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/fastify/fast-uri/pull/154">fastify/fast-uri#154</a></li>
<li>build(deps): bump actions/checkout from 5 to 6 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/fastify/fast-uri/pull/156">fastify/fast-uri#156</a></li>
<li>chore(license): standardise license notice by <a
href="https://github.com/Fdawgs"><code>@​Fdawgs</code></a> in <a
href="https://redirect.github.com/fastify/fast-uri/pull/159">fastify/fast-uri#159</a></li>
<li>style: remove trailing whitespace by <a
href="https://github.com/Fdawgs"><code>@​Fdawgs</code></a> in <a
href="https://redirect.github.com/fastify/fast-uri/pull/161">fastify/fast-uri#161</a></li>
<li>ci: remove unused github files by <a
href="https://github.com/Tony133"><code>@​Tony133</code></a> in <a
href="https://redirect.github.com/fastify/fast-uri/pull/162">fastify/fast-uri#162</a></li>
<li>chore: update readme by <a
href="https://github.com/Tony133"><code>@​Tony133</code></a> in <a
href="https://redirect.github.com/fastify/fast-uri/pull/164">fastify/fast-uri#164</a></li>
<li>build(deps): bump
fastify/workflows/.github/workflows/plugins-ci-package-manager.yml from
5 to 6 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/fastify/fast-uri/pull/165">fastify/fast-uri#165</a></li>
<li>build(deps): bump fastify/workflows/.github/workflows/plugins-ci.yml
from 5 to 6 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/fastify/fast-uri/pull/166">fastify/fast-uri#166</a></li>
<li>build(deps-dev): bump neostandard from 0.12.2 to 0.13.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/fastify/fast-uri/pull/167">fastify/fast-uri#167</a></li>
<li>ci: add lock-threads workflow by <a
href="https://github.com/Fdawgs"><code>@​Fdawgs</code></a> in <a
href="https://redirect.github.com/fastify/fast-uri/pull/169">fastify/fast-uri#169</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Tony133"><code>@​Tony133</code></a> made
their first contribution in <a
href="https://redirect.github.com/fastify/fast-uri/pull/162">fastify/fast-uri#162</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/fastify/fast-uri/compare/v3.1.0...v3.1.1">https://github.com/fastify/fast-uri/compare/v3.1.0...v3.1.1</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/fastify/fast-uri/commit/919dd8ea7689fcc220d0d9b71307f5095e723ef9"><code>919dd8e</code></a>
Bumped v3.1.2</li>
<li><a
href="https://github.com/fastify/fast-uri/commit/c65ba573714af6b8e19e481d9444c27bc4355d07"><code>c65ba57</code></a>
fixup: linting</li>
<li><a
href="https://github.com/fastify/fast-uri/commit/6c86c17c3d76fb93aa3700ec6c0fa00faeb97293"><code>6c86c17</code></a>
Merge commit from fork</li>
<li><a
href="https://github.com/fastify/fast-uri/commit/a95158ad308df4d92bbde4eba699ce5165e9f796"><code>a95158a</code></a>
Handle malformed fragment decoding without throwing (<a
href="https://redirect.github.com/fastify/fast-uri/issues/171">#171</a>)</li>
<li><a
href="https://github.com/fastify/fast-uri/commit/cea547c91c6aae610041b17b75792ca4aa035a6d"><code>cea547c</code></a>
Bumped v3.1.1</li>
<li><a
href="https://github.com/fastify/fast-uri/commit/876ce79b662c3e5015e4e7dffe6f37752ad34f35"><code>876ce79</code></a>
Merge commit from fork</li>
<li><a
href="https://github.com/fastify/fast-uri/commit/dcdf690b71a7bb3a19887ada65a9ab160d83bcc0"><code>dcdf690</code></a>
ci: add lock-threads workflow (<a
href="https://redirect.github.com/fastify/fast-uri/issues/169">#169</a>)</li>
<li><a
href="https://github.com/fastify/fast-uri/commit/c860e6589b1ac346f66e114b4eadb9613768108c"><code>c860e65</code></a>
build(deps-dev): bump neostandard from 0.12.2 to 0.13.0 (<a
href="https://redirect.github.com/fastify/fast-uri/issues/167">#167</a>)</li>
<li><a
href="https://github.com/fastify/fast-uri/commit/9b4c6dc82fde0ca44e674403ece9185d85bb6d5f"><code>9b4c6dc</code></a>
build(deps): bump fastify/workflows/.github/workflows/plugins-ci.yml (<a
href="https://redirect.github.com/fastify/fast-uri/issues/166">#166</a>)</li>
<li><a
href="https://github.com/fastify/fast-uri/commit/85d09a9f7aa76b32c2bb005a90a71e144c361d24"><code>85d09a9</code></a>
build(deps): bump
fastify/workflows/.github/workflows/plugins-ci-package-mana...</li>
<li>Additional commits viewable in <a
href="https://github.com/fastify/fast-uri/compare/v3.1.0...v3.1.2">compare
view</a></li>
</ul>
</details>
<br />

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Alex Rudenko <alexrudenko@chromium.org>
2026-05-11 11:26:11 +00:00
Alex Rudenko 8e06761572 fix: only require a page in page-scoped tools (#2030)
getSelectedMcpPage and getPageById throw if the page is not found, so
these should only be called for page-scoped tools.
2026-05-11 09:39:23 +00:00
Samiya Caur 64a02d8c8e test: fix flaky navigate_page with open dialog test (#2020)
Attempt to fix flakiness reported in #2019
2026-05-08 11:20:49 +00:00
yulunz 06e0ab6022 feat: add an error logging method (#2006) 2026-05-07 23:06:18 +00:00
Piotr Paulski 407c2bd03f fix: Make fill_form more appealing when filling forms with checkboxes (#1971)
Fixes #1942

Verified using `npm run eval --
scripts/eval_scenarios/fill_select_and_checkboxes_test.ts`

Without this change, I observed 7 runs using fill_form for all controls
at once, 14 runs using click to select checkboxes and 10 runs that did
nothing (total 31 runs)

After this change: 9 fill_form using runs (passes), 1 click based
approach and 10 no-attempt fails (20 runs total)

Depending how we count the no-attempt runs, its either increase from 23%
to 45% or 33% to 90% in eval pass rate.

Co-authored-by: Piotr Paulski <piotrpaulski@chromium.org>
2026-05-07 15:00:52 +00:00
yulunz a0d6ea1a62 chore: make Clearcut logger a global singleton (#1999)
We will add a error logging method to ClearcutLogger in a follow-up PR.
Since the error can happen anywhere in the stack, the logger instance
has to be readily available (i.e. w/o passing the logger instance
everywhere). This commit registers the instantiated logger as a global
singleton, and makes it possible to retrieve it by a static method
(`ClearcutLogger.get()`) wherever we need it.
2026-05-07 05:46:24 +00:00
Wolfgang Beyer 7548c97663 feat: support third-party developer tools (#1982)
Enables "third-party developer tools" feature. This allows the inspected
web page to expose tools which provide debugging information to Chrome
DevTools for Agents.

Third-party developer tools enable web applications to expose internal
state, component hierarchies, or specific debug data that cannot be
deduced through static analysis. This allows Chrome DevTools for Agents
to provide richer, more actionable context to AI agents during debugging
sessions.

2 additional tools are enabled in Chrome DevTools for Agents for
interacting with third-party developer tools:
`list_3p_developer_tools()` and `execute_3p_developer_tool`.

Code changes in this PR:
- Rename "in-page tools" to "third-party developer tools"
- Unhide
- Make available in CLI
- Add documentation
2026-05-06 12:43:34 +00:00
Alex Rudenko f45f0681a2 fix: make sure env variables are consistently applied when parsing args (#1994)
This PR moves the checks for CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS and
CI env vars to parseArguments making sure it is correctly applied by the
daemon and in tests. It also updates the tests to set explicit
CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS as it might not always be
inherited. This change is likely to affect the metrics collected and
might explain some fluctuations we observed.
2026-05-05 15:44:55 +00:00
Alex Rudenko da0441d425 docs: extract WebMCP into its own category (#1993)
Extracting WebMCP tools into a separate category for better grouping in
the docs. This changes `--experimentalWebmcp` to
`--categoryExperimentalWebmcp` to align with other experimental
categories. Debugging category was not a good fit since the tools
provided by WebMCP are not necessarily used for debugging.

cc @beaufortfrancois
2026-05-05 12:50:42 +00:00
cooleryu 510ec0f48b fix(input): stop native select option clicks from timing out (#1960)
## Summary

Teach the `click` tool to handle accessibility snapshot targets that
point at an `option` inside a native, single-select `<select>` element.

When the target is a native select option, `click` now selects that
option through the owning `<select>` element instead of asking Puppeteer
to click an option node that has no clickable box while the dropdown is
collapsed. Other option-like targets, including custom ARIA options,
continue through the normal click path.

## Motivation

Fixes #1941.

The text snapshot can expose native `<option>` nodes with stable uids.
This makes it natural for an agent to call `click` on an option uid
after seeing the desired option in the snapshot.

However, a collapsed native `<select>` does not expose its child
`<option>` nodes as directly clickable page boxes. In that state, the
option can exist in the DOM and accessibility tree while still having no
clickable geometry. Puppeteer therefore waits for the option to become
interactive and eventually times out.

The existing `fill` tool already handles selecting native `<select>`
options. This change keeps that guidance explicit in the `click` tool
description, while also making `click(option_uid)` robust for the native
select case that appears in the snapshot.

## Changes

- Added a constrained native select fallback in `click`:
  - Only runs for single-click requests.
  - Only runs when the snapshot node role is `option`.
- Only handles real `HTMLOptionElement` nodes owned by a native
`<select>`.
- Does not handle disabled selects, disabled options, disabled
optgroups, or multi-selects.
- Falls back to the existing locator click behavior for all other
targets.
- Dispatches `input` and `change` events when selecting a different
native option.
- Updated the `click` tool description to steer agents toward `fill` for
native `<select>` option selection.
- Regenerated CLI/tool reference docs with `npm run gen`.
- Added regression coverage for:
  - Clicking an option uid in a collapsed native `<select>`.
  - Clicking an option uid inside a native `<optgroup>`.
- Clicking a custom ARIA `role="option"` element through the normal
click path.

## Test Plan

Passed:

```bash
npm run test -- tests/tools/input.test.ts
npm run check-format
```

Also attempted:

```bash
npm run test
```

The full suite hit unrelated local failures outside this change area:

- `tests/tools/network.test.ts`: snapshot ordering difference for
redirected requests.
- `tests/tools/screenshot.test.ts`: `Page.captureScreenshot` failed for
the large full-page screenshot case with `Page is too large`.

The changed input tool tests pass locally.

## Risk

Low. The fallback is intentionally narrow:

- It is gated by the accessibility role being `option`.
- It verifies the DOM node is an actual `HTMLOptionElement`.
- It only applies to native, non-disabled, single-select `<select>`
controls.
- It does not reinterpret custom combobox/listbox implementations.
- It preserves the existing locator click path for non-native option
targets.

The main behavior change is that `click(option_uid)` can now succeed for
native collapsed dropdowns that previously timed out.

## Related Issue

Closes #1941.

## Maintainer Context

This targets a small but high-impact mismatch between the snapshot
representation and browser interaction semantics.

The snapshot correctly exposes native options because they exist in the
accessibility tree. The click implementation previously treated that uid
like any other clickable element, but collapsed native options do not
have normal clickable layout boxes. This PR makes the native select case
explicit without expanding `click` into a general custom dropdown
heuristic.

The tool description still recommends `fill` for native `<select>`
selection so agents are guided toward the more direct tool. The code
fallback exists for the common case where an agent already selected an
option uid from the snapshot.
2026-05-04 09:12:43 +00:00
Alex Rudenko a90378adf3 fix: always allow tmpdir access with client roots (#1984)
This PR changes the implementation to allow access to tmpdir even if the
client is not configured it explicitly because several tools default to
the tmpdir for outputs. Many clients like gemini-cli/claude do not
configure the tmp dir as a root by default.
2026-04-30 12:25:35 +00:00
Nicholas Roscino b2b3e99d67 feat(cli): generate commands for conditional tools (#1962)
This PR adds all tools in the CLI interface. When a tool is not enabled
the server responds with an error guiding the user on how to enable the
category or the experiment.

Closes:
https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1933
2026-04-30 07:59:08 +00:00