chrome-devtools-mcp 0.19.0 → 0.20.1
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 +10 -2
- package/build/src/DevtoolsUtils.js +0 -46
- package/build/src/McpContext.js +39 -32
- package/build/src/McpResponse.js +51 -19
- package/build/src/bin/chrome-devtools-cli-options.js +651 -0
- package/build/src/{cli.js → bin/chrome-devtools-mcp-cli-options.js} +1 -1
- package/build/src/{main.js → bin/chrome-devtools-mcp-main.js} +7 -7
- package/build/src/bin/chrome-devtools-mcp.js +21 -0
- package/build/src/bin/chrome-devtools.js +4 -3
- package/build/src/bin/cliDefinitions.js +0 -36
- package/build/src/browser.js +8 -9
- package/build/src/daemon/client.js +1 -0
- package/build/src/daemon/daemon.js +7 -2
- package/build/src/daemon/utils.js +1 -1
- package/build/src/index.js +204 -16
- package/build/src/third_party/THIRD_PARTY_NOTICES +1 -1
- package/build/src/third_party/bundled-packages.json +2 -2
- package/build/src/third_party/devtools-formatter-worker.js +0 -2
- package/build/src/third_party/index.js +309 -89
- package/build/src/third_party/issue-descriptions/selectivePermissionsIntervention.md +7 -0
- package/build/src/version.js +1 -1
- package/package.json +8 -5
- package/build/src/server.js +0 -209
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Selective Permissions Intervention
|
|
2
|
+
|
|
3
|
+
The Selective Permissions Intervention blocks calls to privacy-sensitive APIs when they are called from ad scripts in order to align the permission grant with the user's intent. The particular API that was blocked, the call-stack that triggered the intervention, and why the script that called the API is considered ad-related is shown below.
|
|
4
|
+
|
|
5
|
+
Note that Chrome considers any script with a URL that matches a rule in the [filterlist](ChromeFilterlistRepository) as ad script, and the matching rule is shown in the Ad Ancestry section. In addition, any script loaded while an ad script is in the JavaScript stack will also be considered an ad script by Chrome and is also shown in Ad Ancestry.
|
|
6
|
+
|
|
7
|
+
If you believe this intervention was in error (e.g., this call would occur even when loading the page with an ad blocker enabled), then please [file a bug](SelectivePermissionsInterventionIssue).
|
package/build/src/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chrome-devtools-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.1",
|
|
4
4
|
"description": "MCP server for Chrome DevTools",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"bin":
|
|
7
|
-
|
|
6
|
+
"bin": {
|
|
7
|
+
"chrome-devtools-mcp": "./build/src/bin/chrome-devtools-mcp.js",
|
|
8
|
+
"chrome-devtools": "./build/src/bin/chrome-devtools.js"
|
|
9
|
+
},
|
|
10
|
+
"main": "./build/src/index.js",
|
|
8
11
|
"scripts": {
|
|
9
12
|
"cli:generate": "node --experimental-strip-types scripts/generate-cli.ts",
|
|
10
13
|
"clean": "node -e \"require('fs').rmSync('build', {recursive: true, force: true})\"",
|
|
@@ -56,7 +59,7 @@
|
|
|
56
59
|
"@types/yargs": "^17.0.33",
|
|
57
60
|
"@typescript-eslint/eslint-plugin": "^8.43.0",
|
|
58
61
|
"@typescript-eslint/parser": "^8.43.0",
|
|
59
|
-
"chrome-devtools-frontend": "1.0.
|
|
62
|
+
"chrome-devtools-frontend": "1.0.1596260",
|
|
60
63
|
"core-js": "3.48.0",
|
|
61
64
|
"debug": "4.4.3",
|
|
62
65
|
"eslint": "^9.35.0",
|
|
@@ -65,7 +68,7 @@
|
|
|
65
68
|
"globals": "^17.0.0",
|
|
66
69
|
"lighthouse": "13.0.3",
|
|
67
70
|
"prettier": "^3.6.2",
|
|
68
|
-
"puppeteer": "24.
|
|
71
|
+
"puppeteer": "24.39.1",
|
|
69
72
|
"rollup": "4.59.0",
|
|
70
73
|
"rollup-plugin-cleanup": "^3.2.1",
|
|
71
74
|
"rollup-plugin-license": "^3.6.0",
|
package/build/src/server.js
DELETED
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2026 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
import { ensureBrowserConnected, ensureBrowserLaunched } from './browser.js';
|
|
7
|
-
import { loadIssueDescriptions } from './issue-descriptions.js';
|
|
8
|
-
import { logger } from './logger.js';
|
|
9
|
-
import { McpContext } from './McpContext.js';
|
|
10
|
-
import { McpResponse } from './McpResponse.js';
|
|
11
|
-
import { Mutex } from './Mutex.js';
|
|
12
|
-
import { SlimMcpResponse } from './SlimMcpResponse.js';
|
|
13
|
-
import { ClearcutLogger } from './telemetry/ClearcutLogger.js';
|
|
14
|
-
import { bucketizeLatency } from './telemetry/metricUtils.js';
|
|
15
|
-
import { McpServer, SetLevelRequestSchema, } from './third_party/index.js';
|
|
16
|
-
import { ToolCategory } from './tools/categories.js';
|
|
17
|
-
import { pageIdSchema } from './tools/ToolDefinition.js';
|
|
18
|
-
import { createTools } from './tools/tools.js';
|
|
19
|
-
import { VERSION } from './version.js';
|
|
20
|
-
export async function createMcpServer(serverArgs, options) {
|
|
21
|
-
let clearcutLogger;
|
|
22
|
-
if (serverArgs.usageStatistics) {
|
|
23
|
-
clearcutLogger = new ClearcutLogger({
|
|
24
|
-
logFile: serverArgs.logFile,
|
|
25
|
-
appVersion: VERSION,
|
|
26
|
-
clearcutEndpoint: serverArgs.clearcutEndpoint,
|
|
27
|
-
clearcutForceFlushIntervalMs: serverArgs.clearcutForceFlushIntervalMs,
|
|
28
|
-
clearcutIncludePidHeader: serverArgs.clearcutIncludePidHeader,
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
const server = new McpServer({
|
|
32
|
-
name: 'chrome_devtools',
|
|
33
|
-
title: 'Chrome DevTools MCP server',
|
|
34
|
-
version: VERSION,
|
|
35
|
-
}, { capabilities: { logging: {} } });
|
|
36
|
-
server.server.setRequestHandler(SetLevelRequestSchema, () => {
|
|
37
|
-
return {};
|
|
38
|
-
});
|
|
39
|
-
let context;
|
|
40
|
-
async function getContext() {
|
|
41
|
-
const chromeArgs = (serverArgs.chromeArg ?? []).map(String);
|
|
42
|
-
const ignoreDefaultChromeArgs = (serverArgs.ignoreDefaultChromeArg ?? []).map(String);
|
|
43
|
-
if (serverArgs.proxyServer) {
|
|
44
|
-
chromeArgs.push(`--proxy-server=${serverArgs.proxyServer}`);
|
|
45
|
-
}
|
|
46
|
-
const devtools = serverArgs.experimentalDevtools ?? false;
|
|
47
|
-
const browser = serverArgs.browserUrl || serverArgs.wsEndpoint || serverArgs.autoConnect
|
|
48
|
-
? await ensureBrowserConnected({
|
|
49
|
-
browserURL: serverArgs.browserUrl,
|
|
50
|
-
wsEndpoint: serverArgs.wsEndpoint,
|
|
51
|
-
wsHeaders: serverArgs.wsHeaders,
|
|
52
|
-
// Important: only pass channel, if autoConnect is true.
|
|
53
|
-
channel: serverArgs.autoConnect
|
|
54
|
-
? serverArgs.channel
|
|
55
|
-
: undefined,
|
|
56
|
-
userDataDir: serverArgs.userDataDir,
|
|
57
|
-
devtools,
|
|
58
|
-
})
|
|
59
|
-
: await ensureBrowserLaunched({
|
|
60
|
-
headless: serverArgs.headless,
|
|
61
|
-
executablePath: serverArgs.executablePath,
|
|
62
|
-
channel: serverArgs.channel,
|
|
63
|
-
isolated: serverArgs.isolated ?? false,
|
|
64
|
-
userDataDir: serverArgs.userDataDir,
|
|
65
|
-
logFile: options.logFile,
|
|
66
|
-
viewport: serverArgs.viewport,
|
|
67
|
-
chromeArgs,
|
|
68
|
-
ignoreDefaultChromeArgs,
|
|
69
|
-
acceptInsecureCerts: serverArgs.acceptInsecureCerts,
|
|
70
|
-
devtools,
|
|
71
|
-
enableExtensions: serverArgs.categoryExtensions,
|
|
72
|
-
viaCli: serverArgs.viaCli,
|
|
73
|
-
});
|
|
74
|
-
if (context?.browser !== browser) {
|
|
75
|
-
context = await McpContext.from(browser, logger, {
|
|
76
|
-
experimentalDevToolsDebugging: devtools,
|
|
77
|
-
experimentalIncludeAllPages: serverArgs.experimentalIncludeAllPages,
|
|
78
|
-
performanceCrux: serverArgs.performanceCrux,
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
return context;
|
|
82
|
-
}
|
|
83
|
-
const toolMutex = new Mutex();
|
|
84
|
-
function registerTool(tool) {
|
|
85
|
-
if (tool.annotations.category === ToolCategory.EMULATION &&
|
|
86
|
-
serverArgs.categoryEmulation === false) {
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
if (tool.annotations.category === ToolCategory.PERFORMANCE &&
|
|
90
|
-
serverArgs.categoryPerformance === false) {
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
if (tool.annotations.category === ToolCategory.NETWORK &&
|
|
94
|
-
serverArgs.categoryNetwork === false) {
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
if (tool.annotations.category === ToolCategory.EXTENSIONS &&
|
|
98
|
-
serverArgs.categoryExtensions === false) {
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
if (tool.annotations.conditions?.includes('computerVision') &&
|
|
102
|
-
!serverArgs.experimentalVision) {
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
if (tool.annotations.conditions?.includes('experimentalInteropTools') &&
|
|
106
|
-
!serverArgs.experimentalInteropTools) {
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
if (tool.annotations.conditions?.includes('screencast') &&
|
|
110
|
-
!serverArgs.experimentalScreencast) {
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
const schema = 'pageScoped' in tool &&
|
|
114
|
-
tool.pageScoped &&
|
|
115
|
-
serverArgs.experimentalPageIdRouting &&
|
|
116
|
-
!serverArgs.slim
|
|
117
|
-
? { ...tool.schema, ...pageIdSchema }
|
|
118
|
-
: tool.schema;
|
|
119
|
-
server.registerTool(tool.name, {
|
|
120
|
-
description: tool.description,
|
|
121
|
-
inputSchema: schema,
|
|
122
|
-
annotations: tool.annotations,
|
|
123
|
-
}, async (params) => {
|
|
124
|
-
const guard = await toolMutex.acquire();
|
|
125
|
-
const startTime = Date.now();
|
|
126
|
-
let success = false;
|
|
127
|
-
try {
|
|
128
|
-
logger(`${tool.name} request: ${JSON.stringify(params, null, ' ')}`);
|
|
129
|
-
const context = await getContext();
|
|
130
|
-
logger(`${tool.name} context: resolved`);
|
|
131
|
-
await context.detectOpenDevToolsWindows();
|
|
132
|
-
const response = serverArgs.slim
|
|
133
|
-
? new SlimMcpResponse(serverArgs)
|
|
134
|
-
: new McpResponse(serverArgs);
|
|
135
|
-
if ('pageScoped' in tool && tool.pageScoped) {
|
|
136
|
-
const page = serverArgs.experimentalPageIdRouting &&
|
|
137
|
-
params.pageId &&
|
|
138
|
-
!serverArgs.slim
|
|
139
|
-
? context.getPageById(params.pageId)
|
|
140
|
-
: context.getSelectedMcpPage();
|
|
141
|
-
response.setPage(page);
|
|
142
|
-
await tool.handler({
|
|
143
|
-
params,
|
|
144
|
-
page,
|
|
145
|
-
}, response, context);
|
|
146
|
-
}
|
|
147
|
-
else {
|
|
148
|
-
await tool.handler(
|
|
149
|
-
// @ts-expect-error types do not match.
|
|
150
|
-
{
|
|
151
|
-
params,
|
|
152
|
-
}, response, context);
|
|
153
|
-
}
|
|
154
|
-
const { content, structuredContent } = await response.handle(tool.name, context);
|
|
155
|
-
const result = {
|
|
156
|
-
content,
|
|
157
|
-
};
|
|
158
|
-
success = true;
|
|
159
|
-
if (serverArgs.experimentalStructuredContent) {
|
|
160
|
-
result.structuredContent = structuredContent;
|
|
161
|
-
}
|
|
162
|
-
return result;
|
|
163
|
-
}
|
|
164
|
-
catch (err) {
|
|
165
|
-
logger(`${tool.name} error:`, err, err?.stack);
|
|
166
|
-
let errorText = err && 'message' in err ? err.message : String(err);
|
|
167
|
-
if ('cause' in err && err.cause) {
|
|
168
|
-
errorText += `\nCause: ${err.cause.message}`;
|
|
169
|
-
}
|
|
170
|
-
return {
|
|
171
|
-
content: [
|
|
172
|
-
{
|
|
173
|
-
type: 'text',
|
|
174
|
-
text: errorText,
|
|
175
|
-
},
|
|
176
|
-
],
|
|
177
|
-
isError: true,
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
finally {
|
|
181
|
-
void clearcutLogger?.logToolInvocation({
|
|
182
|
-
toolName: tool.name,
|
|
183
|
-
success,
|
|
184
|
-
latencyMs: bucketizeLatency(Date.now() - startTime),
|
|
185
|
-
});
|
|
186
|
-
guard.dispose();
|
|
187
|
-
}
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
const tools = createTools(serverArgs);
|
|
191
|
-
for (const tool of tools) {
|
|
192
|
-
registerTool(tool);
|
|
193
|
-
}
|
|
194
|
-
await loadIssueDescriptions();
|
|
195
|
-
return { server, clearcutLogger };
|
|
196
|
-
}
|
|
197
|
-
export const logDisclaimers = (args) => {
|
|
198
|
-
console.error(`chrome-devtools-mcp exposes content of the browser instance to the MCP clients allowing them to inspect,
|
|
199
|
-
debug, and modify any data in the browser or DevTools.
|
|
200
|
-
Avoid sharing sensitive or personal information that you do not want to share with MCP clients.`);
|
|
201
|
-
if (!args.slim && args.performanceCrux) {
|
|
202
|
-
console.error(`Performance tools may send trace URLs to the Google CrUX API to fetch real-user experience data. To disable, run with --no-performance-crux.`);
|
|
203
|
-
}
|
|
204
|
-
if (!args.slim && args.usageStatistics) {
|
|
205
|
-
console.error(`
|
|
206
|
-
Google collects usage statistics to improve Chrome DevTools MCP. To opt-out, run with --no-usage-statistics.
|
|
207
|
-
For more details, visit: https://github.com/ChromeDevTools/chrome-devtools-mcp#usage-statistics`);
|
|
208
|
-
}
|
|
209
|
-
};
|