chrome-devtools-mcp 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -1
- package/build/src/browser.js +48 -2
- package/build/src/cli.js +20 -0
- package/build/src/main.js +9 -3
- package/build/src/third_party/THIRD_PARTY_NOTICES +2 -1948
- package/build/src/third_party/index.js +533 -33261
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ control and inspect a live Chrome browser. It acts as a Model-Context-Protocol
|
|
|
7
7
|
(MCP) server, giving your AI coding assistant access to the full power of
|
|
8
8
|
Chrome DevTools for reliable automation, in-depth debugging, and performance analysis.
|
|
9
9
|
|
|
10
|
-
## [Tool reference](./docs/tool-reference.md) | [Changelog](./CHANGELOG.md) | [Contributing](./CONTRIBUTING.md) | [Troubleshooting](./docs/troubleshooting.md)
|
|
10
|
+
## [Tool reference](./docs/tool-reference.md) | [Changelog](./CHANGELOG.md) | [Contributing](./CONTRIBUTING.md) | [Troubleshooting](./docs/troubleshooting.md) | [Design Principles](./docs/design-principles.md)
|
|
11
11
|
|
|
12
12
|
## Key features
|
|
13
13
|
|
|
@@ -350,6 +350,11 @@ The Chrome DevTools MCP server supports the following configuration option:
|
|
|
350
350
|
|
|
351
351
|
<!-- BEGIN AUTO GENERATED OPTIONS -->
|
|
352
352
|
|
|
353
|
+
- **`--autoConnect`**
|
|
354
|
+
If specified, automatically connects to a browser (Chrome 145+) running in the user data directory identified by the channel param. Requires remote debugging being enabled in Chrome here: chrome://inspect/#remote-debugging.
|
|
355
|
+
- **Type:** boolean
|
|
356
|
+
- **Default:** `false`
|
|
357
|
+
|
|
353
358
|
- **`--browserUrl`, `-u`**
|
|
354
359
|
Connect to a running, debuggable Chrome instance (e.g. `http://127.0.0.1:9222`). For more details see: https://github.com/ChromeDevTools/chrome-devtools-mcp#connecting-to-a-running-chrome-instance.
|
|
355
360
|
- **Type:** string
|
package/build/src/browser.js
CHANGED
|
@@ -32,6 +32,7 @@ function makeTargetFilter() {
|
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
34
|
export async function ensureBrowserConnected(options) {
|
|
35
|
+
const { channel } = options;
|
|
35
36
|
if (browser?.connected) {
|
|
36
37
|
return browser;
|
|
37
38
|
}
|
|
@@ -49,11 +50,56 @@ export async function ensureBrowserConnected(options) {
|
|
|
49
50
|
else if (options.browserURL) {
|
|
50
51
|
connectOptions.browserURL = options.browserURL;
|
|
51
52
|
}
|
|
53
|
+
else if (channel || options.userDataDir) {
|
|
54
|
+
const userDataDir = options.userDataDir;
|
|
55
|
+
if (userDataDir) {
|
|
56
|
+
// TODO: re-expose this logic via Puppeteer.
|
|
57
|
+
const portPath = path.join(userDataDir, 'DevToolsActivePort');
|
|
58
|
+
try {
|
|
59
|
+
const fileContent = await fs.promises.readFile(portPath, 'utf8');
|
|
60
|
+
const [rawPort, rawPath] = fileContent
|
|
61
|
+
.split('\n')
|
|
62
|
+
.map(line => {
|
|
63
|
+
return line.trim();
|
|
64
|
+
})
|
|
65
|
+
.filter(line => {
|
|
66
|
+
return !!line;
|
|
67
|
+
});
|
|
68
|
+
if (!rawPort || !rawPath) {
|
|
69
|
+
throw new Error(`Invalid DevToolsActivePort '${fileContent}' found`);
|
|
70
|
+
}
|
|
71
|
+
const port = parseInt(rawPort, 10);
|
|
72
|
+
if (isNaN(port) || port <= 0 || port > 65535) {
|
|
73
|
+
throw new Error(`Invalid port '${rawPort}' found`);
|
|
74
|
+
}
|
|
75
|
+
const browserWSEndpoint = `ws://127.0.0.1:${port}${rawPath}`;
|
|
76
|
+
connectOptions.browserWSEndpoint = browserWSEndpoint;
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
throw new Error(`Could not connect to Chrome in ${userDataDir}. Check if Chrome is running and remote debugging is enabled.`, {
|
|
80
|
+
cause: error,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
if (!channel) {
|
|
86
|
+
throw new Error('Channel must be provided if userDataDir is missing');
|
|
87
|
+
}
|
|
88
|
+
connectOptions.channel = (channel === 'stable' ? 'chrome' : `chrome-${channel}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
52
91
|
else {
|
|
53
|
-
throw new Error('Either browserURL or
|
|
92
|
+
throw new Error('Either browserURL, wsEndpoint, channel or userDataDir must be provided');
|
|
54
93
|
}
|
|
55
94
|
logger('Connecting Puppeteer to ', JSON.stringify(connectOptions));
|
|
56
|
-
|
|
95
|
+
try {
|
|
96
|
+
browser = await puppeteer.connect(connectOptions);
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
throw new Error('Could not connect to Chrome. Check if Chrome is running and remote debugging is enabled by going to chrome://inspect/#remote-debugging.', {
|
|
100
|
+
cause: err,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
57
103
|
logger('Connected Puppeteer');
|
|
58
104
|
return browser;
|
|
59
105
|
}
|
package/build/src/cli.js
CHANGED
|
@@ -5,6 +5,18 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { yargs, hideBin } from './third_party/index.js';
|
|
7
7
|
export const cliOptions = {
|
|
8
|
+
autoConnect: {
|
|
9
|
+
type: 'boolean',
|
|
10
|
+
description: 'If specified, automatically connects to a browser (Chrome 145+) running in the user data directory identified by the channel param. Requires remote debugging being enabled in Chrome here: chrome://inspect/#remote-debugging.',
|
|
11
|
+
conflicts: ['isolated', 'executablePath'],
|
|
12
|
+
default: false,
|
|
13
|
+
coerce: (value) => {
|
|
14
|
+
if (!value) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
return value;
|
|
18
|
+
},
|
|
19
|
+
},
|
|
8
20
|
browserUrl: {
|
|
9
21
|
type: 'string',
|
|
10
22
|
description: 'Connect to a running, debuggable Chrome instance (e.g. `http://127.0.0.1:9222`). For more details see: https://github.com/ChromeDevTools/chrome-devtools-mcp#connecting-to-a-running-chrome-instance.',
|
|
@@ -204,6 +216,14 @@ export function parseArguments(version, argv = process.argv) {
|
|
|
204
216
|
'$0 --user-data-dir=/tmp/user-data-dir',
|
|
205
217
|
'Use a custom user data directory',
|
|
206
218
|
],
|
|
219
|
+
[
|
|
220
|
+
'$0 --auto-connect',
|
|
221
|
+
'Connect to a stable Chrome instance (Chrome 145+) running instead of launching a new instance',
|
|
222
|
+
],
|
|
223
|
+
[
|
|
224
|
+
'$0 --auto-connect --channel=canary',
|
|
225
|
+
'Connect to a canary Chrome instance (Chrome 145+) running instead of launching a new instance',
|
|
226
|
+
],
|
|
207
227
|
]);
|
|
208
228
|
return yargsInstance
|
|
209
229
|
.wrap(Math.min(120, yargsInstance.terminalWidth()))
|
package/build/src/main.js
CHANGED
|
@@ -16,7 +16,7 @@ import { ToolCategory } from './tools/categories.js';
|
|
|
16
16
|
import { tools } from './tools/tools.js';
|
|
17
17
|
// If moved update release-please config
|
|
18
18
|
// x-release-please-start-version
|
|
19
|
-
const VERSION = '0.
|
|
19
|
+
const VERSION = '0.12.0';
|
|
20
20
|
// x-release-please-end
|
|
21
21
|
export const args = parseArguments(VERSION);
|
|
22
22
|
const logFile = args.logFile ? saveLogsToFile(args.logFile) : undefined;
|
|
@@ -36,11 +36,14 @@ async function getContext() {
|
|
|
36
36
|
extraArgs.push(`--proxy-server=${args.proxyServer}`);
|
|
37
37
|
}
|
|
38
38
|
const devtools = args.experimentalDevtools ?? false;
|
|
39
|
-
const browser = args.browserUrl || args.wsEndpoint
|
|
39
|
+
const browser = args.browserUrl || args.wsEndpoint || args.autoConnect
|
|
40
40
|
? await ensureBrowserConnected({
|
|
41
41
|
browserURL: args.browserUrl,
|
|
42
42
|
wsEndpoint: args.wsEndpoint,
|
|
43
43
|
wsHeaders: args.wsHeaders,
|
|
44
|
+
// Important: only pass channel, if autoConnect is true.
|
|
45
|
+
channel: args.autoConnect ? args.channel : undefined,
|
|
46
|
+
userDataDir: args.userDataDir,
|
|
44
47
|
devtools,
|
|
45
48
|
})
|
|
46
49
|
: await ensureBrowserLaunched({
|
|
@@ -104,7 +107,10 @@ function registerTool(tool) {
|
|
|
104
107
|
}
|
|
105
108
|
catch (err) {
|
|
106
109
|
logger(`${tool.name} error:`, err, err?.stack);
|
|
107
|
-
|
|
110
|
+
let errorText = err && 'message' in err ? err.message : String(err);
|
|
111
|
+
if ('cause' in err && err.cause) {
|
|
112
|
+
errorText += `\nCause: ${err.cause.message}`;
|
|
113
|
+
}
|
|
108
114
|
return {
|
|
109
115
|
content: [
|
|
110
116
|
{
|