chrome-devtools-mcp 0.24.0 → 0.26.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.
Files changed (33) hide show
  1. package/README.md +23 -6
  2. package/build/src/McpPage.js +4 -4
  3. package/build/src/McpResponse.js +18 -16
  4. package/build/src/TextSnapshot.js +2 -2
  5. package/build/src/ToolHandler.js +188 -0
  6. package/build/src/bin/chrome-devtools-cli-options.js +28 -5
  7. package/build/src/bin/chrome-devtools-mcp-cli-options.js +8 -5
  8. package/build/src/bin/chrome-devtools-mcp-main.js +4 -8
  9. package/build/src/bin/chrome-devtools.js +0 -2
  10. package/build/src/index.js +9 -164
  11. package/build/src/telemetry/ClearcutLogger.js +27 -0
  12. package/build/src/telemetry/errors.js +14 -0
  13. package/build/src/telemetry/types.js +0 -8
  14. package/build/src/third_party/THIRD_PARTY_NOTICES +12 -14
  15. package/build/src/third_party/bundled-packages.json +3 -3
  16. package/build/src/third_party/devtools-formatter-worker.js +49 -33
  17. package/build/src/third_party/devtools-heap-snapshot-worker.js +60 -44
  18. package/build/src/third_party/index.js +2138 -1352
  19. package/build/src/third_party/issue-descriptions/genericFormModelContextMissingToolDescription.md +5 -0
  20. package/build/src/third_party/issue-descriptions/genericFormModelContextMissingToolName.md +5 -0
  21. package/build/src/third_party/issue-descriptions/genericFormModelContextParameterMissingName.md +5 -0
  22. package/build/src/third_party/issue-descriptions/genericFormModelContextParameterMissingTitleAndDescription.md +5 -0
  23. package/build/src/third_party/issue-descriptions/genericFormModelContextRequiredParameterMissingName.md +5 -0
  24. package/build/src/third_party/lighthouse-devtools-mcp-bundle.js +4236 -4219
  25. package/build/src/tools/categories.js +6 -3
  26. package/build/src/tools/input.js +72 -7
  27. package/build/src/tools/lighthouse.js +7 -7
  28. package/build/src/tools/pages.js +5 -5
  29. package/build/src/tools/{inPage.js → thirdPartyDeveloper.js} +15 -15
  30. package/build/src/tools/tools.js +2 -2
  31. package/build/src/tools/webmcp.js +2 -4
  32. package/build/src/version.js +1 -1
  33. package/package.json +7 -8
package/README.md CHANGED
@@ -161,7 +161,7 @@ To install Chrome DevTools MCP with skills, add the marketplace registry in Clau
161
161
  Then, install the plugin:
162
162
 
163
163
  ```sh
164
- /plugin install chrome-devtools-mcp
164
+ /plugin install chrome-devtools-mcp@chrome-devtools-plugins
165
165
  ```
166
166
 
167
167
  Restart Claude Code to have the MCP server and skills load (check with `/skills`).
@@ -477,7 +477,7 @@ If you run into any issues, checkout our [troubleshooting guide](./docs/troubles
477
477
 
478
478
  <!-- BEGIN AUTO GENERATED TOOLS -->
479
479
 
480
- - **Input automation** (9 tools)
480
+ - **Input automation** (10 tools)
481
481
  - [`click`](docs/tool-reference.md#click)
482
482
  - [`drag`](docs/tool-reference.md#drag)
483
483
  - [`fill`](docs/tool-reference.md#fill)
@@ -487,6 +487,7 @@ If you run into any issues, checkout our [troubleshooting guide](./docs/troubles
487
487
  - [`press_key`](docs/tool-reference.md#press_key)
488
488
  - [`type_text`](docs/tool-reference.md#type_text)
489
489
  - [`upload_file`](docs/tool-reference.md#upload_file)
490
+ - [`click_at`](docs/tool-reference.md#click_at)
490
491
  - **Navigation automation** (6 tools)
491
492
  - [`close_page`](docs/tool-reference.md#close_page)
492
493
  - [`list_pages`](docs/tool-reference.md#list_pages)
@@ -504,21 +505,32 @@ If you run into any issues, checkout our [troubleshooting guide](./docs/troubles
504
505
  - **Network** (2 tools)
505
506
  - [`get_network_request`](docs/tool-reference.md#get_network_request)
506
507
  - [`list_network_requests`](docs/tool-reference.md#list_network_requests)
507
- - **Debugging** (6 tools)
508
+ - **Debugging** (8 tools)
508
509
  - [`evaluate_script`](docs/tool-reference.md#evaluate_script)
509
510
  - [`get_console_message`](docs/tool-reference.md#get_console_message)
510
511
  - [`lighthouse_audit`](docs/tool-reference.md#lighthouse_audit)
511
512
  - [`list_console_messages`](docs/tool-reference.md#list_console_messages)
512
513
  - [`take_screenshot`](docs/tool-reference.md#take_screenshot)
513
514
  - [`take_snapshot`](docs/tool-reference.md#take_snapshot)
515
+ - [`screencast_start`](docs/tool-reference.md#screencast_start)
516
+ - [`screencast_stop`](docs/tool-reference.md#screencast_stop)
517
+ - **Memory** (4 tools)
518
+ - [`take_memory_snapshot`](docs/tool-reference.md#take_memory_snapshot)
519
+ - [`get_memory_snapshot_details`](docs/tool-reference.md#get_memory_snapshot_details)
520
+ - [`get_nodes_by_class`](docs/tool-reference.md#get_nodes_by_class)
521
+ - [`load_memory_snapshot`](docs/tool-reference.md#load_memory_snapshot)
514
522
  - **Extensions** (5 tools)
515
523
  - [`install_extension`](docs/tool-reference.md#install_extension)
516
524
  - [`list_extensions`](docs/tool-reference.md#list_extensions)
517
525
  - [`reload_extension`](docs/tool-reference.md#reload_extension)
518
526
  - [`trigger_extension_action`](docs/tool-reference.md#trigger_extension_action)
519
527
  - [`uninstall_extension`](docs/tool-reference.md#uninstall_extension)
520
- - **Memory** (1 tools)
521
- - [`take_memory_snapshot`](docs/tool-reference.md#take_memory_snapshot)
528
+ - **Third-party** (2 tools)
529
+ - [`execute_3p_developer_tool`](docs/tool-reference.md#execute_3p_developer_tool)
530
+ - [`list_3p_developer_tools`](docs/tool-reference.md#list_3p_developer_tools)
531
+ - **WebMCP** (2 tools)
532
+ - [`execute_webmcp_tool`](docs/tool-reference.md#execute_webmcp_tool)
533
+ - [`list_webmcp_tools`](docs/tool-reference.md#list_webmcp_tools)
522
534
 
523
535
  <!-- END AUTO GENERATED TOOLS -->
524
536
 
@@ -595,7 +607,7 @@ The Chrome DevTools MCP server supports the following configuration option:
595
607
  Path to ffmpeg executable for screencast recording.
596
608
  - **Type:** string
597
609
 
598
- - **`--experimentalWebmcp`/ `--experimental-webmcp`**
610
+ - **`--categoryExperimentalWebmcp`/ `--category-experimental-webmcp`**
599
611
  Set to true to enable debugging WebMCP tools. Requires Chrome 149+ with the following flags: `--enable-features=WebMCPTesting,DevToolsWebMCPSupport`
600
612
  - **Type:** boolean
601
613
 
@@ -627,6 +639,11 @@ The Chrome DevTools MCP server supports the following configuration option:
627
639
  - **Type:** boolean
628
640
  - **Default:** `false`
629
641
 
642
+ - **`--categoryExperimentalThirdParty`/ `--category-experimental-third-party`**
643
+ Set to true to enable third-party developer tools exposed by the inspected page itself
644
+ - **Type:** boolean
645
+ - **Default:** `false`
646
+
630
647
  - **`--performanceCrux`/ `--performance-crux`**
631
648
  Set to false to disable sending URLs from performance traces to CrUX API to get field performance data.
632
649
  - **Type:** boolean
@@ -30,7 +30,7 @@ export class McpPage {
30
30
  // Dialog
31
31
  #dialog;
32
32
  #dialogHandler;
33
- inPageTools;
33
+ thirdPartyDeveloperTools;
34
34
  constructor(page, id) {
35
35
  this.pptrPage = page;
36
36
  this.id = id;
@@ -53,8 +53,8 @@ export class McpPage {
53
53
  throw new Error(`A dialog is open (${this.#dialog.type()}: ${this.#dialog.message()}).`);
54
54
  }
55
55
  }
56
- getInPageTools() {
57
- return this.inPageTools;
56
+ getThirdPartyDeveloperTools() {
57
+ return this.thirdPartyDeveloperTools;
58
58
  }
59
59
  getWebMcpTools() {
60
60
  return this.pptrPage.webmcp.tools();
@@ -88,7 +88,7 @@ export class McpPage {
88
88
  dispose() {
89
89
  this.pptrPage.off('dialog', this.#dialogHandler);
90
90
  }
91
- async executeInPageTool(toolName, params, response) {
91
+ async executeThirdPartyDeveloperTool(toolName, params, response) {
92
92
  // Creates array of ElementHandles from the UIDs in the params.
93
93
  // We do not replace the uids with the ElementsHandles yet, because
94
94
  // the `evaluate` function only turns them into DOM elements if they
@@ -125,7 +125,7 @@ export class McpResponse {
125
125
  #networkRequestsOptions;
126
126
  #consoleDataOptions;
127
127
  #listExtensions;
128
- #listInPageTools;
128
+ #listThirdPartyDeveloperTools;
129
129
  #listWebMcpTools;
130
130
  #devToolsData;
131
131
  #tabId;
@@ -163,9 +163,9 @@ export class McpResponse {
163
163
  setListExtensions() {
164
164
  this.#listExtensions = true;
165
165
  }
166
- setListInPageTools() {
167
- if (this.#args.categoryExperimentalInPage) {
168
- this.#listInPageTools = true;
166
+ setListThirdPartyDeveloperTools() {
167
+ if (this.#args.categoryExperimentalThirdParty) {
168
+ this.#listThirdPartyDeveloperTools = true;
169
169
  }
170
170
  }
171
171
  setListWebMcpTools() {
@@ -381,14 +381,14 @@ export class McpResponse {
381
381
  if (this.#listExtensions) {
382
382
  extensions = await context.listExtensions();
383
383
  }
384
- let inPageTools;
385
- if (this.#listInPageTools) {
384
+ let thirdPartyDeveloperTools;
385
+ if (this.#listThirdPartyDeveloperTools) {
386
386
  const page = this.#page ?? context.getSelectedMcpPage();
387
- inPageTools = await getToolGroup(page);
388
- page.inPageTools = inPageTools;
387
+ thirdPartyDeveloperTools = await getToolGroup(page);
388
+ page.thirdPartyDeveloperTools = thirdPartyDeveloperTools;
389
389
  }
390
390
  let webmcpTools;
391
- if (this.#listWebMcpTools && this.#args.experimentalWebmcp) {
391
+ if (this.#listWebMcpTools && this.#args.categoryExperimentalWebmcp) {
392
392
  const page = this.#page ?? context.getSelectedMcpPage();
393
393
  webmcpTools = page.getWebMcpTools();
394
394
  }
@@ -469,7 +469,7 @@ export class McpResponse {
469
469
  traceSummary: this.#attachedTraceSummary,
470
470
  extensions,
471
471
  lighthouseResult: this.#attachedLighthouseResult,
472
- inPageTools,
472
+ thirdPartyDeveloperTools,
473
473
  webmcpTools,
474
474
  errorMessage: this.#error?.message,
475
475
  });
@@ -700,14 +700,16 @@ Call ${handleDialog.name} to handle it before continuing.`);
700
700
  response.push(extensionsMessage);
701
701
  }
702
702
  }
703
- if (this.#listInPageTools) {
704
- structuredContent.inPageTools = data.inPageTools ?? undefined;
705
- response.push('## In-page tools');
706
- if (!data.inPageTools || !data.inPageTools.tools) {
707
- response.push('No in-page tools available.');
703
+ if (this.#listThirdPartyDeveloperTools) {
704
+ structuredContent.thirdPartyDeveloperTools =
705
+ data.thirdPartyDeveloperTools ?? undefined;
706
+ response.push('## Third-party developer tools');
707
+ if (!data.thirdPartyDeveloperTools ||
708
+ !data.thirdPartyDeveloperTools.tools) {
709
+ response.push('No third-party developer tools available.');
708
710
  }
709
711
  else {
710
- const toolGroup = data.inPageTools;
712
+ const toolGroup = data.thirdPartyDeveloperTools;
711
713
  response.push(`${toolGroup.name}: ${toolGroup.description}`);
712
714
  response.push('Available tools:');
713
715
  const toolDefinitionsMessage = toolGroup.tools
@@ -99,8 +99,8 @@ export class TextSnapshot {
99
99
  return snapshot;
100
100
  }
101
101
  // ExtraHandles represent DOM nodes which might not be part of the accessibility tree, e.g. DOM nodes
102
- // returned by in-page tools. We insert them into the tree by finding the closest ancestor in the
103
- // tree and inserting the node as a child. The ancestor's child nodes are re-parented if necessary.
102
+ // returned by third-party developer tools. We insert them into the tree by finding the closest ancestor
103
+ // in the tree and inserting the node as a child. The ancestor's child nodes are re-parented if necessary.
104
104
  static async insertExtraNodes(page, idToNode, seenUniqueIds, snapshotId, idCounter, rootNodeWithId, seenBackendNodeIds, extraHandles) {
105
105
  const { uniqueBackendNodeIdToMcpId } = page;
106
106
  const createExtraNode = async (handle) => {
@@ -0,0 +1,188 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { logger } from './logger.js';
7
+ import { McpResponse } from './McpResponse.js';
8
+ import { SlimMcpResponse } from './SlimMcpResponse.js';
9
+ import { ClearcutLogger } from './telemetry/ClearcutLogger.js';
10
+ import { bucketizeLatency } from './telemetry/metricUtils.js';
11
+ import { labels, OFF_BY_DEFAULT_CATEGORIES } from './tools/categories.js';
12
+ import { pageIdSchema } from './tools/ToolDefinition.js';
13
+ export function buildFlag(category) {
14
+ return `category${category.charAt(0).toUpperCase() + category.slice(1)}`;
15
+ }
16
+ function buildDisabledMessage(toolName, flag, categoryLabel) {
17
+ const reason = categoryLabel
18
+ ? `is in category ${categoryLabel} which`
19
+ : `requires experimental feature ${flag} and`;
20
+ return `Tool ${toolName} ${reason} is currently disabled. Enable it by running chrome-devtools start ${flag}=true. For more information check the README.`;
21
+ }
22
+ function getCategoryStatus(category, serverArgs) {
23
+ const categoryFlag = buildFlag(category);
24
+ const flagValue = serverArgs[categoryFlag];
25
+ const isDisabled = OFF_BY_DEFAULT_CATEGORIES.includes(category)
26
+ ? !flagValue
27
+ : flagValue === false;
28
+ if (isDisabled) {
29
+ return {
30
+ categoryFlag,
31
+ disabled: true,
32
+ };
33
+ }
34
+ return {
35
+ disabled: false,
36
+ };
37
+ }
38
+ function getConditionStatus(condition, serverArgs) {
39
+ if (condition && !serverArgs[condition]) {
40
+ return { conditionFlag: condition, disabled: true };
41
+ }
42
+ return { disabled: false };
43
+ }
44
+ function getToolStatusInfo(tool, serverArgs) {
45
+ const category = tool.annotations.category;
46
+ const categoryCheck = getCategoryStatus(category, serverArgs);
47
+ if (category && categoryCheck.disabled) {
48
+ if (!categoryCheck.categoryFlag) {
49
+ throw new Error('when the category is disabled there should always be a flag set');
50
+ }
51
+ return {
52
+ disabled: true,
53
+ reason: buildDisabledMessage(tool.name, `--${categoryCheck.categoryFlag}`, labels[category]),
54
+ };
55
+ }
56
+ for (const condition of tool.annotations.conditions || []) {
57
+ const conditionCheck = getConditionStatus(condition, serverArgs);
58
+ if (conditionCheck.disabled) {
59
+ if (!conditionCheck.conditionFlag) {
60
+ throw new Error('when the condition is disabled there should always be a flag set');
61
+ }
62
+ return {
63
+ disabled: true,
64
+ reason: buildDisabledMessage(tool.name, `--${conditionCheck.conditionFlag}`),
65
+ };
66
+ }
67
+ }
68
+ return { disabled: false };
69
+ }
70
+ function isPageScopedTool(tool) {
71
+ return 'pageScoped' in tool && tool.pageScoped === true;
72
+ }
73
+ export class ToolHandler {
74
+ tool;
75
+ serverArgs;
76
+ getContext;
77
+ toolMutex;
78
+ inputSchema;
79
+ shouldRegister;
80
+ disabledReason;
81
+ constructor(tool, serverArgs, getContext, toolMutex) {
82
+ this.tool = tool;
83
+ this.serverArgs = serverArgs;
84
+ this.getContext = getContext;
85
+ this.toolMutex = toolMutex;
86
+ const { disabled, reason } = getToolStatusInfo(tool, serverArgs);
87
+ this.disabledReason = reason;
88
+ this.shouldRegister = !(disabled && !serverArgs.viaCli);
89
+ this.inputSchema =
90
+ 'pageScoped' in tool &&
91
+ tool.pageScoped &&
92
+ serverArgs.experimentalPageIdRouting &&
93
+ !serverArgs.slim
94
+ ? { ...tool.schema, ...pageIdSchema }
95
+ : tool.schema;
96
+ }
97
+ async handle(params) {
98
+ if (this.disabledReason) {
99
+ return {
100
+ content: [
101
+ {
102
+ type: 'text',
103
+ text: this.disabledReason,
104
+ },
105
+ ],
106
+ isError: true,
107
+ };
108
+ }
109
+ const guard = await this.toolMutex.acquire();
110
+ const startTime = Date.now();
111
+ let success = false;
112
+ try {
113
+ logger(`${this.tool.name} request: ${JSON.stringify(params, null, ' ')}`);
114
+ const context = await this.getContext();
115
+ logger(`${this.tool.name} context: resolved`);
116
+ await context.detectOpenDevToolsWindows();
117
+ const response = this.serverArgs.slim
118
+ ? new SlimMcpResponse(this.serverArgs)
119
+ : new McpResponse(this.serverArgs);
120
+ response.setRedactNetworkHeaders(this.serverArgs.redactNetworkHeaders);
121
+ try {
122
+ if (isPageScopedTool(this.tool)) {
123
+ const pageId = typeof params.pageId === 'number' ? params.pageId : undefined;
124
+ const page = this.serverArgs.experimentalPageIdRouting &&
125
+ pageId !== undefined &&
126
+ !this.serverArgs.slim
127
+ ? context.getPageById(pageId)
128
+ : context.getSelectedMcpPage();
129
+ response.setPage(page);
130
+ if (this.tool.blockedByDialog) {
131
+ page.throwIfDialogOpen();
132
+ }
133
+ await this.tool.handler({
134
+ params,
135
+ page,
136
+ }, response, context);
137
+ }
138
+ else {
139
+ await this.tool.handler({
140
+ params,
141
+ }, response, context);
142
+ }
143
+ }
144
+ catch (err) {
145
+ response.setError(err);
146
+ }
147
+ const { content, structuredContent } = await response.handle(this.tool.name, context);
148
+ const result = {
149
+ content,
150
+ };
151
+ if (response.error) {
152
+ result.isError = true;
153
+ }
154
+ success = true;
155
+ if (this.serverArgs.experimentalStructuredContent) {
156
+ result.structuredContent = structuredContent;
157
+ }
158
+ return result;
159
+ }
160
+ catch (err) {
161
+ logger(`${this.tool.name} error:`, err, err?.stack);
162
+ let errorText = err && 'message' in err ? err.message : String(err);
163
+ if ('cause' in err && err.cause) {
164
+ errorText += `\nCause: ${err.cause.message}`;
165
+ }
166
+ return {
167
+ content: [
168
+ {
169
+ type: 'text',
170
+ text: errorText,
171
+ },
172
+ ],
173
+ isError: true,
174
+ };
175
+ }
176
+ finally {
177
+ void ClearcutLogger.get()?.logToolInvocation({
178
+ toolName: this.tool.name,
179
+ params,
180
+ schema: this.inputSchema,
181
+ success,
182
+ latencyMs: bucketizeLatency(Date.now() - startTime),
183
+ });
184
+ guard.dispose();
185
+ }
186
+ }
187
+ }
188
+ //# sourceMappingURL=ToolHandler.js.map
@@ -162,9 +162,27 @@ export const commands = {
162
162
  },
163
163
  },
164
164
  },
165
+ execute_3p_developer_tool: {
166
+ description: 'Executes a tool exposed by the page. (requires flag: --categoryExperimentalThirdParty=true)',
167
+ category: 'Third-party',
168
+ args: {
169
+ toolName: {
170
+ name: 'toolName',
171
+ type: 'string',
172
+ description: 'The name of the tool to execute',
173
+ required: true,
174
+ },
175
+ params: {
176
+ name: 'params',
177
+ type: 'string',
178
+ description: 'The JSON-stringified parameters to pass to the tool',
179
+ required: false,
180
+ },
181
+ },
182
+ },
165
183
  execute_webmcp_tool: {
166
- description: 'Executes a WebMCP tool exposed by the page. (requires flag: --experimentalWebmcp=true)',
167
- category: 'Debugging',
184
+ description: 'Executes a WebMCP tool exposed by the page. (requires flag: --categoryExperimentalWebmcp=true)',
185
+ category: 'WebMCP',
168
186
  args: {
169
187
  toolName: {
170
188
  name: 'toolName',
@@ -193,7 +211,7 @@ export const commands = {
193
211
  value: {
194
212
  name: 'value',
195
213
  type: 'string',
196
- description: 'The value to fill in',
214
+ description: 'The value to fill in. "true" or "false" for checkboxes and toggles, "true" for radio buttons.',
197
215
  required: true,
198
216
  },
199
217
  includeSnapshot: {
@@ -371,6 +389,11 @@ export const commands = {
371
389
  },
372
390
  },
373
391
  },
392
+ list_3p_developer_tools: {
393
+ description: "Lists all third-party developer tools the page exposes for providing runtime information.\n Third-party developer tools can be called via the 'execute_3p_developer_tool()' MCP tool.\n Alternatively, third-party developer tools can be executed by calling 'evaluate_script' and adding the\n following command to the script:\n 'window.__dtmcp.executeTool(toolName, params)'\n This might be helpful when the third-party developer tools return non-serializable values or when composing\n third-party developer tools with additional functionality. (requires flag: --categoryExperimentalThirdParty=true)",
394
+ category: 'Third-party',
395
+ args: {},
396
+ },
374
397
  list_console_messages: {
375
398
  description: 'List all console messages for the currently selected page since the last navigation.',
376
399
  category: 'Debugging',
@@ -444,8 +467,8 @@ export const commands = {
444
467
  args: {},
445
468
  },
446
469
  list_webmcp_tools: {
447
- description: 'Lists all WebMCP tools the page exposes. (requires flag: --experimentalWebmcp=true)',
448
- category: 'Debugging',
470
+ description: 'Lists all WebMCP tools the page exposes. (requires flag: --categoryExperimentalWebmcp=true)',
471
+ category: 'WebMCP',
449
472
  args: {},
450
473
  },
451
474
  load_memory_snapshot: {
@@ -183,7 +183,7 @@ export const cliOptions = {
183
183
  describe: 'Path to ffmpeg executable for screencast recording.',
184
184
  implies: 'experimentalScreencast',
185
185
  },
186
- experimentalWebmcp: {
186
+ categoryExperimentalWebmcp: {
187
187
  type: 'boolean',
188
188
  describe: 'Set to true to enable debugging WebMCP tools. Requires Chrome 149+ with the following flags: `--enable-features=WebMCPTesting,DevToolsWebMCPSupport`',
189
189
  },
@@ -216,11 +216,10 @@ export const cliOptions = {
216
216
  default: false,
217
217
  describe: 'Set to true to include tools related to extensions. Note: This feature is currently only supported with a pipe connection. autoConnect, browserUrl, and wsEndpoint are not supported with this feature until 149 will be released.',
218
218
  },
219
- categoryExperimentalInPage: {
219
+ categoryExperimentalThirdParty: {
220
220
  type: 'boolean',
221
- hidden: true,
222
221
  default: false,
223
- describe: 'Set to true to enable tools exposed by the inspected page itself',
222
+ describe: 'Set to true to enable third-party developer tools exposed by the inspected page itself',
224
223
  },
225
224
  performanceCrux: {
226
225
  type: 'boolean',
@@ -262,7 +261,7 @@ export const cliOptions = {
262
261
  default: false,
263
262
  },
264
263
  };
265
- export function parseArguments(version, argv = process.argv) {
264
+ export function parseArguments(version, argv = process.argv, env = process.env) {
266
265
  const yargsInstance = yargs(hideBin(argv))
267
266
  .scriptName('npx chrome-devtools-mcp@latest')
268
267
  .options(cliOptions)
@@ -275,6 +274,10 @@ export function parseArguments(version, argv = process.argv) {
275
274
  !args.executablePath) {
276
275
  args.channel = 'stable';
277
276
  }
277
+ if (env['CI'] || env['CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS']) {
278
+ console.error("turning off usage statistics. process.env['CI'] || process.env['CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS'] is set.");
279
+ args.usageStatistics = false;
280
+ }
278
281
  return true;
279
282
  })
280
283
  .example([
@@ -7,6 +7,7 @@ import '../polyfill.js';
7
7
  import process from 'node:process';
8
8
  import { createMcpServer, logDisclaimers } from '../index.js';
9
9
  import { logger, saveLogsToFile } from '../logger.js';
10
+ import { ClearcutLogger } from '../telemetry/ClearcutLogger.js';
10
11
  import { computeFlagUsage } from '../telemetry/flagUtils.js';
11
12
  import { StdioServerTransport } from '../third_party/index.js';
12
13
  import { checkForUpdates } from '../utils/check-for-updates.js';
@@ -15,24 +16,19 @@ import { cliOptions, parseArguments } from './chrome-devtools-mcp-cli-options.js
15
16
  await checkForUpdates('Run `npm install chrome-devtools-mcp@latest` to update.');
16
17
  export const args = parseArguments(VERSION);
17
18
  const logFile = args.logFile ? saveLogsToFile(args.logFile) : undefined;
18
- if (process.env['CI'] ||
19
- process.env['CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS']) {
20
- console.error("turning off usage statistics. process.env['CI'] || process.env['CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS'] is set.");
21
- args.usageStatistics = false;
22
- }
23
19
  if (process.env['CHROME_DEVTOOLS_MCP_CRASH_ON_UNCAUGHT'] !== 'true') {
24
20
  process.on('unhandledRejection', (reason, promise) => {
25
21
  logger('Unhandled promise rejection', promise, reason);
26
22
  });
27
23
  }
28
24
  logger(`Starting Chrome DevTools MCP Server v${VERSION}`);
29
- const { server, clearcutLogger } = await createMcpServer(args, {
25
+ const { server } = await createMcpServer(args, {
30
26
  logFile,
31
27
  });
32
28
  const transport = new StdioServerTransport();
33
29
  await server.connect(transport);
34
30
  logger('Chrome DevTools MCP Server connected');
35
31
  logDisclaimers(args);
36
- void clearcutLogger?.logDailyActiveIfNeeded();
37
- void clearcutLogger?.logServerStart(computeFlagUsage(args, cliOptions));
32
+ void ClearcutLogger.get()?.logDailyActiveIfNeeded();
33
+ void ClearcutLogger.get()?.logServerStart(computeFlagUsage(args, cliOptions));
38
34
  //# sourceMappingURL=chrome-devtools-mcp-main.js.map
@@ -24,8 +24,6 @@ const defaultArgs = ['--viaCli', '--experimentalStructuredContent'];
24
24
  const startCliOptions = {
25
25
  ...cliOptions,
26
26
  };
27
- // Not supported in CLI on purpose.
28
- delete startCliOptions.autoConnect;
29
27
  // Missing CLI serialization.
30
28
  delete startCliOptions.viewport;
31
29
  // Change the defaults for the CLI.