Skip to content

Commit aec9492

Browse files
committed
Merge branch 'main' into orkon/cli-skill
2 parents dc33129 + 7273f16 commit aec9492

7 files changed

Lines changed: 196 additions & 128 deletions

File tree

docs/troubleshooting.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
auto-accept installation prompt.
99
- Find a specific error in the output of the `chrome-devtools-mcp` server.
1010
Usually, if your client is an IDE, logs would be in the Output pane.
11+
- Search the [GitHub repository issues and discussions](https://github.com/ChromeDevTools/chrome-devtools-mcp) for help or existing similar problems.
1112

1213
## Debugging
1314

@@ -98,3 +99,12 @@ Possible workarounds include:
9899
`npx chrome-devtools-mcp --browser-url http://127.0.0.1:9222`
99100

100101
- **Use Powershell or Git Bash** instead of WSL.
102+
103+
### Connection timeouts with `--autoConnect`
104+
105+
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:
106+
107+
1. Chrome 144+ is **already** running.
108+
2. Remote debugging is enabled in Chrome via `chrome://inspect/#remote-debugging`.
109+
3. You have allowed the remote debugging connection prompt in the browser.
110+
4. There is no other MCP server or tool trying to connect to the same debugging port.

scripts/test.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ const nodeArgs = [
6262
function installChrome(version) {
6363
try {
6464
return execSync(
65-
`npx @puppeteer/browsers install chrome@${version} --format "{{path}}"`,
65+
`npx puppeteer browsers install chrome@${version} --format "{{path}}"`,
6666
)
6767
.toString()
6868
.trim();

skills/chrome-devtools-cli/SKILL.md

Lines changed: 79 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,83 @@
11
---
22
name: chrome-devtools-cli
3-
description: Use to call Chrome DevTools MCP from shell scripts.
3+
description: Use this skill to call Chrome DevTools MCP from shell scripts.
44
---
55

6-
Documentation and examples for using the `chrome-devtools` CLI to automate browser tasks, perform audits, and interact with pages via CLI.
6+
## Getting started (one-time)
7+
8+
Install the package globally to make the `chrome-devtools` command available:
9+
10+
```sh
11+
npm i chrome-devtools-mcp@latest -g
12+
chrome-devtools status # check if install worked.
13+
```
14+
15+
## How it works
16+
17+
The CLI acts as a client to a background `chrome-devtools-mcp` daemon.
18+
19+
- **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.
20+
- **Persistence**: The same background instance is reused for subsequent commands, preserving the browser state (open pages, cookies, etc.).
21+
- **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`).
22+
23+
## Command Usage
24+
25+
The CLI supports all tools available in the [Tool reference](./tool-reference.md).
26+
27+
```sh
28+
chrome-devtools <tool> [arguments] [flags]
29+
```
30+
31+
- **Required Arguments**: Passed as positional arguments.
32+
- **Optional Arguments**: Passed as flags (e.g., `--filePath`, `--fullPage`).
33+
34+
### Examples
35+
36+
**New Page and Navigation:**
37+
38+
```sh
39+
chrome-devtools new_page "https://example.com"
40+
chrome-devtools navigate_page "https://web.dev" --type url
41+
```
42+
43+
**Interaction:**
44+
45+
```sh
46+
# Click an element by its UID from a snapshot
47+
chrome-devtools click "element-uid-123"
48+
49+
# Fill a form field
50+
chrome-devtools fill "input-uid-456" "search query"
51+
```
52+
53+
**Analysis:**
54+
55+
```sh
56+
# Run a Lighthouse audit (defaults to navigation mode)
57+
chrome-devtools lighthouse_audit --mode snapshot
58+
```
59+
60+
## Output format
61+
62+
By default, the CLI outputs a human-readable summary of the tool's result. For programmatic use, you can request raw JSON:
63+
64+
```sh
65+
chrome-devtools list_pages --format=json
66+
```
67+
68+
## Troubleshooting
69+
70+
If the CLI hangs or fails to connect, try stopping the background process:
71+
72+
```sh
73+
chrome-devtools stop
74+
```
75+
76+
For more verbose logs, set the `DEBUG` environment variable:
77+
78+
```sh
79+
DEBUG=* chrome-devtools list_pages
80+
```
781

882
Snapshots looks like this:
983

@@ -18,7 +92,7 @@ uid=1_0 RootWebArea "Example Domain" url="https://example.com/"
1892
## Input Automation (<uid> from snapshot)
1993

2094
```bash
21-
chrome-devtools take_snapshot --help # Help message for commands, works for any command.
95+
chrome-devtools take_snapshot --help
2296
chrome-devtools take_snapshot # Take a text snapshot of the page to get UIDs for elements
2397
chrome-devtools click "id" # Clicks on the provided element
2498
chrome-devtools click "id" --dblClick true --includeSnapshot true # Double clicks and returns a snapshot
@@ -96,7 +170,7 @@ chrome-devtools list_network_requests --includePreservedRequests true # Include
96170

97171
```bash
98172
chrome-devtools evaluate_script "() => document.title" # Evaluate a JavaScript function on the page
99-
evaluate_script "(a) => a.innerText" --args 1_4 # Evaluate JS with UID arguments
173+
chrome-devtools evaluate_script "(a) => a.innerText" --args 1_4 # Evaluate JS with UID arguments
100174
chrome-devtools get_console_message 1 # Gets a console message by its ID
101175
chrome-devtools lighthouse_audit --mode "navigation" # Run Lighthouse audit for navigation
102176
chrome-devtools lighthouse_audit --mode "snapshot" --device "mobile" # Run Lighthouse audit for a snapshot on mobile
@@ -115,7 +189,7 @@ chrome-devtools take_snapshot --verbose true --filePath "s.txt" # Take a verbose
115189
## Service Management
116190

117191
```bash
118-
chrome-devtools start # Start or restart chrome-devtools-mcp
192+
chrome-devtools start # Start or restart chrome-devtools-mcp, all chrome-devtools-mcp args will be forwarded
119193
chrome-devtools status # Checks if chrome-devtools-mcp is running
120194
chrome-devtools stop # Stop chrome-devtools-mcp if any
121195
```

skills/troubleshooting/SKILL.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
---
2+
name: troubleshooting
3+
description: Uses Chrome DevTools MCP and documentation to troubleshoot connection and target issues. Trigger this skill when list_pages, new_page, or navigate_page fail, or when the server initialization fails.
4+
---
5+
6+
## Troubleshooting Wizard
7+
8+
You are acting as a troubleshooting wizard to help the user configure and fix their Chrome DevTools MCP server setup. When this skill is triggered (e.g., because `list_pages`, `new_page`, or `navigate_page` failed, or the server wouldn't start), follow this step-by-step diagnostic process:
9+
10+
### Step 1: Find and Read Configuration
11+
12+
Your first action should be to locate and read the MCP configuration file. Search for the following files in the user's workspace: `.mcp.json`, `gemini-extension.json`, `.claude/settings.json`, `.vscode/launch.json`, or `.gemini/settings.json`.
13+
14+
If you find a configuration file, read and interpret it to identify potential issues such as:
15+
16+
- Incorrect arguments or flags.
17+
- Missing environment variables.
18+
- Usage of `--autoConnect` in incompatible environments.
19+
20+
If you cannot find any of these files, only then should you ask the user to provide their configuration file content.
21+
22+
### Step 2: Triage Common Connection Errors
23+
24+
Before reading documentation or suggesting configuration changes, check if the error message matches one of the following common patterns.
25+
26+
#### Error: `Could not find DevToolsActivePort`
27+
28+
This error is highly specific to the `--autoConnect` feature. It means the MCP server cannot find the file created by a running, debuggable Chrome instance. This is not a generic connection failure.
29+
30+
Your primary goal is to guide the user to ensure Chrome is running and properly configured. Do not immediately suggest switching to `--browserUrl`. Follow this exact sequence:
31+
32+
1. **Ask the user to confirm that the correct Chrome version** (e.g., "Chrome Canary" if the error mentions it) is currently running.
33+
2. **If the user confirms it is running, instruct them to enable remote debugging.** Be very specific about the URL and the action: "Please open a new tab in Chrome, navigate to `chrome://inspect/#remote-debugging`, and make sure the 'Enable remote debugging' checkbox is checked."
34+
3. **Once the user confirms both steps, your only next action should be to call the `list_pages` tool.** This is the simplest and safest way to verify if the connection is now successful. Do not retry the original, more complex command yet.
35+
4. **If `list_pages` succeeds, the problem is resolved.** If it still fails with the same error, then you can proceed to the more advanced steps like suggesting `--browserUrl` or checking for sandboxing issues.
36+
37+
#### Symptom: Server starts but creates a new empty profile
38+
39+
If the server starts successfully but `list_pages` returns an empty list or creates a new profile instead of connecting to the existing Chrome instance, check for typos in the arguments.
40+
41+
- **Check for flag typos:** For example, `--autoBronnect` instead of `--autoConnect`.
42+
- **Verify the configuration:** Ensure the arguments match the expected flags exactly.
43+
44+
#### Other Common Errors
45+
46+
Identify other error messages from the failed tool call or the MCP initialization logs:
47+
48+
- `Target closed`
49+
- "Tool not found" (check if they are using `--slim` which only enables navigation and screenshot tools).
50+
- `ProtocolError: Network.enable timed out` or `The socket connection was closed unexpectedly`
51+
- `Error [ERR_MODULE_NOT_FOUND]: Cannot find module`
52+
- Any sandboxing or host validation errors.
53+
54+
### Step 3: Read Known Issues
55+
56+
Read the contents of https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/docs/troubleshooting.md to map the error to a known issue. Pay close attention to:
57+
58+
- Sandboxing restrictions (macOS Seatbelt, Linux containers).
59+
- WSL requirements.
60+
- `--autoConnect` handshakes, timeouts, and requirements (requires **running** Chrome 144+).
61+
62+
### Step 4: Formulate a Configuration
63+
64+
Based on the exact error and the user's environment (OS, MCP client), formulate the correct MCP configuration snippet. Check if they need to:
65+
66+
- Pass `--browser-url=http://127.0.0.1:9222` instead of `--autoConnect` (e.g. if they are in a sandboxed environment like Claude Desktop).
67+
- Enable remote debugging in Chrome (`chrome://inspect/#remote-debugging`) and accept the connection prompt. **Ask the user to verify this is enabled if using `--autoConnect`.**
68+
- Add `--logFile <absolute_path_to_log_file>` to capture debug logs for analysis.
69+
- Increase `startup_timeout_ms` (e.g. to 20000) if using Codex on Windows.
70+
71+
_If you are unsure of the user's configuration, ask the user to provide their current MCP server JSON configuration._
72+
73+
### Step 5: Run Diagnostic Commands
74+
75+
If the issue is still unclear, run diagnostic commands to test the server directly:
76+
77+
- Run `npx chrome-devtools-mcp@latest --help` to verify the installation and Node.js environment.
78+
- If you need more information, run `DEBUG=* npx chrome-devtools-mcp@latest --logFile=/tmp/cdm-test.log` to capture verbose logs. Analyze the output for errors.
79+
80+
### Step 6: Check GitHub for Existing Issues
81+
82+
If https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/docs/troubleshooting.md does not cover the specific error, check if the `gh` (GitHub CLI) tool is available in the environment. If so, search the GitHub repository for similar issues:
83+
`gh issue list --repo ChromeDevTools/chrome-devtools-mcp --search "<error snippet>" --state all`
84+
85+
Alternatively, you can recommend that the user checks https://github.com/ChromeDevTools/chrome-devtools-mcp/issues and https://github.com/ChromeDevTools/chrome-devtools-mcp/discussions for help.

src/bin/chrome-devtools.ts

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,6 @@ import type {CallToolResult} from '../third_party/index.js';
2424
import {VERSION} from '../version.js';
2525

2626
import {commands} from './cliDefinitions.js';
27-
import {generateCustomHelp} from './customHelp.js';
28-
29-
const argv = hideBin(process.argv);
30-
31-
if (argv.length === 0 || argv[0] === '--custom-help') {
32-
console.log(generateCustomHelp(VERSION, commands));
33-
process.exit(0);
34-
}
3527

3628
async function start(args: string[]) {
3729
const combinedArgs = [...args, ...defaultArgs];
@@ -41,13 +33,18 @@ async function start(args: string[]) {
4133

4234
const defaultArgs = ['--viaCli', '--experimentalStructuredContent'];
4335

44-
const y = yargs(argv)
36+
const y = yargs(hideBin(process.argv))
4537
.scriptName('chrome-devtools')
4638
.showHelpOnFail(true)
39+
.usage('chrome-devtools <command> [...args] --flags')
40+
.usage(
41+
`Run 'chrome-devtools <command> --help' for help on the specific command.`,
42+
)
4743
.demandCommand()
4844
.version(VERSION)
4945
.strict()
50-
.help(true);
46+
.help(true)
47+
.wrap(120);
5148

5249
y.command(
5350
'start',
@@ -84,7 +81,6 @@ y.command('status', 'Checks if chrome-devtools-mcp is running', async () => {
8481
y.command('stop', 'Stop chrome-devtools-mcp if any', async () => {
8582
if (!isDaemonRunning()) {
8683
process.exit(0);
87-
return;
8884
}
8985
await stopDaemon();
9086
process.exit(0);
@@ -96,11 +92,19 @@ for (const [commandName, commandDef] of Object.entries(commands)) {
9692
name => args[name].required,
9793
);
9894

95+
const optionalArgNames = Object.keys(args).filter(
96+
name => !args[name].required,
97+
);
98+
9999
let commandStr = commandName;
100100
for (const arg of requiredArgNames) {
101101
commandStr += ` <${arg}>`;
102102
}
103103

104+
for (const arg of optionalArgNames) {
105+
commandStr += ` [--${arg}]`;
106+
}
107+
104108
y.command(
105109
commandStr,
106110
commandDef.description,

0 commit comments

Comments
 (0)