chrome-devtools-mcp 0.23.0 → 0.24.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 (77) hide show
  1. package/build/src/DevToolsConnectionAdapter.js +1 -0
  2. package/build/src/DevtoolsUtils.js +1 -0
  3. package/build/src/HeapSnapshotManager.js +16 -0
  4. package/build/src/McpContext.js +57 -4
  5. package/build/src/McpPage.js +6 -0
  6. package/build/src/McpResponse.js +38 -4
  7. package/build/src/Mutex.js +1 -0
  8. package/build/src/PageCollector.js +1 -0
  9. package/build/src/SlimMcpResponse.js +1 -0
  10. package/build/src/TextSnapshot.js +11 -5
  11. package/build/src/WaitForHelper.js +6 -0
  12. package/build/src/bin/check-latest-version.js +1 -0
  13. package/build/src/bin/chrome-devtools-cli-options.js +206 -46
  14. package/build/src/bin/chrome-devtools-mcp-cli-options.js +3 -1
  15. package/build/src/bin/chrome-devtools-mcp-main.js +1 -0
  16. package/build/src/bin/chrome-devtools-mcp.js +1 -0
  17. package/build/src/bin/chrome-devtools.js +5 -13
  18. package/build/src/browser.js +1 -0
  19. package/build/src/daemon/client.js +4 -2
  20. package/build/src/daemon/daemon.js +1 -0
  21. package/build/src/daemon/types.js +1 -0
  22. package/build/src/daemon/utils.js +1 -0
  23. package/build/src/formatters/ConsoleFormatter.js +48 -1
  24. package/build/src/formatters/HeapSnapshotFormatter.js +18 -2
  25. package/build/src/formatters/IssueFormatter.js +1 -0
  26. package/build/src/formatters/NetworkFormatter.js +1 -0
  27. package/build/src/formatters/SnapshotFormatter.js +2 -1
  28. package/build/src/index.js +114 -51
  29. package/build/src/issue-descriptions.js +1 -0
  30. package/build/src/logger.js +1 -0
  31. package/build/src/polyfill.js +1 -0
  32. package/build/src/telemetry/ClearcutLogger.js +13 -1
  33. package/build/src/telemetry/WatchdogClient.js +1 -0
  34. package/build/src/telemetry/flagUtils.js +1 -0
  35. package/build/src/telemetry/metricUtils.js +1 -0
  36. package/build/src/telemetry/persistence.js +1 -0
  37. package/build/src/telemetry/toolMetricsUtils.js +2 -1
  38. package/build/src/telemetry/types.js +1 -0
  39. package/build/src/telemetry/watchdog/ClearcutSender.js +1 -0
  40. package/build/src/telemetry/watchdog/main.js +1 -0
  41. package/build/src/third_party/THIRD_PARTY_NOTICES +5 -5
  42. package/build/src/third_party/bundled-packages.json +2 -2
  43. package/build/src/third_party/devtools-formatter-worker.js +2451 -2933
  44. package/build/src/third_party/devtools-heap-snapshot-worker.js +32 -26
  45. package/build/src/third_party/index.js +535 -135
  46. package/build/src/third_party/lighthouse-devtools-mcp-bundle.js +21717 -20261
  47. package/build/src/tools/ToolDefinition.js +1 -0
  48. package/build/src/tools/categories.js +6 -2
  49. package/build/src/tools/console.js +3 -0
  50. package/build/src/tools/emulation.js +2 -0
  51. package/build/src/tools/extensions.js +6 -0
  52. package/build/src/tools/inPage.js +3 -2
  53. package/build/src/tools/input.js +13 -2
  54. package/build/src/tools/lighthouse.js +17 -9
  55. package/build/src/tools/memory.js +34 -1
  56. package/build/src/tools/network.js +5 -0
  57. package/build/src/tools/pages.js +9 -0
  58. package/build/src/tools/performance.js +6 -0
  59. package/build/src/tools/screencast.js +6 -2
  60. package/build/src/tools/screenshot.js +3 -0
  61. package/build/src/tools/script.js +2 -0
  62. package/build/src/tools/slim/tools.js +4 -0
  63. package/build/src/tools/snapshot.js +5 -1
  64. package/build/src/tools/tools.js +1 -0
  65. package/build/src/tools/webmcp.js +3 -0
  66. package/build/src/trace-processing/parse.js +1 -0
  67. package/build/src/types.js +1 -0
  68. package/build/src/utils/check-for-updates.js +1 -0
  69. package/build/src/utils/files.js +5 -10
  70. package/build/src/utils/id.js +1 -0
  71. package/build/src/utils/keyboard.js +1 -0
  72. package/build/src/utils/pagination.js +1 -0
  73. package/build/src/utils/string.js +1 -0
  74. package/build/src/utils/types.js +1 -0
  75. package/build/src/version.js +2 -1
  76. package/package.json +9 -9
  77. package/build/src/bin/cliDefinitions.js +0 -621
@@ -70,3 +70,4 @@ export function geolocationTransform(arg) {
70
70
  longitude,
71
71
  };
72
72
  }
73
+ //# sourceMappingURL=ToolDefinition.js.map
@@ -12,7 +12,7 @@ export var ToolCategory;
12
12
  ToolCategory["NETWORK"] = "network";
13
13
  ToolCategory["DEBUGGING"] = "debugging";
14
14
  ToolCategory["EXTENSIONS"] = "extensions";
15
- ToolCategory["IN_PAGE"] = "in-page";
15
+ ToolCategory["IN_PAGE"] = "experimentalInPage";
16
16
  ToolCategory["MEMORY"] = "memory";
17
17
  })(ToolCategory || (ToolCategory = {}));
18
18
  export const labels = {
@@ -26,4 +26,8 @@ export const labels = {
26
26
  [ToolCategory.IN_PAGE]: 'In-page tools',
27
27
  [ToolCategory.MEMORY]: 'Memory',
28
28
  };
29
- export const OFF_BY_DEFAULT_CATEGORIES = [ToolCategory.EXTENSIONS];
29
+ export const OFF_BY_DEFAULT_CATEGORIES = [
30
+ ToolCategory.EXTENSIONS,
31
+ ToolCategory.IN_PAGE,
32
+ ];
33
+ //# sourceMappingURL=categories.js.map
@@ -60,6 +60,7 @@ export const listConsoleMessages = definePageTool(cliArgs => {
60
60
  .optional()
61
61
  .describe('Set to true to return the preserved messages over the last 3 navigations.'),
62
62
  },
63
+ blockedByDialog: false,
63
64
  handler: async (request, response) => {
64
65
  response.setIncludeConsoleData(true, {
65
66
  pageSize: request.params.pageSize,
@@ -82,7 +83,9 @@ export const getConsoleMessage = definePageTool({
82
83
  .number()
83
84
  .describe('The msgid of a console message on the page from the listed console messages'),
84
85
  },
86
+ blockedByDialog: false,
85
87
  handler: async (request, response) => {
86
88
  response.attachConsoleMessage(request.params.msgid);
87
89
  },
88
90
  });
91
+ //# sourceMappingURL=console.js.map
@@ -48,8 +48,10 @@ export const emulate = definePageTool({
48
48
  .transform(viewportTransform)
49
49
  .describe(`Emulate device viewports '<width>x<height>x<devicePixelRatio>[,mobile][,touch][,landscape]'. 'touch' and 'mobile' to emulate mobile devices. 'landscape' to emulate landscape mode.`),
50
50
  },
51
+ blockedByDialog: true,
51
52
  handler: async (request, _response, context) => {
52
53
  const page = request.page;
53
54
  await context.emulate(request.params, page.pptrPage);
54
55
  },
55
56
  });
57
+ //# sourceMappingURL=emulation.js.map
@@ -18,6 +18,7 @@ export const installExtension = defineTool({
18
18
  .string()
19
19
  .describe('Absolute path to the unpacked extension folder.'),
20
20
  },
21
+ blockedByDialog: false,
21
22
  handler: async (request, response, context) => {
22
23
  const { path } = request.params;
23
24
  const id = await context.installExtension(path);
@@ -34,6 +35,7 @@ export const uninstallExtension = defineTool({
34
35
  schema: {
35
36
  id: zod.string().describe('ID of the extension to uninstall.'),
36
37
  },
38
+ blockedByDialog: false,
37
39
  handler: async (request, response, context) => {
38
40
  const { id } = request.params;
39
41
  await context.uninstallExtension(id);
@@ -48,6 +50,7 @@ export const listExtensions = defineTool({
48
50
  readOnlyHint: true,
49
51
  },
50
52
  schema: {},
53
+ blockedByDialog: false,
51
54
  handler: async (_request, response, _context) => {
52
55
  response.setListExtensions();
53
56
  },
@@ -62,6 +65,7 @@ export const reloadExtension = defineTool({
62
65
  schema: {
63
66
  id: zod.string().describe('ID of the extension to reload.'),
64
67
  },
68
+ blockedByDialog: false,
65
69
  handler: async (request, response, context) => {
66
70
  const { id } = request.params;
67
71
  const extension = await context.getExtension(id);
@@ -82,9 +86,11 @@ export const triggerExtensionAction = defineTool({
82
86
  schema: {
83
87
  id: zod.string().describe('ID of the extension to trigger the action for.'),
84
88
  },
89
+ blockedByDialog: false,
85
90
  handler: async (request, response, context) => {
86
91
  const { id } = request.params;
87
92
  await context.triggerExtensionAction(id);
88
93
  response.appendResponseLine(`Extension action triggered for ID ${id}`);
89
94
  },
90
95
  });
96
+ //# sourceMappingURL=extensions.js.map
@@ -18,9 +18,9 @@ export const listInPageTools = definePageTool({
18
18
  annotations: {
19
19
  category: ToolCategory.IN_PAGE,
20
20
  readOnlyHint: true,
21
- conditions: ['inPageTools'],
22
21
  },
23
22
  schema: {},
23
+ blockedByDialog: false,
24
24
  handler: async (_request, response, _context) => {
25
25
  response.setListInPageTools();
26
26
  },
@@ -31,7 +31,6 @@ export const executeInPageTool = definePageTool({
31
31
  annotations: {
32
32
  category: ToolCategory.IN_PAGE,
33
33
  readOnlyHint: false,
34
- conditions: ['inPageTools'],
35
34
  },
36
35
  schema: {
37
36
  toolName: zod.string().describe('The name of the tool to execute'),
@@ -40,6 +39,7 @@ export const executeInPageTool = definePageTool({
40
39
  .optional()
41
40
  .describe('The JSON-stringified parameters to pass to the tool'),
42
41
  },
42
+ blockedByDialog: false,
43
43
  handler: async (request, response) => {
44
44
  const toolName = request.params.toolName;
45
45
  let params = {};
@@ -72,3 +72,4 @@ export const executeInPageTool = definePageTool({
72
72
  await request.page.executeInPageTool(toolName, params, response);
73
73
  },
74
74
  });
75
+ //# sourceMappingURL=inPage.js.map
@@ -40,6 +40,7 @@ export const click = definePageTool({
40
40
  dblClick: dblClickSchema,
41
41
  includeSnapshot: includeSnapshotSchema,
42
42
  },
43
+ blockedByDialog: true,
43
44
  handler: async (request, response) => {
44
45
  const uid = request.params.uid;
45
46
  const handle = await request.page.getElementByUid(uid);
@@ -70,7 +71,7 @@ export const clickAt = definePageTool({
70
71
  annotations: {
71
72
  category: ToolCategory.INPUT,
72
73
  readOnlyHint: false,
73
- conditions: ['computerVision'],
74
+ conditions: ['experimentalVision'],
74
75
  },
75
76
  schema: {
76
77
  x: zod.number().describe('The x coordinate'),
@@ -78,6 +79,7 @@ export const clickAt = definePageTool({
78
79
  dblClick: dblClickSchema,
79
80
  includeSnapshot: includeSnapshotSchema,
80
81
  },
82
+ blockedByDialog: true,
81
83
  handler: async (request, response) => {
82
84
  const page = request.page;
83
85
  await page.waitForEventsAfterAction(async () => {
@@ -106,6 +108,7 @@ export const hover = definePageTool({
106
108
  .describe('The uid of an element on the page from the page content snapshot'),
107
109
  includeSnapshot: includeSnapshotSchema,
108
110
  },
111
+ blockedByDialog: true,
109
112
  handler: async (request, response) => {
110
113
  const uid = request.params.uid;
111
114
  const handle = await request.page.getElementByUid(uid);
@@ -200,6 +203,7 @@ export const fill = definePageTool({
200
203
  value: zod.string().describe('The value to fill in'),
201
204
  includeSnapshot: includeSnapshotSchema,
202
205
  },
206
+ blockedByDialog: true,
203
207
  handler: async (request, response, context) => {
204
208
  const page = request.page;
205
209
  await page.waitForEventsAfterAction(async () => {
@@ -222,6 +226,7 @@ export const typeText = definePageTool({
222
226
  text: zod.string().describe('The text to type'),
223
227
  submitKey: submitKeySchema,
224
228
  },
229
+ blockedByDialog: true,
225
230
  handler: async (request, response) => {
226
231
  const page = request.page;
227
232
  await page.waitForEventsAfterAction(async () => {
@@ -245,6 +250,7 @@ export const drag = definePageTool({
245
250
  to_uid: zod.string().describe('The uid of the element to drop into'),
246
251
  includeSnapshot: includeSnapshotSchema,
247
252
  },
253
+ blockedByDialog: true,
248
254
  handler: async (request, response) => {
249
255
  const fromHandle = await request.page.getElementByUid(request.params.from_uid);
250
256
  const toHandle = await request.page.getElementByUid(request.params.to_uid);
@@ -283,6 +289,7 @@ export const fillForm = definePageTool({
283
289
  .describe('Elements from snapshot to fill out.'),
284
290
  includeSnapshot: includeSnapshotSchema,
285
291
  },
292
+ blockedByDialog: true,
286
293
  handler: async (request, response, context) => {
287
294
  const page = request.page;
288
295
  for (const element of request.params.elements) {
@@ -310,8 +317,10 @@ export const uploadFile = definePageTool({
310
317
  filePath: zod.string().describe('The local path of the file to upload'),
311
318
  includeSnapshot: includeSnapshotSchema,
312
319
  },
313
- handler: async (request, response) => {
320
+ blockedByDialog: true,
321
+ handler: async (request, response, context) => {
314
322
  const { uid, filePath } = request.params;
323
+ context.validatePath(filePath);
315
324
  const handle = (await request.page.getElementByUid(uid));
316
325
  try {
317
326
  try {
@@ -355,6 +364,7 @@ export const pressKey = definePageTool({
355
364
  .describe('A key or a combination (e.g., "Enter", "Control+A", "Control++", "Control+Shift+R"). Modifiers: Control, Shift, Alt, Meta'),
356
365
  includeSnapshot: includeSnapshotSchema,
357
366
  },
367
+ blockedByDialog: true,
358
368
  handler: async (request, response) => {
359
369
  const page = request.page;
360
370
  const tokens = parseKey(request.params.key);
@@ -374,3 +384,4 @@ export const pressKey = definePageTool({
374
384
  }
375
385
  },
376
386
  });
387
+ //# sourceMappingURL=input.js.map
@@ -4,13 +4,13 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import path from 'node:path';
7
- import { snapshot, navigation, generateReport, zod, } from '../third_party/index.js';
7
+ import { snapshot, navigation, generateReport, zod, agenticBrowsingConfig, } from '../third_party/index.js';
8
8
  import { ToolCategory } from './categories.js';
9
9
  import { startTrace } from './performance.js';
10
10
  import { definePageTool } from './ToolDefinition.js';
11
11
  export const lighthouseAudit = definePageTool({
12
12
  name: 'lighthouse_audit',
13
- description: `Get Lighthouse score and reports for accessibility, SEO and best practices. This excludes performance. For performance audits, run ${startTrace.name}`,
13
+ description: `Get Lighthouse score and reports for accessibility, SEO, best practices, and agentic browsing. This excludes performance. For performance audits, run ${startTrace.name}`,
14
14
  annotations: {
15
15
  category: ToolCategory.DEBUGGING,
16
16
  readOnlyHint: false,
@@ -29,11 +29,18 @@ export const lighthouseAudit = definePageTool({
29
29
  .optional()
30
30
  .describe('Directory for reports. If omitted, uses temporary files.'),
31
31
  },
32
+ blockedByDialog: true,
32
33
  handler: async (request, response, context) => {
33
34
  const page = request.page;
34
- const categories = ['accessibility', 'seo', 'best-practices'];
35
+ const categories = [
36
+ 'accessibility',
37
+ 'seo',
38
+ 'best-practices',
39
+ 'agentic-browsing',
40
+ ];
35
41
  const formats = ['json', 'html'];
36
42
  const { mode = 'navigation', device = 'desktop', outputDirPath, } = request.params;
43
+ context.validatePath(outputDirPath);
37
44
  const flags = {
38
45
  onlyCategories: categories,
39
46
  output: formats,
@@ -60,17 +67,17 @@ export const lighthouseAudit = definePageTool({
60
67
  disabled: false,
61
68
  };
62
69
  }
70
+ const options = {
71
+ flags,
72
+ config: agenticBrowsingConfig,
73
+ };
63
74
  let result;
64
75
  try {
65
76
  if (mode === 'navigation') {
66
- result = await navigation(page.pptrPage, page.pptrPage.url(), {
67
- flags,
68
- });
77
+ result = await navigation(page.pptrPage, page.pptrPage.url(), options);
69
78
  }
70
79
  else {
71
- result = await snapshot(page.pptrPage, {
72
- flags,
73
- });
80
+ result = await snapshot(page.pptrPage, options);
74
81
  }
75
82
  if (!result) {
76
83
  throw new Error('Lighthouse audit failed.');
@@ -121,3 +128,4 @@ export const lighthouseAudit = definePageTool({
121
128
  response.attachLighthouseResult(output);
122
129
  },
123
130
  });
131
+ //# sourceMappingURL=lighthouse.js.map
@@ -19,8 +19,10 @@ export const takeMemorySnapshot = definePageTool({
19
19
  .string()
20
20
  .describe('A path to a .heapsnapshot file to save the heapsnapshot to.'),
21
21
  },
22
- handler: async (request, response, _context) => {
22
+ blockedByDialog: true,
23
+ handler: async (request, response, context) => {
23
24
  const page = request.page;
25
+ context.validatePath(request.params.filePath);
24
26
  await page.pptrPage.captureHeapSnapshot({
25
27
  path: ensureExtension(request.params.filePath, '.heapsnapshot'),
26
28
  });
@@ -38,7 +40,9 @@ export const exploreMemorySnapshot = defineTool({
38
40
  schema: {
39
41
  filePath: zod.string().describe('A path to a .heapsnapshot file to read.'),
40
42
  },
43
+ blockedByDialog: false,
41
44
  handler: async (request, response, context) => {
45
+ context.validatePath(request.params.filePath);
42
46
  const stats = await context.getHeapSnapshotStats(request.params.filePath);
43
47
  const staticData = await context.getHeapSnapshotStaticData(request.params.filePath);
44
48
  response.setHeapSnapshotStats(stats, staticData);
@@ -63,7 +67,9 @@ export const getMemorySnapshotDetails = defineTool({
63
67
  .optional()
64
68
  .describe('The page size for pagination of aggregates.'),
65
69
  },
70
+ blockedByDialog: false,
66
71
  handler: async (request, response, context) => {
72
+ context.validatePath(request.params.filePath);
67
73
  const aggregates = await context.getHeapSnapshotAggregates(request.params.filePath);
68
74
  response.setHeapSnapshotAggregates(aggregates, {
69
75
  pageIdx: request.params.pageIdx,
@@ -71,3 +77,30 @@ export const getMemorySnapshotDetails = defineTool({
71
77
  });
72
78
  },
73
79
  });
80
+ export const getNodesByClass = defineTool({
81
+ name: 'get_nodes_by_class',
82
+ description: 'Loads a memory heapsnapshot and returns instances of a specific class with their stable IDs.',
83
+ annotations: {
84
+ category: ToolCategory.MEMORY,
85
+ readOnlyHint: true,
86
+ conditions: ['experimentalMemory'],
87
+ },
88
+ schema: {
89
+ filePath: zod.string().describe('A path to a .heapsnapshot file to read.'),
90
+ uid: zod
91
+ .number()
92
+ .describe('The unique UID for the class, obtained from aggregates listing.'),
93
+ pageIdx: zod.number().optional().describe('The page index for pagination.'),
94
+ pageSize: zod.number().optional().describe('The page size for pagination.'),
95
+ },
96
+ blockedByDialog: false,
97
+ handler: async (request, response, context) => {
98
+ context.validatePath(request.params.filePath);
99
+ const nodes = await context.getHeapSnapshotNodesByUid(request.params.filePath, request.params.uid);
100
+ response.setHeapSnapshotNodes(nodes, {
101
+ pageIdx: request.params.pageIdx,
102
+ pageSize: request.params.pageSize,
103
+ });
104
+ },
105
+ });
106
+ //# sourceMappingURL=memory.js.map
@@ -57,6 +57,7 @@ export const listNetworkRequests = definePageTool({
57
57
  .optional()
58
58
  .describe('Set to true to return the preserved requests over the last 3 navigations.'),
59
59
  },
60
+ blockedByDialog: false,
60
61
  handler: async (request, response, context) => {
61
62
  const data = await request.page.getDevToolsData();
62
63
  response.attachDevToolsData(data);
@@ -93,7 +94,10 @@ export const getNetworkRequest = definePageTool({
93
94
  .optional()
94
95
  .describe('The absolute or relative path to a .network-response file to save the response body to. If omitted, the body is returned inline.'),
95
96
  },
97
+ blockedByDialog: true,
96
98
  handler: async (request, response, context) => {
99
+ context.validatePath(request.params.requestFilePath);
100
+ context.validatePath(request.params.responseFilePath);
97
101
  if (request.params.reqid) {
98
102
  response.attachNetworkRequest(request.params.reqid, {
99
103
  requestFilePath: request.params.requestFilePath,
@@ -118,3 +122,4 @@ export const getNetworkRequest = definePageTool({
118
122
  }
119
123
  },
120
124
  });
125
+ //# sourceMappingURL=network.js.map
@@ -61,6 +61,7 @@ export const listPages = defineTool(args => {
61
61
  readOnlyHint: true,
62
62
  },
63
63
  schema: {},
64
+ blockedByDialog: false,
64
65
  handler: async (_request, response) => {
65
66
  response.setIncludePages(true);
66
67
  response.setListInPageTools();
@@ -84,6 +85,7 @@ export const selectPage = defineTool({
84
85
  .optional()
85
86
  .describe('Whether to focus the page and bring it to the top.'),
86
87
  },
88
+ blockedByDialog: false,
87
89
  handler: async (request, response, context) => {
88
90
  const page = context.getPageById(request.params.pageId);
89
91
  context.selectPage(page);
@@ -107,6 +109,7 @@ export const closePage = defineTool({
107
109
  .number()
108
110
  .describe('The ID of the page to close. Call list_pages to list pages.'),
109
111
  },
112
+ blockedByDialog: false,
110
113
  handler: async (request, response, context) => {
111
114
  try {
112
115
  await context.closePage(request.params.pageId);
@@ -153,6 +156,7 @@ export const newPage = defineTool(args => {
153
156
  : {}),
154
157
  ...timeoutSchema,
155
158
  },
159
+ blockedByDialog: false,
156
160
  handler: async (request, response, context) => {
157
161
  const page = await context.newPage(request.params.background, request.params.isolatedContext);
158
162
  await navigateWithInterception(page, () => page.pptrPage.goto(request.params.url, {
@@ -199,6 +203,7 @@ export const navigatePage = definePageTool(args => {
199
203
  : {}),
200
204
  ...timeoutSchema,
201
205
  },
206
+ blockedByDialog: false,
202
207
  handler: async (request, response) => {
203
208
  const page = request.page;
204
209
  const options = {
@@ -306,6 +311,7 @@ export const resizePage = definePageTool({
306
311
  width: zod.number().describe('Page width'),
307
312
  height: zod.number().describe('Page height'),
308
313
  },
314
+ blockedByDialog: false,
309
315
  handler: async (request, response, _context) => {
310
316
  const page = request.page;
311
317
  try {
@@ -347,6 +353,7 @@ export const handleDialog = definePageTool({
347
353
  .optional()
348
354
  .describe('Optional prompt text to enter into the dialog.'),
349
355
  },
356
+ blockedByDialog: false,
350
357
  handler: async (request, response, _context) => {
351
358
  const page = request.page;
352
359
  const dialog = page.getDialog();
@@ -394,9 +401,11 @@ export const getTabId = definePageTool({
394
401
  .number()
395
402
  .describe(`The ID of the page to get the tab ID for. Call ${listPages().name} to get available pages.`),
396
403
  },
404
+ blockedByDialog: false,
397
405
  handler: async (request, response, context) => {
398
406
  const page = context.getPageById(request.params.pageId);
399
407
  const tabId = page.pptrPage._tabId;
400
408
  response.setTabId(tabId);
401
409
  },
402
410
  });
411
+ //# sourceMappingURL=pages.js.map
@@ -31,7 +31,9 @@ export const startTrace = definePageTool({
31
31
  .describe('Determines if the trace recording should be automatically stopped.'),
32
32
  filePath: filePathSchema,
33
33
  },
34
+ blockedByDialog: true,
34
35
  handler: async (request, response, context) => {
36
+ context.validatePath(request.params.filePath);
35
37
  if (context.isRunningPerformanceTrace()) {
36
38
  response.appendResponseLine('Error: a performance trace is already running. Use performance_stop_trace to stop it. Only one trace can be running at any given time.');
37
39
  return;
@@ -93,7 +95,9 @@ export const stopTrace = definePageTool({
93
95
  schema: {
94
96
  filePath: filePathSchema,
95
97
  },
98
+ blockedByDialog: true,
96
99
  handler: async (request, response, context) => {
100
+ context.validatePath(request.params.filePath);
97
101
  if (!context.isRunningPerformanceTrace()) {
98
102
  return;
99
103
  }
@@ -116,6 +120,7 @@ export const analyzeInsight = definePageTool({
116
120
  .string()
117
121
  .describe('The name of the Insight you want more information on. For example: "DocumentLatency" or "LCPBreakdown"'),
118
122
  },
123
+ blockedByDialog: false,
119
124
  handler: async (request, response, context) => {
120
125
  const lastRecording = context.recordedTraces().at(-1);
121
126
  if (!lastRecording) {
@@ -188,3 +193,4 @@ async function populateCruxData(result) {
188
193
  }));
189
194
  result.parsedTrace.metadata.cruxFieldData = cruxData;
190
195
  }
196
+ //# sourceMappingURL=performance.js.map
@@ -21,7 +21,7 @@ export const startScreencast = definePageTool(args => ({
21
21
  annotations: {
22
22
  category: ToolCategory.DEBUGGING,
23
23
  readOnlyHint: false,
24
- conditions: ['screencast'],
24
+ conditions: ['experimentalScreencast'],
25
25
  },
26
26
  schema: {
27
27
  filePath: zod
@@ -29,7 +29,9 @@ export const startScreencast = definePageTool(args => ({
29
29
  .optional()
30
30
  .describe(`Output file path (${supportedExtensions.join(',')} are supported). Uses mkdtemp to generate a unique path if not provided.`),
31
31
  },
32
+ blockedByDialog: false,
32
33
  handler: async (request, response, context) => {
34
+ context.validatePath(request.params.filePath);
33
35
  if (context.getScreenRecorder() !== null) {
34
36
  response.appendResponseLine('Error: a screencast recording is already in progress. Use screencast_stop to stop it before starting a new one.');
35
37
  return;
@@ -72,9 +74,10 @@ export const stopScreencast = definePageTool({
72
74
  annotations: {
73
75
  category: ToolCategory.DEBUGGING,
74
76
  readOnlyHint: false,
75
- conditions: ['screencast'],
77
+ conditions: ['experimentalScreencast'],
76
78
  },
77
79
  schema: {},
80
+ blockedByDialog: false,
78
81
  handler: async (_request, response, context) => {
79
82
  const data = context.getScreenRecorder();
80
83
  if (!data) {
@@ -89,3 +92,4 @@ export const stopScreencast = definePageTool({
89
92
  }
90
93
  },
91
94
  });
95
+ //# sourceMappingURL=screencast.js.map
@@ -38,7 +38,9 @@ export const screenshot = definePageTool({
38
38
  .optional()
39
39
  .describe('The absolute path, or a path relative to the current working directory, to save the screenshot to instead of attaching it to the response.'),
40
40
  },
41
+ blockedByDialog: true,
41
42
  handler: async (request, response, context) => {
43
+ context.validatePath(request.params.filePath);
42
44
  if (request.params.uid && request.params.fullPage) {
43
45
  throw new Error('Providing both "uid" and "fullPage" is not allowed.');
44
46
  }
@@ -82,3 +84,4 @@ export const screenshot = definePageTool({
82
84
  }
83
85
  },
84
86
  });
87
+ //# sourceMappingURL=screenshot.js.map
@@ -46,6 +46,7 @@ Example with arguments: \`(el) => {
46
46
  }
47
47
  : {}),
48
48
  },
49
+ blockedByDialog: true,
49
50
  handler: async (request, response, context) => {
50
51
  const { serviceWorkerId, args: uidArgs, function: fnString, pageId, dialogAction, } = request.params;
51
52
  if (cliArgs?.categoryExtensions && serviceWorkerId) {
@@ -125,3 +126,4 @@ const getWebWorker = async (context, serviceWorkerId) => {
125
126
  throw new Error('Service worker not found.');
126
127
  }
127
128
  };
129
+ //# sourceMappingURL=script.js.map
@@ -15,6 +15,7 @@ export const screenshot = definePageTool({
15
15
  readOnlyHint: false,
16
16
  },
17
17
  schema: {},
18
+ blockedByDialog: true,
18
19
  handler: async (request, response, context) => {
19
20
  const page = request.page;
20
21
  const screenshot = await page.pptrPage.screenshot({
@@ -35,6 +36,7 @@ export const navigate = definePageTool({
35
36
  schema: {
36
37
  url: zod.string().describe('URL to navigate to'),
37
38
  },
39
+ blockedByDialog: false,
38
40
  handler: async (request, response) => {
39
41
  const page = request.page;
40
42
  const options = {
@@ -68,6 +70,7 @@ export const evaluate = definePageTool({
68
70
  schema: {
69
71
  script: zod.string().describe(`JS script to run on the page`),
70
72
  },
73
+ blockedByDialog: true,
71
74
  handler: async (request, response) => {
72
75
  const page = request.page;
73
76
  try {
@@ -79,3 +82,4 @@ export const evaluate = definePageTool({
79
82
  }
80
83
  },
81
84
  });
85
+ //# sourceMappingURL=tools.js.map
@@ -26,7 +26,9 @@ in the DevTools Elements panel (if any).`,
26
26
  .optional()
27
27
  .describe('The absolute path, or a path relative to the current working directory, to save the snapshot to instead of attaching it to the response.'),
28
28
  },
29
- handler: async (request, response) => {
29
+ blockedByDialog: true,
30
+ handler: async (request, response, context) => {
31
+ context.validatePath(request.params.filePath);
30
32
  response.includeSnapshot({
31
33
  verbose: request.params.verbose ?? false,
32
34
  filePath: request.params.filePath,
@@ -47,6 +49,7 @@ export const waitFor = definePageTool({
47
49
  .describe('Non-empty list of texts. Resolves when any value appears on the page.'),
48
50
  ...timeoutSchema,
49
51
  },
52
+ blockedByDialog: true,
50
53
  handler: async (request, response, context) => {
51
54
  const page = request.page;
52
55
  await context.waitForTextOnPage(request.params.text, request.params.timeout, page.pptrPage);
@@ -54,3 +57,4 @@ export const waitFor = definePageTool({
54
57
  response.includeSnapshot();
55
58
  },
56
59
  });
60
+ //# sourceMappingURL=snapshot.js.map
@@ -53,3 +53,4 @@ export const createTools = (args) => {
53
53
  });
54
54
  return tools;
55
55
  };
56
+ //# sourceMappingURL=tools.js.map
@@ -15,6 +15,7 @@ export const listWebMcpTools = definePageTool({
15
15
  conditions: ['experimentalWebmcp'],
16
16
  },
17
17
  schema: {},
18
+ blockedByDialog: false,
18
19
  handler: async (_request, response, _context) => {
19
20
  response.setListWebMcpTools();
20
21
  },
@@ -34,6 +35,7 @@ export const executeWebMcpTool = definePageTool({
34
35
  .optional()
35
36
  .describe('The JSON-stringified parameters to pass to the WebMCP tool'),
36
37
  },
38
+ blockedByDialog: false,
37
39
  handler: async (request, response) => {
38
40
  const toolName = request.params.toolName;
39
41
  let input = {};
@@ -61,3 +63,4 @@ export const executeWebMcpTool = definePageTool({
61
63
  response.appendResponseLine(JSON.stringify({ status, output, errorText }, null, 2));
62
64
  },
63
65
  });
66
+ //# sourceMappingURL=webmcp.js.map
@@ -82,3 +82,4 @@ export function getInsightOutput(result, insightSetId, insightName) {
82
82
  const formatter = new DevTools.PerformanceInsightFormatter(DevTools.AgentFocus.fromParsedTrace(result.parsedTrace), matchingInsight);
83
83
  return { output: formatter.formatInsight() };
84
84
  }
85
+ //# sourceMappingURL=parse.js.map
@@ -4,3 +4,4 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  export {};
7
+ //# sourceMappingURL=types.js.map
@@ -71,3 +71,4 @@ export async function checkForUpdates(message) {
71
71
  // Fail silently in case of any errors.
72
72
  }
73
73
  }
74
+ //# sourceMappingURL=check-for-updates.js.map
@@ -6,18 +6,13 @@
6
6
  import fs from 'node:fs/promises';
7
7
  import os from 'node:os';
8
8
  import path from 'node:path';
9
- export async function saveTemporaryFile(data, filename) {
10
- try {
11
- const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'chrome-devtools-mcp-'));
12
- const filepath = path.join(dir, filename);
13
- await fs.writeFile(filepath, data);
14
- return { filepath };
15
- }
16
- catch (err) {
17
- throw new Error('Could not save a file', { cause: err });
18
- }
9
+ export async function getTempFilePath(filename) {
10
+ const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'chrome-devtools-mcp-'));
11
+ const filepath = path.join(dir, filename);
12
+ return filepath;
19
13
  }
20
14
  export function ensureExtension(filepath, extension) {
21
15
  const ext = path.extname(filepath);
22
16
  return filepath.slice(0, filepath.length - ext.length) + extension;
23
17
  }
18
+ //# sourceMappingURL=files.js.map
@@ -13,3 +13,4 @@ export function createIdGenerator() {
13
13
  };
14
14
  }
15
15
  export const stableIdSymbol = Symbol('stableIdSymbol');
16
+ //# sourceMappingURL=id.js.map
@@ -294,3 +294,4 @@ export function parseKey(keyInput) {
294
294
  }
295
295
  return [result.at(-1), ...result.slice(0, -1)];
296
296
  }
297
+ //# sourceMappingURL=keyboard.js.map