chrome-devtools-mcp 1.1.1 → 1.2.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 (105) hide show
  1. package/README.md +12 -3
  2. package/build/src/DevtoolsUtils.js +57 -0
  3. package/build/src/HeapSnapshotManager.js +5 -0
  4. package/build/src/McpContext.js +28 -8
  5. package/build/src/McpPage.js +9 -9
  6. package/build/src/McpResponse.js +101 -53
  7. package/build/src/PageCollector.js +7 -7
  8. package/build/src/ServiceWorkerCollector.js +171 -0
  9. package/build/src/TextSnapshot.js +1 -1
  10. package/build/src/ToolHandler.js +10 -4
  11. package/build/src/WaitForHelper.js +2 -2
  12. package/build/src/bin/chrome-devtools-cli-options.js +22 -4
  13. package/build/src/bin/chrome-devtools-mcp-cli-options.js +19 -4
  14. package/build/src/bin/chrome-devtools-mcp-main.js +5 -5
  15. package/build/src/browser.js +8 -4
  16. package/build/src/daemon/client.js +7 -7
  17. package/build/src/daemon/daemon.js +12 -12
  18. package/build/src/daemon/utils.js +2 -2
  19. package/build/src/formatters/IssueFormatter.js +4 -4
  20. package/build/src/index.js +13 -1
  21. package/build/src/telemetry/ClearcutLogger.js +1 -1
  22. package/build/src/telemetry/WatchdogClient.js +4 -4
  23. package/build/src/telemetry/persistence.js +2 -2
  24. package/build/src/telemetry/watchdog/ClearcutSender.js +10 -10
  25. package/build/src/telemetry/watchdog/main.js +5 -5
  26. package/build/src/third_party/THIRD_PARTY_NOTICES +30 -0
  27. package/build/src/third_party/bundled-packages.json +2 -1
  28. package/build/src/third_party/devtools-formatter-worker.js +1 -0
  29. package/build/src/third_party/devtools-heap-snapshot-worker.js +107 -0
  30. package/build/src/third_party/index.js +5906 -4913
  31. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsEmptyList.md +1 -0
  32. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsHttpNotFound.md +1 -0
  33. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsInvalidContentType.md +1 -0
  34. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsInvalidResponse.md +1 -0
  35. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsNoResponse.md +1 -0
  36. package/build/src/third_party/issue-descriptions/emailVerificationRequestDnsFetchFailed.md +1 -0
  37. package/build/src/third_party/issue-descriptions/emailVerificationRequestDnsInvalidRecord.md +1 -0
  38. package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownHttpNotFound.md +1 -0
  39. package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownInvalidContentType.md +1 -0
  40. package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownInvalidResponse.md +1 -0
  41. package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownNoResponse.md +1 -0
  42. package/build/src/third_party/issue-descriptions/emailVerificationRequestInvalidEmail.md +1 -0
  43. package/build/src/third_party/issue-descriptions/emailVerificationRequestJwksHttpNotFound.md +1 -0
  44. package/build/src/third_party/issue-descriptions/emailVerificationRequestJwksInvalidResponse.md +1 -0
  45. package/build/src/third_party/issue-descriptions/emailVerificationRequestKeyBindingSigningFailed.md +1 -0
  46. package/build/src/third_party/issue-descriptions/emailVerificationRequestRpOriginIsOpaque.md +1 -0
  47. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenHttpNotFound.md +1 -0
  48. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidContentType.md +1 -0
  49. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidResponse.md +1 -0
  50. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidSdJwt.md +1 -0
  51. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenMalformedSdJwt.md +1 -0
  52. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenNoResponse.md +1 -0
  53. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidAudience.md +1 -0
  54. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidIssuedAt.md +1 -0
  55. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidNonce.md +1 -0
  56. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidSdHash.md +1 -0
  57. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidTyp.md +1 -0
  58. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingAud.md +1 -0
  59. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingCnf.md +1 -0
  60. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingIat.md +1 -0
  61. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingNonce.md +1 -0
  62. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingSdHash.md +1 -0
  63. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbSignatureFailed.md +1 -0
  64. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidEmail.md +1 -0
  65. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidEmailVerified.md +1 -0
  66. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidHolderKey.md +1 -0
  67. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidIssuedAt.md +1 -0
  68. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidIssuer.md +1 -0
  69. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtJwksMissingKeys.md +1 -0
  70. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingCnf.md +1 -0
  71. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingEmail.md +1 -0
  72. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingIat.md +1 -0
  73. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingIss.md +1 -0
  74. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtSignatureFailed.md +1 -0
  75. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtUnsupportedHeaderAlg.md +1 -0
  76. package/build/src/third_party/issue-descriptions/emailVerificationRequestUserLoggedOut.md +1 -0
  77. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownAccountsEndpointCrossOrigin.md +1 -0
  78. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownHttpNotFound.md +1 -0
  79. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownInvalidContentType.md +1 -0
  80. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownInvalidResponse.md +1 -0
  81. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownIssuanceEndpointCrossOrigin.md +1 -0
  82. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownListEmpty.md +1 -0
  83. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownMissingAccountsEndpoint.md +1 -0
  84. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownMissingIssuanceEndpoint.md +1 -0
  85. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownNoResponse.md +1 -0
  86. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownUnsupportedSigningAlgorithm.md +1 -0
  87. package/build/src/tools/console.js +7 -0
  88. package/build/src/tools/emulation.js +1 -0
  89. package/build/src/tools/extensions.js +5 -2
  90. package/build/src/tools/input.js +11 -3
  91. package/build/src/tools/lighthouse.js +11 -6
  92. package/build/src/tools/memory.js +33 -10
  93. package/build/src/tools/network.js +2 -2
  94. package/build/src/tools/pages.js +13 -5
  95. package/build/src/tools/performance.js +8 -7
  96. package/build/src/tools/screencast.js +2 -1
  97. package/build/src/tools/screenshot.js +1 -1
  98. package/build/src/tools/script.js +1 -1
  99. package/build/src/tools/slim/tools.js +3 -0
  100. package/build/src/tools/snapshot.js +3 -2
  101. package/build/src/tools/thirdPartyDeveloper.js +12 -2
  102. package/build/src/tools/webmcp.js +2 -0
  103. package/build/src/trace-processing/parse.js +5 -5
  104. package/build/src/version.js +1 -1
  105. package/package.json +4 -3
@@ -22,7 +22,7 @@ async function navigateWithInterception(page, action, allowListString, timeout)
22
22
  void interceptedRequest.continue();
23
23
  }
24
24
  else {
25
- logger(`Blocking request to: ${requestUrl}`);
25
+ logger?.(`Blocking request to: ${requestUrl}`);
26
26
  void interceptedRequest.abort('blockedbyclient');
27
27
  }
28
28
  };
@@ -30,7 +30,7 @@ async function navigateWithInterception(page, action, allowListString, timeout)
30
30
  if (allowList) {
31
31
  page.pptrPage.off('request', requestHandler);
32
32
  await page.pptrPage.setRequestInterception(false).catch(error => {
33
- logger(`Failed to disable request interception`, error);
33
+ logger?.(`Failed to disable request interception`, error);
34
34
  });
35
35
  }
36
36
  };
@@ -62,6 +62,7 @@ export const listPages = defineTool(args => {
62
62
  },
63
63
  schema: {},
64
64
  blockedByDialog: false,
65
+ verifyFilesSchema: [],
65
66
  handler: async (_request, response) => {
66
67
  response.setIncludePages(true);
67
68
  response.setListThirdPartyDeveloperTools();
@@ -86,6 +87,7 @@ export const selectPage = defineTool({
86
87
  .describe('Whether to focus the page and bring it to the top.'),
87
88
  },
88
89
  blockedByDialog: false,
90
+ verifyFilesSchema: [],
89
91
  handler: async (request, response, context) => {
90
92
  const page = context.getPageById(request.params.pageId);
91
93
  context.selectPage(page);
@@ -110,6 +112,7 @@ export const closePage = defineTool({
110
112
  .describe('The ID of the page to close. Call list_pages to list pages.'),
111
113
  },
112
114
  blockedByDialog: false,
115
+ verifyFilesSchema: [],
113
116
  handler: async (request, response, context) => {
114
117
  try {
115
118
  await context.closePage(request.params.pageId);
@@ -157,6 +160,7 @@ export const newPage = defineTool(args => {
157
160
  ...timeoutSchema,
158
161
  },
159
162
  blockedByDialog: false,
163
+ verifyFilesSchema: [],
160
164
  handler: async (request, response, context) => {
161
165
  const page = await context.newPage(request.params.background, request.params.isolatedContext);
162
166
  await navigateWithInterception(page, () => page.pptrPage.goto(request.params.url, {
@@ -204,6 +208,7 @@ export const navigatePage = definePageTool(args => {
204
208
  ...timeoutSchema,
205
209
  },
206
210
  blockedByDialog: false,
211
+ verifyFilesSchema: [],
207
212
  handler: async (request, response) => {
208
213
  const page = request.page;
209
214
  const options = {
@@ -290,7 +295,7 @@ export const navigatePage = definePageTool(args => {
290
295
  await page.pptrPage
291
296
  .removeScriptToEvaluateOnNewDocument(initScriptId)
292
297
  .catch(error => {
293
- logger(`Failed to remove init script`, error);
298
+ logger?.(`Failed to remove init script`, error);
294
299
  });
295
300
  }
296
301
  }
@@ -312,6 +317,7 @@ export const resizePage = definePageTool({
312
317
  height: zod.number().describe('Page height'),
313
318
  },
314
319
  blockedByDialog: false,
320
+ verifyFilesSchema: [],
315
321
  handler: async (request, response, _context) => {
316
322
  const page = request.page;
317
323
  try {
@@ -354,6 +360,7 @@ export const handleDialog = definePageTool({
354
360
  .describe('Optional prompt text to enter into the dialog.'),
355
361
  },
356
362
  blockedByDialog: false,
363
+ verifyFilesSchema: [],
357
364
  handler: async (request, response, _context) => {
358
365
  const page = request.page;
359
366
  const dialog = page.getDialog();
@@ -367,7 +374,7 @@ export const handleDialog = definePageTool({
367
374
  }
368
375
  catch (err) {
369
376
  // Likely already handled by the user outside of MCP.
370
- logger(err);
377
+ logger?.(err);
371
378
  }
372
379
  response.appendResponseLine('Successfully accepted the dialog');
373
380
  break;
@@ -378,7 +385,7 @@ export const handleDialog = definePageTool({
378
385
  }
379
386
  catch (err) {
380
387
  // Likely already handled.
381
- logger(err);
388
+ logger?.(err);
382
389
  }
383
390
  response.appendResponseLine('Successfully dismissed the dialog');
384
391
  break;
@@ -402,6 +409,7 @@ export const getTabId = definePageTool({
402
409
  .describe(`The ID of the page to get the tab ID for. Call ${listPages().name} to get available pages.`),
403
410
  },
404
411
  blockedByDialog: false,
412
+ verifyFilesSchema: [],
405
413
  handler: async (request, response, context) => {
406
414
  const page = context.getPageById(request.params.pageId);
407
415
  const tabId = page.pptrPage._tabId;
@@ -32,8 +32,8 @@ export const startTrace = definePageTool({
32
32
  filePath: filePathSchema,
33
33
  },
34
34
  blockedByDialog: true,
35
+ verifyFilesSchema: ['filePath'],
35
36
  handler: async (request, response, context) => {
36
- await context.validatePath(request.params.filePath);
37
37
  if (context.isRunningPerformanceTrace()) {
38
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.');
39
39
  return;
@@ -96,8 +96,8 @@ export const stopTrace = definePageTool({
96
96
  filePath: filePathSchema,
97
97
  },
98
98
  blockedByDialog: true,
99
+ verifyFilesSchema: ['filePath'],
99
100
  handler: async (request, response, context) => {
100
- await context.validatePath(request.params.filePath);
101
101
  if (!context.isRunningPerformanceTrace()) {
102
102
  return;
103
103
  }
@@ -121,6 +121,7 @@ export const analyzeInsight = definePageTool({
121
121
  .describe('The name of the Insight you want more information on. For example: "DocumentLatency" or "LCPBreakdown"'),
122
122
  },
123
123
  blockedByDialog: false,
124
+ verifyFilesSchema: [],
124
125
  handler: async (request, response, context) => {
125
126
  const lastRecording = context.recordedTraces().at(-1);
126
127
  if (!lastRecording) {
@@ -172,8 +173,8 @@ async function stopTracingAndAppendOutput(page, response, context, filePath) {
172
173
  }
173
174
  /** We tell CrUXManager to fetch data so it's available when DevTools.PerformanceTraceFormatter is invoked */
174
175
  async function populateCruxData(result) {
175
- logger('populateCruxData called');
176
- const cruxManager = DevTools.CrUXManager.instance();
176
+ logger?.('populateCruxData called');
177
+ const cruxManager = DevTools.CrUXManager.CrUXManager.instance();
177
178
  // go/jtfbx. Yes, we're aware this API key is public. ;)
178
179
  cruxManager.setEndpointForTesting('https://chromeuxreport.googleapis.com/v1/records:queryRecord?key=AIzaSyBn5gimNjhiEyA_euicSKko6IlD3HdgUfk');
179
180
  const cruxSetting = DevTools.Common.Settings.Settings.instance().createSetting('field-data', {
@@ -185,13 +186,13 @@ async function populateCruxData(result) {
185
186
  urls.push(result.parsedTrace.data.Meta.mainFrameURL);
186
187
  const urlSet = new Set(urls);
187
188
  if (urlSet.size === 0) {
188
- logger('No URLs found for CrUX data');
189
+ logger?.('No URLs found for CrUX data');
189
190
  return;
190
191
  }
191
- logger(`Fetching CrUX data for ${urlSet.size} URLs: ${Array.from(urlSet).join(', ')}`);
192
+ logger?.(`Fetching CrUX data for ${urlSet.size} URLs: ${Array.from(urlSet).join(', ')}`);
192
193
  const cruxData = await Promise.all(Array.from(urlSet).map(async (url) => {
193
194
  const data = await cruxManager.getFieldDataForPage(url);
194
- logger(`CrUX data for ${url}: ${data ? 'found' : 'not found'}`);
195
+ logger?.(`CrUX data for ${url}: ${data ? 'found' : 'not found'}`);
195
196
  return data;
196
197
  }));
197
198
  result.parsedTrace.metadata.cruxFieldData = cruxData;
@@ -30,8 +30,8 @@ export const startScreencast = definePageTool(args => ({
30
30
  .describe(`Output file path (${supportedExtensions.join(',')} are supported). Uses mkdtemp to generate a unique path if not provided.`),
31
31
  },
32
32
  blockedByDialog: false,
33
+ verifyFilesSchema: ['filePath'],
33
34
  handler: async (request, response, context) => {
34
- await context.validatePath(request.params.filePath);
35
35
  if (context.getScreenRecorder() !== null) {
36
36
  response.appendResponseLine('Error: a screencast recording is already in progress. Use screencast_stop to stop it before starting a new one.');
37
37
  return;
@@ -78,6 +78,7 @@ export const stopScreencast = definePageTool({
78
78
  },
79
79
  schema: {},
80
80
  blockedByDialog: false,
81
+ verifyFilesSchema: [],
81
82
  handler: async (_request, response, context) => {
82
83
  const data = context.getScreenRecorder();
83
84
  if (!data) {
@@ -39,8 +39,8 @@ export const screenshot = definePageTool({
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
41
  blockedByDialog: true,
42
+ verifyFilesSchema: ['filePath'],
42
43
  handler: async (request, response, context) => {
43
- await context.validatePath(request.params.filePath);
44
44
  if (request.params.uid && request.params.fullPage) {
45
45
  throw new Error('Providing both "uid" and "fullPage" is not allowed.');
46
46
  }
@@ -51,9 +51,9 @@ Example with arguments: \`(el) => {
51
51
  : {}),
52
52
  },
53
53
  blockedByDialog: true,
54
+ verifyFilesSchema: ['filePath'],
54
55
  handler: async (request, response, context) => {
55
56
  const { serviceWorkerId, args: uidArgs, function: fnString, pageId, dialogAction, filePath, } = request.params;
56
- await context.validatePath(filePath);
57
57
  if (cliArgs?.categoryExtensions && serviceWorkerId) {
58
58
  if (uidArgs && uidArgs.length > 0) {
59
59
  throw new Error('args (element uids) cannot be used when evaluating in a service worker.');
@@ -16,6 +16,7 @@ export const screenshot = definePageTool({
16
16
  },
17
17
  schema: {},
18
18
  blockedByDialog: true,
19
+ verifyFilesSchema: [],
19
20
  handler: async (request, response, context) => {
20
21
  const page = request.page;
21
22
  const screenshot = await page.pptrPage.screenshot({
@@ -37,6 +38,7 @@ export const navigate = definePageTool({
37
38
  url: zod.string().describe('URL to navigate to'),
38
39
  },
39
40
  blockedByDialog: false,
41
+ verifyFilesSchema: [],
40
42
  handler: async (request, response) => {
41
43
  const page = request.page;
42
44
  const options = {
@@ -71,6 +73,7 @@ export const evaluate = definePageTool({
71
73
  script: zod.string().describe(`JS script to run on the page`),
72
74
  },
73
75
  blockedByDialog: true,
76
+ verifyFilesSchema: [],
74
77
  handler: async (request, response) => {
75
78
  const page = request.page;
76
79
  try {
@@ -27,8 +27,8 @@ in the DevTools Elements panel (if any).`,
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
29
  blockedByDialog: true,
30
- handler: async (request, response, context) => {
31
- await context.validatePath(request.params.filePath);
30
+ verifyFilesSchema: ['filePath'],
31
+ handler: async (request, response) => {
32
32
  response.includeSnapshot({
33
33
  verbose: request.params.verbose ?? false,
34
34
  filePath: request.params.filePath,
@@ -50,6 +50,7 @@ export const waitFor = definePageTool({
50
50
  ...timeoutSchema,
51
51
  },
52
52
  blockedByDialog: true,
53
+ verifyFilesSchema: [],
53
54
  handler: async (request, response, context) => {
54
55
  const page = request.page;
55
56
  await context.waitForTextOnPage(request.params.text, request.params.timeout, page.pptrPage);
@@ -21,6 +21,7 @@ export const listThirdPartyDeveloperTools = definePageTool({
21
21
  },
22
22
  schema: {},
23
23
  blockedByDialog: false,
24
+ verifyFilesSchema: [],
24
25
  handler: async (_request, response, _context) => {
25
26
  response.setListThirdPartyDeveloperTools();
26
27
  },
@@ -40,6 +41,7 @@ export const executeThirdPartyDeveloperTool = definePageTool({
40
41
  .describe('The JSON-stringified parameters to pass to the tool'),
41
42
  },
42
43
  blockedByDialog: false,
44
+ verifyFilesSchema: [],
43
45
  handler: async (request, response) => {
44
46
  const toolName = request.params.toolName;
45
47
  let params = {};
@@ -58,8 +60,16 @@ export const executeThirdPartyDeveloperTool = definePageTool({
58
60
  throw new Error(`Failed to parse params as JSON: ${errorMessage}`);
59
61
  }
60
62
  }
61
- const toolGroup = request.page.getThirdPartyDeveloperTools();
62
- const tool = toolGroup?.tools.find(t => t.name === toolName);
63
+ const toolGroups = request.page.getThirdPartyDeveloperTools();
64
+ let tool;
65
+ if (toolGroups) {
66
+ for (const group of toolGroups) {
67
+ tool = group.tools?.find(t => t.name === toolName);
68
+ if (tool) {
69
+ break;
70
+ }
71
+ }
72
+ }
63
73
  if (!tool) {
64
74
  throw new Error(`Tool ${toolName} not found`);
65
75
  }
@@ -15,6 +15,7 @@ export const listWebMcpTools = definePageTool({
15
15
  },
16
16
  schema: {},
17
17
  blockedByDialog: false,
18
+ verifyFilesSchema: [],
18
19
  handler: async (_request, response, _context) => {
19
20
  response.setListWebMcpTools();
20
21
  },
@@ -34,6 +35,7 @@ export const executeWebMcpTool = definePageTool({
34
35
  .describe('The JSON-stringified parameters to pass to the WebMCP tool'),
35
36
  },
36
37
  blockedByDialog: false,
38
+ verifyFilesSchema: [],
37
39
  handler: async (request, response) => {
38
40
  const toolName = request.params.toolName;
39
41
  let input = {};
@@ -40,7 +40,7 @@ export async function parseRawTraceBuffer(buffer, metadata) {
40
40
  }
41
41
  catch (e) {
42
42
  const errorText = e instanceof Error ? e.message : JSON.stringify(e);
43
- logger(`Unexpected error parsing trace: ${errorText}`);
43
+ logger?.(`Unexpected error parsing trace: ${errorText}`);
44
44
  return {
45
45
  error: errorText,
46
46
  };
@@ -51,9 +51,9 @@ const extraFormatDescriptions = `Information on performance traces may contain m
51
51
  ${DevTools.PerformanceTraceFormatter.callFrameDataFormatDescription}
52
52
 
53
53
  ${DevTools.PerformanceTraceFormatter.networkDataFormatDescription}`;
54
- export function getTraceSummary(result) {
54
+ export function getTraceSummary(result, deviceScope) {
55
55
  const focus = DevTools.AgentFocus.fromParsedTrace(result.parsedTrace);
56
- const formatter = new DevTools.PerformanceTraceFormatter(focus);
56
+ const formatter = new DevTools.PerformanceTraceFormatter(focus, deviceScope);
57
57
  const summaryText = formatter.formatTraceSummary();
58
58
  return `## Summary of Performance trace findings:
59
59
  ${summaryText}
@@ -61,7 +61,7 @@ ${summaryText}
61
61
  ## Details on call tree & network request formats:
62
62
  ${extraFormatDescriptions}`;
63
63
  }
64
- export function getInsightOutput(result, insightSetId, insightName) {
64
+ export function getInsightOutput(result, insightSetId, insightName, deviceScope) {
65
65
  if (!result.insights) {
66
66
  return {
67
67
  error: 'No Performance insights are available for this trace.',
@@ -79,7 +79,7 @@ export function getInsightOutput(result, insightSetId, insightName) {
79
79
  error: `No Insight with the name ${insightName} found. Double check the name you provided is accurate and try again.`,
80
80
  };
81
81
  }
82
- const formatter = new DevTools.PerformanceInsightFormatter(DevTools.AgentFocus.fromParsedTrace(result.parsedTrace), matchingInsight);
82
+ const formatter = new DevTools.PerformanceInsightFormatter(DevTools.AgentFocus.fromParsedTrace(result.parsedTrace), matchingInsight, deviceScope);
83
83
  return { output: formatter.formatInsight() };
84
84
  }
85
85
  //# sourceMappingURL=parse.js.map
@@ -5,6 +5,6 @@
5
5
  */
6
6
  // If moved update release-please config
7
7
  // x-release-please-start-version
8
- export const VERSION = '1.1.1';
8
+ export const VERSION = '1.2.0';
9
9
  // x-release-please-end
10
10
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chrome-devtools-mcp",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "MCP server for Chrome DevTools",
5
5
  "type": "module",
6
6
  "bin": {
@@ -54,6 +54,7 @@
54
54
  "@rollup/plugin-json": "^6.1.0",
55
55
  "@rollup/plugin-node-resolve": "^16.0.3",
56
56
  "@stylistic/eslint-plugin": "^5.4.0",
57
+ "@toon-format/toon": "^2.2.0",
57
58
  "@types/debug": "^4.1.12",
58
59
  "@types/filesystem": "^0.0.36",
59
60
  "@types/node": "^25.0.0",
@@ -62,7 +63,7 @@
62
63
  "@types/yargs": "^17.0.33",
63
64
  "@typescript-eslint/eslint-plugin": "^8.43.0",
64
65
  "@typescript-eslint/parser": "^8.43.0",
65
- "chrome-devtools-frontend": "1.0.1632065",
66
+ "chrome-devtools-frontend": "1.0.1641723",
66
67
  "core-js": "3.49.0",
67
68
  "debug": "4.4.3",
68
69
  "eslint": "^9.35.0",
@@ -72,7 +73,7 @@
72
73
  "lighthouse": "13.3.0",
73
74
  "prettier": "^3.6.2",
74
75
  "puppeteer": "25.1.0",
75
- "rollup": "4.60.4",
76
+ "rollup": "4.61.0",
76
77
  "rollup-plugin-cleanup": "^3.2.1",
77
78
  "rollup-plugin-license": "^3.6.0",
78
79
  "semver": "^7.7.4",