chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:30:05 +08:00
commit 51d876a392
274 changed files with 121542 additions and 0 deletions
+102
View File
@@ -0,0 +1,102 @@
# Chrome DevTools CLI
The `chrome-devtools-mcp` package includes an **experimental** CLI interface that allows you to interact with the browser directly from your terminal. This is particularly useful for debugging or when you want an agent to generate scripts that automate browser actions.
## Getting started
Install the package globally to make the `chrome-devtools` command available:
```sh
npm i chrome-devtools-mcp@latest -g
chrome-devtools status # check if install worked.
```
## How it works
The CLI acts as a client to a background `chrome-devtools-mcp` daemon (uses Unix sockets on Linux/Mac and named pipes on Windows).
- **Automatic Start**: The first time you call a tool (e.g., `list_pages`), the CLI automatically starts the MCP server and the browser in the background if they aren't already running.
- **Persistence**: The same background instance is reused for subsequent commands, preserving the browser state (open pages, cookies, etc.).
- **Manual Control**: You can explicitly manage the background process using `start`, `stop`, and `status`. The `start` command forwards all subsequent arguments to the underlying MCP server (e.g., `--headless`, `--userDataDir`) but not all args are supported. Run `chrome-devtools start --help` for supported args. Headless is enabled by default. Isolated is enabled by default unless `--userDataDir` is provided.
```sh
# Check if the daemon is running
chrome-devtools status
# Navigate the current page to a URL
chrome-devtools navigate_page "https://google.com"
# Take a screenshot and save it to a file
chrome-devtools take_screenshot --filePath screenshot.png
# Stop the background daemon when finished
chrome-devtools stop
```
## Command Usage
The CLI only supports tools available in the MCP server without additional arguments (see [Tool reference](./tool-reference.md)).
Thus, `--categoryExtensions` tools are currently not available in the CLI.
```sh
chrome-devtools <tool> [arguments] [flags]
```
- **Required Arguments**: Passed as positional arguments.
- **Optional Arguments**: Passed as flags (e.g., `--filePath`, `--fullPage`).
### Examples
**New Page and Navigation:**
```sh
chrome-devtools new_page "https://example.com"
chrome-devtools navigate_page "https://web.dev" --type url
```
**Interaction:**
```sh
# Click an element by its UID from a snapshot
chrome-devtools click "element-uid-123"
# Fill a form field
chrome-devtools fill "input-uid-456" "search query"
```
**Analysis:**
```sh
# Run a Lighthouse audit (defaults to navigation mode)
chrome-devtools lighthouse_audit --mode snapshot
```
## Output format
By default, the CLI outputs a human-readable summary of the tool's result. For programmatic use, you can request raw JSON:
```sh
chrome-devtools list_pages --output-format=json
```
## Troubleshooting
If the CLI hangs or fails to connect, try stopping the background process:
```sh
chrome-devtools stop
```
For more verbose logs, set the `DEBUG` environment variable:
```sh
DEBUG=* chrome-devtools list_pages
```
## CLI generation
Implemented in `scripts/generate-cli.ts`. Some commands are excluded from CLI
generation such as `wait_for` and `fill_form`.
`chrome-devtools-mcp` args are also filtered in `src/bin/chrome-devtools.ts`
because not all args make sense in a CLI interface.
+30
View File
@@ -0,0 +1,30 @@
# Experimental: Debugging Chrome on Android
This is an experimental feature as Puppeteer does not officially support Chrome on Android as a target.
The workflow below works for most users. See [Troubleshooting: DevTools is not detecting the Android device for more help](https://developer.chrome.com/docs/devtools/remote-debugging#troubleshooting) for more help.
1. Open the Developer Options screen on your Android. See [Configure on-device developer Options](https://developer.android.com/studio/debug/dev-options.html).
2. Select Enable USB Debugging.
3. Connect your Android device directly to your development machine using a USB cable.
4. On your development machine setup port forwarding from your development machine to your android device:
```shell
adb forward tcp:9222 localabstract:chrome_devtools_remote
```
5. Configure your MCP server to connect to the Chrome
```json
"chrome-devtools": {
"command": "npx",
"args": [
"chrome-devtools-mcp@latest",
"--wsEndpoint=ws://127.0.0.1:9222/devtools/browser/"
],
"trust": true
}
```
6. Test your setup by running the following prompt in your coding agent:
```none
Check the performance of developers.chrome.com
```
The Chrome DevTools MCP server should now control Chrome on your Android device.
+12
View File
@@ -0,0 +1,12 @@
# Design Principles
These are rough guidelines to follow when shipping features for the MCP server.
Apply them with nuance.
- **Agent-Agnostic API**: Use standards like MCP. Don't lock in to one LLM. Interoperability is key.
- **Token-Optimized**: Return semantic summaries. "LCP was 3.2s" is better than 50k lines of JSON. Files are the right location for large amounts of data.
- **Small, Deterministic Blocks**: Give agents composable tools (Click, Screenshot), not magic buttons.
- **Self-Healing Errors**: Return actionable errors that include context and potential fixes.
- **Human-Agent Collaboration**: Output must be readable by machines (structured) AND humans (summaries).
- **Progressive Complexity**: Tools should be simple by default (high-level actions) but offer advanced optional arguments for power users.
- **Reference over Value**: for heavy assets (screenshots, traces, videos), return a file path or resource URI, never the raw data stream. Some MCP clients support a built-in handling of heavy assets e.g. directly displaying images. This _could_ be an exception.
+41
View File
@@ -0,0 +1,41 @@
<!-- AUTO GENERATED DO NOT EDIT - run 'npm run gen' to update-->
# Chrome DevTools MCP Slim Tool Reference
- **[Navigation automation](#navigation-automation)** (1 tools)
- [`navigate`](#navigate)
- **[Debugging](#debugging)** (2 tools)
- [`evaluate`](#evaluate)
- [`screenshot`](#screenshot)
## Navigation automation
### `navigate`
**Description:** Loads a URL
**Parameters:**
- **url** (string) **(required)**: URL to [`navigate`](#navigate) to
---
## Debugging
### `evaluate`
**Description:** Evaluates a JavaScript script
**Parameters:**
- **script** (string) **(required)**: JS script to run on the page
---
### `screenshot`
**Description:** Takes a [`screenshot`](#screenshot)
**Parameters:** None
---
+87
View File
@@ -0,0 +1,87 @@
# Developer Guide: Building third-party developer tools
This documentation outlines how to expose custom runtime data and tools from your web application to Chrome DevTools for Agents.
## Overview
Third-party developer tools enable your web application 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.
## How It Works: Tool Discovery
Chrome DevTools for Agents uses an event-based mechanism to discover tools exposed by the page. The process follows these steps:
1. **Event Dispatch:** Chrome DevTools for Agents dispatches a `devtoolstooldiscovery` event on the global `window` object.
2. **Listener:** Your application listens for this event and provides the tool definitions.
3. **Response:** Your application must call `event.respondWith()` to register a `ToolGroup` object.
_Note: Chrome DevTools for Agents requests this list automatically after page navigations (e.g., `new_page`, `navigate_page`) or when explicitly requested via the `list_3p_developer_tools()` MCP tool._
## Implementation
To expose tools, implement a listener for the `devtoolstooldiscovery` event and provide a `ToolGroup` containing your tool definitions.
### Type Definitions
Your tools must follow the `ToolDefinition` and `ToolGroup` interfaces:
```typescript
export interface ToolDefinition {
name: string;
description: string;
inputSchema: JSONSchema7;
execute: (args: Record<string, unknown>) => unknown;
}
export interface ToolGroup {
name: string;
description: string;
tools: ToolDefinition[];
}
```
### Example Implementation
```typescript
window.addEventListener(
'devtoolstooldiscovery',
(event: DevtoolsToolDiscoveryEvent) => {
event.respondWith({
name: 'Page-specific DevTools',
description: "Provide runtime info directly from the page's JavaScript",
tools: [
{
name: 'add',
description: 'Calculates the sum of two numbers.',
inputSchema: {
type: 'object',
properties: {
a: {type: 'number'},
b: {type: 'number'},
},
required: ['a', 'b'],
},
execute: async (input: {a: number; b: number}) => {
return input.a + input.b;
},
},
],
});
},
);
```
## Tool Invocation
Once discovered, MCP clients can execute your tools through Chrome DevTools for Agents using:
- **`execute_3p_developer_tool`**: The standard way to invoke a specific registered tool by name with validated parameters.
- **`evaluate_script`**: Allows for more complex interactions by running a custom script that calls `window.__dtmcp.executeTool()` directly, enabling you to compose functionality.
## Important Considerations
- **Experimental Status:** This feature is currently experimental. APIs may change, and there are no guarantees regarding stability.
- **Security & Scope:**
- **Context:** Third-party developer tools execute only within the context of the page that defines them. They do not persist across origins.
- **Capabilities:** These tools do not grant expanded privileges; they can only execute code that an attacker would already be able to run on that page.
- **DOM Elements:** If your tools require DOM elements as inputs or outputs, they are handled via special UIDs referenced in the accessibility tree.
- **Flags:** The implementation is gated behind the `--categoryExperimentalThirdParty=true` command-line flag.
+681
View File
@@ -0,0 +1,681 @@
<!-- AUTO GENERATED DO NOT EDIT - run 'npm run gen' to update-->
# Chrome DevTools MCP Tool Reference
- **[Input automation](#input-automation)** (10 tools)
- [`click`](#click)
- [`drag`](#drag)
- [`fill`](#fill)
- [`fill_form`](#fill_form)
- [`handle_dialog`](#handle_dialog)
- [`hover`](#hover)
- [`press_key`](#press_key)
- [`type_text`](#type_text)
- [`upload_file`](#upload_file)
- [`click_at`](#click_at)
- **[Navigation automation](#navigation-automation)** (6 tools)
- [`close_page`](#close_page)
- [`list_pages`](#list_pages)
- [`navigate_page`](#navigate_page)
- [`new_page`](#new_page)
- [`select_page`](#select_page)
- [`wait_for`](#wait_for)
- **[Emulation](#emulation)** (2 tools)
- [`emulate`](#emulate)
- [`resize_page`](#resize_page)
- **[Performance](#performance)** (3 tools)
- [`performance_analyze_insight`](#performance_analyze_insight)
- [`performance_start_trace`](#performance_start_trace)
- [`performance_stop_trace`](#performance_stop_trace)
- **[Network](#network)** (2 tools)
- [`get_network_request`](#get_network_request)
- [`list_network_requests`](#list_network_requests)
- **[Debugging](#debugging)** (8 tools)
- [`evaluate_script`](#evaluate_script)
- [`get_console_message`](#get_console_message)
- [`lighthouse_audit`](#lighthouse_audit)
- [`list_console_messages`](#list_console_messages)
- [`take_screenshot`](#take_screenshot)
- [`take_snapshot`](#take_snapshot)
- [`screencast_start`](#screencast_start)
- [`screencast_stop`](#screencast_stop)
- **[Memory](#memory)** (11 tools)
- [`take_heapsnapshot`](#take_heapsnapshot)
- [`close_heapsnapshot`](#close_heapsnapshot)
- [`compare_heapsnapshots`](#compare_heapsnapshots)
- [`get_heapsnapshot_class_nodes`](#get_heapsnapshot_class_nodes)
- [`get_heapsnapshot_details`](#get_heapsnapshot_details)
- [`get_heapsnapshot_dominators`](#get_heapsnapshot_dominators)
- [`get_heapsnapshot_duplicate_strings`](#get_heapsnapshot_duplicate_strings)
- [`get_heapsnapshot_edges`](#get_heapsnapshot_edges)
- [`get_heapsnapshot_retainers`](#get_heapsnapshot_retainers)
- [`get_heapsnapshot_retaining_paths`](#get_heapsnapshot_retaining_paths)
- [`get_heapsnapshot_summary`](#get_heapsnapshot_summary)
- **[Extensions](#extensions)** (5 tools)
- [`install_extension`](#install_extension)
- [`list_extensions`](#list_extensions)
- [`reload_extension`](#reload_extension)
- [`trigger_extension_action`](#trigger_extension_action)
- [`uninstall_extension`](#uninstall_extension)
- **[Third-party](#third-party)** (2 tools)
- [`execute_3p_developer_tool`](#execute_3p_developer_tool)
- [`list_3p_developer_tools`](#list_3p_developer_tools)
- **[WebMCP](#webmcp)** (2 tools)
- [`execute_webmcp_tool`](#execute_webmcp_tool)
- [`list_webmcp_tools`](#list_webmcp_tools)
## Input automation
### `click`
**Description:** Clicks on the provided element
**Parameters:**
- **uid** (string) **(required)**: The uid of an element on the page from the page content snapshot
- **dblClick** (boolean) _(optional)_: Set to true for double clicks. Default is false.
- **includeSnapshot** (boolean) _(optional)_: Whether to include a snapshot in the response. Default is false.
---
### `drag`
**Description:** [`Drag`](#drag) an element onto another element
**Parameters:**
- **from_uid** (string) **(required)**: The uid of the element to [`drag`](#drag)
- **to_uid** (string) **(required)**: The uid of the element to drop into
- **includeSnapshot** (boolean) _(optional)_: Whether to include a snapshot in the response. Default is false.
---
### `fill`
**Description:** Type text into an input, text area or select an option from a &lt;select&gt; element.
**Parameters:**
- **uid** (string) **(required)**: The uid of an element on the page from the page content snapshot
- **value** (string) **(required)**: The value to [`fill`](#fill) in. "true" or "false" for checkboxes and toggles, "true" for radio buttons.
- **includeSnapshot** (boolean) _(optional)_: Whether to include a snapshot in the response. Default is false.
---
### `fill_form`
**Description:** [`Fill`](#fill) out multiple form elements (inputs, selects, checkboxes, radios) at once. ALWAYS prefer this tool over multiple individual '[`fill`](#fill)' or '[`click`](#click)' calls when interacting with forms. It is significantly faster, more reliable, and reduces turn count. Example: [`Fill`](#fill) username, password, and check "Remember Me" in one call.
**Parameters:**
- **elements** (array) **(required)**: Elements from snapshot to [`fill`](#fill) out.
- **includeSnapshot** (boolean) _(optional)_: Whether to include a snapshot in the response. Default is false.
---
### `handle_dialog`
**Description:** If a browser dialog was opened, use this command to handle it
**Parameters:**
- **action** (enum: "accept", "dismiss") **(required)**: Whether to dismiss or accept the dialog
- **promptText** (string) _(optional)_: Optional prompt text to enter into the dialog.
---
### `hover`
**Description:** [`Hover`](#hover) over the provided element
**Parameters:**
- **uid** (string) **(required)**: The uid of an element on the page from the page content snapshot
- **includeSnapshot** (boolean) _(optional)_: Whether to include a snapshot in the response. Default is false.
---
### `press_key`
**Description:** Press a key or key combination. Use this when other input methods like [`fill`](#fill)() cannot be used (e.g., keyboard shortcuts, navigation keys, or special key combinations).
**Parameters:**
- **key** (string) **(required)**: A key or a combination (e.g., "Enter", "Control+A", "Control++", "Control+Shift+R"). Modifiers: Control, Shift, Alt, Meta
- **includeSnapshot** (boolean) _(optional)_: Whether to include a snapshot in the response. Default is false.
---
### `type_text`
**Description:** Type text using keyboard into a previously focused input
**Parameters:**
- **text** (string) **(required)**: The text to type
- **submitKey** (string) _(optional)_: Optional key to press after typing. E.g., "Enter", "Tab", "Escape"
---
### `upload_file`
**Description:** Upload a file through a provided element.
**Parameters:**
- **filePath** (string) **(required)**: The local path of the file to upload
- **uid** (string) **(required)**: The uid of the file input element or an element that will open file chooser on the page from the page content snapshot
- **includeSnapshot** (boolean) _(optional)_: Whether to include a snapshot in the response. Default is false.
---
### `click_at`
**Description:** Clicks at the provided coordinates (requires flag: --experimentalVision=true)
**Parameters:**
- **x** (number) **(required)**: The x coordinate
- **y** (number) **(required)**: The y coordinate
- **dblClick** (boolean) _(optional)_: Set to true for double clicks. Default is false.
- **includeSnapshot** (boolean) _(optional)_: Whether to include a snapshot in the response. Default is false.
---
## Navigation automation
### `close_page`
**Description:** Closes the page by its index. The last open page cannot be closed.
**Parameters:**
- **pageId** (number) **(required)**: The ID of the page to close. Call [`list_pages`](#list_pages) to list pages.
---
### `list_pages`
**Description:** Get a list of pages open in the browser.
**Parameters:** None
---
### `navigate_page`
**Description:** Go to a URL, or back, forward, or reload. Use project URL if not specified otherwise.
**Parameters:**
- **handleBeforeUnload** (enum: "accept", "dismiss") _(optional)_: Whether to auto accept or beforeunload dialogs triggered by this navigation. Default is accept.
- **ignoreCache** (boolean) _(optional)_: Whether to ignore cache on reload.
- **initScript** (string) _(optional)_: A JavaScript script to be executed on each new document before any other scripts for the next navigation.
- **timeout** (integer) _(optional)_: Maximum wait time in milliseconds. If set to 0, the default timeout will be used.
- **type** (enum: "url", "back", "forward", "reload") _(optional)_: Navigate the page by URL, back or forward in history, or reload.
- **url** (string) _(optional)_: Target URL (only type=url)
---
### `new_page`
**Description:** Open a new tab and load a URL. Use project URL if not specified otherwise.
**Parameters:**
- **url** (string) **(required)**: URL to load in a new page.
- **background** (boolean) _(optional)_: Whether to open the page in the background without bringing it to the front. Default is false (foreground).
- **isolatedContext** (string) _(optional)_: If specified, the page is created in an isolated browser context with the given name. Pages in the same browser context share cookies and storage. Pages in different browser contexts are fully isolated.
- **timeout** (integer) _(optional)_: Maximum wait time in milliseconds. If set to 0, the default timeout will be used.
---
### `select_page`
**Description:** Select a page as a context for future tool calls.
**Parameters:**
- **pageId** (number) **(required)**: The ID of the page to select. Call [`list_pages`](#list_pages) to get available pages.
- **bringToFront** (boolean) _(optional)_: Whether to focus the page and bring it to the top.
---
### `wait_for`
**Description:** Wait for the specified text to appear on the selected page.
**Parameters:**
- **text** (array) **(required)**: Non-empty list of texts. Resolves when any value appears on the page.
- **timeout** (integer) _(optional)_: Maximum wait time in milliseconds. If set to 0, the default timeout will be used.
---
## Emulation
### `emulate`
**Description:** Emulates various features on the selected page.
**Parameters:**
- **colorScheme** (enum: "dark", "light", "auto") _(optional)_: [`Emulate`](#emulate) the dark or the light mode. Set to "auto" to reset to the default.
- **cpuThrottlingRate** (number) _(optional)_: Represents the CPU slowdown factor. Omit or set the rate to 1 to disable throttling
- **extraHttpHeaders** (string) _(optional)_: Extra HTTP headers as a JSON string object, e.g. {"X-Custom": "value", "Authorization": "Bearer token"}. Headers are included into every HTTP request originating from the page and persist across navigations until cleared. Pass an empty string to clear all extra headers.
- **geolocation** (string) _(optional)_: Geolocation (`&lt;latitude&gt;,&lt;longitude&gt;`) to [`emulate`](#emulate). Latitude between -90 and 90. Longitude between -180 and 180. Omit to clear the geolocation override.
- **networkConditions** (enum: "Offline", "Slow 3G", "Fast 3G", "Slow 4G", "Fast 4G") _(optional)_: Throttle network. Omit to disable throttling.
- **userAgent** (string) _(optional)_: User agent to [`emulate`](#emulate). Set to empty string to clear the user agent override.
- **viewport** (string) _(optional)_: [`Emulate`](#emulate) device viewports '&lt;width&gt;x&lt;height&gt;x&lt;devicePixelRatio&gt;[,mobile][,touch][,landscape]'. 'touch' and 'mobile' to [`emulate`](#emulate) mobile devices. 'landscape' to [`emulate`](#emulate) landscape mode.
---
### `resize_page`
**Description:** Resizes the selected page's window so that the page has specified dimension
**Parameters:**
- **height** (number) **(required)**: Page height
- **width** (number) **(required)**: Page width
---
## Performance
### `performance_analyze_insight`
**Description:** Provides more detailed information on a specific Performance Insight of an insight set that was highlighted in the results of a trace recording.
**Parameters:**
- **insightName** (string) **(required)**: The name of the Insight you want more information on. For example: "DocumentLatency" or "LCPBreakdown"
- **insightSetId** (string) **(required)**: The id for the specific insight set. Only use the ids given in the "Available insight sets" list.
---
### `performance_start_trace`
**Description:** Start a performance trace on the selected webpage. Use to find frontend performance issues, Core Web Vitals (LCP, INP, CLS), and improve page load speed.
**Parameters:**
- **autoStop** (boolean) _(optional)_: Determines if the trace recording should be automatically stopped.
- **filePath** (string) _(optional)_: The absolute file path, or a file path relative to the current working directory, to save the raw trace data. For example, trace.json.gz (compressed) or trace.json (uncompressed).
- **reload** (boolean) _(optional)_: Determines if, once tracing has started, the current selected page should be automatically reloaded. Navigate the page to the right URL using the [`navigate_page`](#navigate_page) tool BEFORE starting the trace if reload or autoStop is set to true.
---
### `performance_stop_trace`
**Description:** Stop the active performance trace recording on the selected webpage.
**Parameters:**
- **filePath** (string) _(optional)_: The absolute file path, or a file path relative to the current working directory, to save the raw trace data. For example, trace.json.gz (compressed) or trace.json (uncompressed).
---
## Network
### `get_network_request`
**Description:** Gets a network request by an optional reqid, if omitted returns the currently selected request in the DevTools Network panel.
**Parameters:**
- **reqid** (number) _(optional)_: The reqid of the network request. If omitted returns the currently selected request in the DevTools Network panel.
- **requestFilePath** (string) _(optional)_: The absolute or relative path to a .network-request file to save the request body to. If omitted, the body is returned inline.
- **responseFilePath** (string) _(optional)_: The absolute or relative path to a .network-response file to save the response body to. If omitted, the body is returned inline.
---
### `list_network_requests`
**Description:** List all requests for the currently selected page since the last navigation.
**Parameters:**
- **includePreservedRequests** (boolean) _(optional)_: Set to true to return the preserved requests over the last 3 navigations.
- **pageIdx** (integer) _(optional)_: Page number to return (0-based). When omitted, returns the first page.
- **pageSize** (integer) _(optional)_: Maximum number of requests to return. When omitted, returns all requests.
- **resourceTypes** (array) _(optional)_: Filter requests to only return requests of the specified resource types. When omitted or empty, returns all requests.
---
## Debugging
### `evaluate_script`
**Description:** Evaluate a JavaScript function inside the currently selected page. Returns the response as JSON, so returned values have to be JSON-serializable.
**Parameters:**
- **function** (string) **(required)**: A JavaScript function declaration to be executed by the tool in the currently selected page.
Example without arguments: `() => document.title` or `async () => await fetch("example.com")`.
Example with arguments: `(el) => el.innerText`
- **args** (array) _(optional)_: An optional list of arguments to pass to the function.
- **dialogAction** (string) _(optional)_: Handle dialogs while execution. "accept", "dismiss", or string for response of window.prompt. Defaults to accept.
- **filePath** (string) _(optional)_: The absolute or relative path to a file to save the script output to. If omitted, the output is returned inline.
---
### `get_console_message`
**Description:** Gets a console message by its ID. You can get all messages by calling [`list_console_messages`](#list_console_messages).
**Parameters:**
- **msgid** (number) **(required)**: The msgid of a console message on the page from the listed console messages
---
### `lighthouse_audit`
**Description:** Get Lighthouse score and reports for accessibility, SEO, best practices, and agentic browsing. This excludes performance. For performance audits, run [`performance_start_trace`](#performance_start_trace)
**Parameters:**
- **device** (enum: "desktop", "mobile") _(optional)_: Device to [`emulate`](#emulate).
- **mode** (enum: "navigation", "snapshot") _(optional)_: "navigation" reloads &amp; audits. "snapshot" analyzes current state.
- **outputDirPath** (string) _(optional)_: Directory for reports. If omitted, uses temporary files.
---
### `list_console_messages`
**Description:** List all console messages for the currently selected page since the last navigation.
**Parameters:**
- **includePreservedMessages** (boolean) _(optional)_: Set to true to return the preserved messages over the last 3 navigations.
- **pageIdx** (integer) _(optional)_: Page number to return (0-based). When omitted, returns the first page.
- **pageSize** (integer) _(optional)_: Maximum number of messages to return. When omitted, returns all messages.
- **serviceWorkerId** (string) _(optional)_: Filter messages to only return messages of the specified service worker.
- **types** (array) _(optional)_: Filter messages to only return messages of the specified resource types. When omitted or empty, returns all messages.
---
### `take_screenshot`
**Description:** Take a screenshot of the page or element.
**Parameters:**
- **filePath** (string) _(optional)_: The absolute path, or a path relative to the current working directory, to save the screenshot to instead of attaching it to the response.
- **format** (enum: "png", "jpeg", "webp") _(optional)_: Type of format to save the screenshot as. Default is "png"
- **fullPage** (boolean) _(optional)_: If set to true takes a screenshot of the full page instead of the currently visible viewport. Incompatible with uid.
- **quality** (number) _(optional)_: Compression quality for JPEG and WebP formats (0-100). Higher values mean better quality but larger file sizes. Ignored for PNG format.
- **uid** (string) _(optional)_: The uid of an element on the page from the page content snapshot. If omitted, takes a page screenshot.
---
### `take_snapshot`
**Description:** Take a text snapshot of the currently selected page based on the a11y tree. The snapshot lists page elements along with a unique
identifier (uid). Always use the latest snapshot. Prefer taking a snapshot over taking a screenshot. The snapshot indicates the element selected
in the DevTools Elements panel (if any).
**Parameters:**
- **filePath** (string) _(optional)_: The absolute path, or a path relative to the current working directory, to save the snapshot to instead of attaching it to the response.
- **verbose** (boolean) _(optional)_: Whether to include all possible information available in the full a11y tree. Default is false.
---
### `screencast_start`
**Description:** Starts recording a screencast (video) of the selected page in specified format. (requires flag: --experimentalScreencast=true)
**Parameters:**
- **filePath** (string) _(optional)_: Output file path (.webm,.mp4 are supported). Uses mkdtemp to generate a unique path if not provided.
---
### `screencast_stop`
**Description:** Stops the active screencast recording on the selected page. (requires flag: --experimentalScreencast=true)
**Parameters:** None
---
## Memory
### `take_heapsnapshot`
**Description:** Capture a heap snapshot of the currently selected page. Use to analyze the memory distribution of JavaScript objects and debug memory leaks.
**Parameters:**
- **filePath** (string) **(required)**: A path to a .heapsnapshot file to save the heapsnapshot to.
---
### `close_heapsnapshot`
**Description:** Closes a previously loaded memory heapsnapshot, freeing its memory. (requires flag: --memoryDebugging=true)
**Parameters:**
- **filePath** (string) **(required)**: A path to the .heapsnapshot file to close.
---
### `compare_heapsnapshots`
**Description:** Loads two memory heapsnapshots and returns the comparison. If classIndex is provided, returns detailed diff for that class, otherwise returns summary diff. (requires flag: --memoryDebugging=true)
**Parameters:**
- **baseFilePath** (string) **(required)**: A path to the base .heapsnapshot file (earlier snapshot).
- **currentFilePath** (string) **(required)**: A path to the current .heapsnapshot file (later snapshot).
- **classIndex** (number) _(optional)_: Optional 0-based index of the class in the summary list to filter results, showing individual objects.
---
### `get_heapsnapshot_class_nodes`
**Description:** Loads a memory heapsnapshot and returns instances of a specific class with their IDs. (requires flag: --memoryDebugging=true)
**Parameters:**
- **filePath** (string) **(required)**: A path to a .heapsnapshot file to read.
- **id** (number) **(required)**: The ID for the class, obtained from details.
- **filterName** (enum: "objectsRetainedByDetachedDomNodes", "objectsRetainedByConsole", "objectsRetainedByEventHandlers", "objectsRetainedByContexts") _(optional)_: An optional filter to apply to the nodes.
- **pageIdx** (number) _(optional)_: The page index for pagination.
- **pageSize** (number) _(optional)_: The page size for pagination.
---
### `get_heapsnapshot_details`
**Description:** Loads a memory heapsnapshot and returns all available information including statistics, static data, and aggregated node information. Supports pagination for aggregates. (requires flag: --memoryDebugging=true)
**Parameters:**
- **filePath** (string) **(required)**: A path to a .heapsnapshot file to read.
- **filterName** (enum: "objectsRetainedByDetachedDomNodes", "objectsRetainedByConsole", "objectsRetainedByEventHandlers", "objectsRetainedByContexts") _(optional)_: An optional filter to apply to the aggregates.
- **pageIdx** (number) _(optional)_: The page index for pagination of aggregates.
- **pageSize** (number) _(optional)_: The page size for pagination of aggregates.
---
### `get_heapsnapshot_dominators`
**Description:** Loads a memory heapsnapshot and returns the dominator chain for a specific node ID. This helps to identify which objects are keeping the target node alive. (requires flag: --memoryDebugging=true)
**Parameters:**
- **filePath** (string) **(required)**: A path to a .heapsnapshot file to read.
- **nodeId** (number) **(required)**: The node ID to get the dominator chain for.
---
### `get_heapsnapshot_duplicate_strings`
**Description:** Loads a memory heapsnapshot and returns duplicate strings grouped by their value. (requires flag: --memoryDebugging=true)
**Parameters:**
- **filePath** (string) **(required)**: A path to a .heapsnapshot file to read.
- **pageIdx** (number) _(optional)_: The page index for pagination.
- **pageSize** (number) _(optional)_: The page size for pagination.
---
### `get_heapsnapshot_edges`
**Description:** Loads a memory heapsnapshot and returns outgoing edges (references) for a specific node ID. (requires flag: --memoryDebugging=true)
**Parameters:**
- **filePath** (string) **(required)**: A path to a .heapsnapshot file to read.
- **nodeId** (number) **(required)**: The node ID to get outgoing edges for.
- **pageIdx** (number) _(optional)_: The page index for pagination.
- **pageSize** (number) _(optional)_: The page size for pagination.
---
### `get_heapsnapshot_retainers`
**Description:** Loads a memory heapsnapshot and returns retainers for a specific node ID. (requires flag: --memoryDebugging=true)
**Parameters:**
- **filePath** (string) **(required)**: A path to a .heapsnapshot file to read.
- **nodeId** (number) **(required)**: The node ID to get retainers for.
- **pageIdx** (number) _(optional)_: The page index for pagination.
- **pageSize** (number) _(optional)_: The page size for pagination.
---
### `get_heapsnapshot_retaining_paths`
**Description:** Loads a memory heapsnapshot and returns retaining paths for a specific node ID. This helps to understand why a node is not being garbage collected. (requires flag: --memoryDebugging=true)
**Parameters:**
- **filePath** (string) **(required)**: A path to a .heapsnapshot file to read.
- **nodeId** (number) **(required)**: The node ID to get retaining paths for.
- **maxDepth** (number) _(optional)_: The maximum depth to search for retaining paths.
- **maxNodes** (number) _(optional)_: The maximum number of nodes to return.
- **maxSiblings** (number) _(optional)_: The maximum number of siblings to return.
---
### `get_heapsnapshot_summary`
**Description:** Loads a memory heapsnapshot and returns snapshot summary stats. (requires flag: --memoryDebugging=true)
**Parameters:**
- **filePath** (string) **(required)**: A path to a .heapsnapshot file to read.
---
## Extensions
> NOTE: The Extensions category is not active by default. Use the '--categoryExtensions' flag.
### `install_extension`
**Description:** Installs a Chrome extension from the given path. (requires flag: --categoryExtensions=true)
**Parameters:**
- **path** (string) **(required)**: Absolute path to the unpacked extension folder.
---
### `list_extensions`
**Description:** Lists all the Chrome extensions installed in the browser. This includes their name, ID, version, and enabled status. (requires flag: --categoryExtensions=true)
**Parameters:** None
---
### `reload_extension`
**Description:** Reloads an unpacked Chrome extension by its ID. (requires flag: --categoryExtensions=true)
**Parameters:**
- **id** (string) **(required)**: ID of the extension to reload.
---
### `trigger_extension_action`
**Description:** Triggers the default action of an extension by its ID. (requires flag: --categoryExtensions=true)
**Parameters:**
- **id** (string) **(required)**: ID of the extension to trigger the action for.
---
### `uninstall_extension`
**Description:** Uninstalls a Chrome extension by its ID. (requires flag: --categoryExtensions=true)
**Parameters:**
- **id** (string) **(required)**: ID of the extension to uninstall.
---
## Third-party
> NOTE: The Third-party category is not active by default. Use the '--categoryExperimentalThirdParty' flag.
### `execute_3p_developer_tool`
**Description:** Executes a tool exposed by the page. (requires flag: --categoryExperimentalThirdParty=true)
**Parameters:**
- **toolName** (string) **(required)**: The name of the tool to execute
- **params** (string) _(optional)_: The JSON-stringified parameters to pass to the tool
---
### `list_3p_developer_tools`
**Description:** Lists all third-party developer tools the page exposes for providing runtime information.
Third-party developer tools can be called via the '[`execute_3p_developer_tool`](#execute_3p_developer_tool)()' MCP tool.
Alternatively, third-party developer tools can be executed by calling '[`evaluate_script`](#evaluate_script)' and adding the
following command to the script:
`window.__dtmcp.executeTool(toolName, params)`
This might be helpful when the third-party developer tools return non-serializable values or when composing
third-party developer tools with additional functionality. (requires flag: --categoryExperimentalThirdParty=true)
**Parameters:** None
---
## WebMCP
> NOTE: The WebMCP category is not active by default. Use the '--categoryExperimentalWebmcp' flag.
### `execute_webmcp_tool`
**Description:** Executes a WebMCP tool exposed by the page. (requires flag: --categoryExperimentalWebmcp=true)
**Parameters:**
- **toolName** (string) **(required)**: The name of the WebMCP tool to execute
- **input** (string) _(optional)_: The JSON-stringified parameters to pass to the WebMCP tool
---
### `list_webmcp_tools`
**Description:** Lists all WebMCP tools the page exposes. (requires flag: --categoryExperimentalWebmcp=true)
**Parameters:** None
---
+183
View File
@@ -0,0 +1,183 @@
# Troubleshooting
## General tips
- Run `npx chrome-devtools-mcp@latest --help` to test if the MCP server runs on your machine.
- Make sure that your MCP client uses the same npm and node version as your terminal.
- When configuring your MCP client, try using the `--yes` argument to `npx` to
auto-accept installation prompt.
- Find a specific error in the output of the `chrome-devtools-mcp` server.
Usually, if your client is an IDE, logs would be in the Output pane.
- Search the [GitHub repository issues and discussions](https://github.com/ChromeDevTools/chrome-devtools-mcp) for help or existing similar problems.
## Debugging
Start the MCP server with debugging enabled and a log file:
- `DEBUG=* npx chrome-devtools-mcp@latest --log-file=/path/to/chrome-devtools-mcp.log`
Using `.mcp.json` to debug while using a client:
```json
{
"mcpServers": {
"chrome-devtools": {
"type": "stdio",
"command": "npx",
"args": [
"chrome-devtools-mcp@latest",
"--log-file",
"/path/to/chrome-devtools-mcp.log"
],
"env": {
"DEBUG": "*"
}
}
}
}
```
## Specific problems
### `Error [ERR_MODULE_NOT_FOUND]: Cannot find module ...`
This usually indicates either a non-supported Node version is in use or that the
`npm`/`npx` cache is corrupted. Try clearing the cache, uninstalling
`chrome-devtools-mcp` and installing it again. Clear the cache by running:
```sh
rm -rf ~/.npm/_npx # NOTE: this might remove other installed npx executables.
npm cache clean --force
```
### `Target closed` error
This indicates that the browser could not be started. Make sure that no Chrome
instances are running or close them. Make sure you have the latest stable Chrome
installed and that [your system is able to run Chrome](https://support.google.com/chrome/a/answer/7100626?hl=en).
### Chrome crashes on macOS when using Web Bluetooth
On macOS, Chrome launched by an MCP client application (such as Claude Desktop) may crash when a Web Bluetooth prompt appears. This is caused by a macOS privacy permission violation (TCC).
To resolve this, grant Bluetooth permission to the MCP client application in `System Settings > Privacy & Security > Bluetooth`. After granting permission, restart the client application and start a new MCP session.
### Remote debugging between virtual machine (VM) and host fails
When attempting to connect to Chrome running on a host machine from within a virtual machine (VM), Chrome may reject the connection due to 'Host' header validation. You can bypass this restriction by creating an SSH tunnel from the VM to the host. In the VM, run:
```sh
ssh -N -L 127.0.0.1:9222:127.0.0.1:9222 <user>@<host-ip>
```
Point the MCP connection inside the VM to `http://127.0.0.1:9222`. This allows DevTools to reach the host browser without triggering the Host validation error.
### Operating system sandboxes
Some MCP clients allow sandboxing the MCP server using macOS Seatbelt or Linux
containers. If sandboxes are enabled, `chrome-devtools-mcp` is not able to start
Chrome that requires permissions to create its own sandboxes. As a workaround,
either disable sandboxing for `chrome-devtools-mcp` in your MCP client or use
`--browser-url` to connect to a Chrome instance that you start manually outside
of the MCP client sandbox.
### WSL
By default, `chrome-devtools-mcp` in WSL requires Chrome to be installed within the Linux environment. While it normally attempts to launch Chrome on the Windows side, this currently fails due to a [known WSL issue](https://github.com/microsoft/WSL/issues/14201). Ensure you are using a [Linux distribution compatible with Chrome](https://support.google.com/chrome/a/answer/7100626).
Possible workarounds include:
- **Install Google Chrome in WSL:**
- `wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb`
- `sudo dpkg -i google-chrome-stable_current_amd64.deb`
- **Use Mirrored networking:**
1. Configure [Mirrored networking for WSL](https://learn.microsoft.com/en-us/windows/wsl/networking).
2. Start Chrome on the Windows side with:
`chrome.exe --remote-debugging-port=9222 --user-data-dir=C:\path\to\dir`
3. Start `chrome-devtools-mcp` with:
`npx chrome-devtools-mcp --browser-url http://127.0.0.1:9222`
- **Use PowerShell or Git Bash** instead of WSL.
### Windows 10: Error during discovery for MCP server 'chrome-devtools': MCP error -32000: Connection closed
- **Solution 1** Call using `cmd` (For more info https://github.com/modelcontextprotocol/servers/issues/1082#issuecomment-2791786310)
```json
"mcpServers": {
"chrome-devtools": {
"command": "cmd",
"args": ["/c", "npx", "-y", "chrome-devtools-mcp@latest"]
}
}
```
> **The Key Change:** On Windows, running a Node.js package via `npx` often requires the `cmd /c` prefix to be executed correctly from within another process like VSCode's extension host. Therefore, `"command": "npx"` was replaced with `"command": "cmd"`, and the actual `npx` command was moved into the `"args"` array, preceded by `"/c"`. This fix allows Windows to interpret the command correctly and launch the server.
- **Solution 2** Instead of another layer of shell you can write the absolute path to `npx`:
> Note: The path below is an example. You must adjust it to match the actual location of `npx` on your machine. Depending on your setup, the file extension might be `.cmd`, `.bat`, or `.exe` rather than `.ps1`. Also, ensure you use double backslashes (`\\`) as path delimiters, as required by the JSON format.
```json
"mcpServers": {
"chrome-devtools": {
"command": "C:\\nvm4w\\nodejs\\npx.ps1",
"args": ["-y", "chrome-devtools-mcp@latest"]
}
}
```
### Claude Code plugin installation fails with `Failed to clone repository`
When installing `chrome-devtools-mcp` as a Claude Code plugin (either from the
official marketplace or via `/plugin marketplace add`), the installation may fail
with a timeout error if your environment cannot reach `github.com` on port 443
(HTTPS):
```
Failed to download/cache plugin chrome-devtools-mcp: Failed to clone repository:
Cloning into '...'...
fatal: unable to access 'https://github.com/ChromeDevTools/chrome-devtools-mcp.git/':
Failed to connect to github.com port 443
```
This can happen in environments with restricted outbound HTTPS connectivity,
corporate firewalls, or proxy configurations that block HTTPS git operations.
**Workaround 1: Use SSH instead of HTTPS**
If you have SSH access to GitHub configured, you can redirect all GitHub HTTPS
URLs to use SSH by running:
```sh
git config --global url."git@github.com:".insteadOf "https://github.com/"
```
Then retry the plugin installation. This tells git to use your SSH key for all
GitHub operations instead of HTTPS.
**Workaround 2: Install via CLI instead**
If the plugin marketplace approach fails, you can install `chrome-devtools-mcp`
as an MCP server directly without cloning the repository:
```sh
claude mcp add chrome-devtools --scope user npx chrome-devtools-mcp@latest
```
This bypasses the git clone entirely and uses npm/npx to fetch the package. Note
that this method installs only the MCP server without the bundled skills.
### Connection timeouts with `--autoConnect`
If you are using the `--autoConnect` flag and tools like `list_pages`, `new_page`, or `navigate_page` fail with a timeout (e.g., `ProtocolError: Network.enable timed out` or `The socket connection was closed unexpectedly`), this usually means the MCP server cannot handshake with the running Chrome instance correctly. Ensure:
1. Chrome 144+ is **already** running.
2. Remote debugging is enabled in Chrome via `chrome://inspect/#remote-debugging`.
3. You have allowed the remote debugging connection prompt in the browser.
4. There is no other MCP server or tool trying to connect to the same debugging port.
> [!IMPORTANT]
> In Chrome versions up to 149, connection issues may be caused by frozen or unloaded tabs.
> Chrome DevTools MCP forces all tabs to be loaded, so ensure your system has sufficient resources.
> It is currently not recommended to use Chrome DevTools MCP with browser instances running hundreds of tabs.
> See [Issue #1921](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1921) for more details.