chrome-devtools-mcp 0.16.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -27,6 +27,12 @@ allowing them to inspect, debug, and modify any data in the browser or DevTools.
27
27
  Avoid sharing sensitive or personal information that you don't want to share with
28
28
  MCP clients.
29
29
 
30
+ Performance tools may send trace URLs to the Google CrUX API to fetch real-user
31
+ experience data. This helps provide a holistic performance picture by
32
+ presenting field data alongside lab data. This data is collected by the [Chrome
33
+ User Experience Report (CrUX)](https://developer.chrome.com/docs/crux). To disable
34
+ this, run with the `--no-performance-crux` flag.
35
+
30
36
  ## **Usage statistics**
31
37
 
32
38
  Google collects usage statistics (such as tool invocation success rates, latency, and environment information) to improve the reliability and performance of Chrome DevTools MCP.
@@ -466,6 +472,11 @@ The Chrome DevTools MCP server supports the following configuration option:
466
472
  - **Type:** boolean
467
473
  - **Default:** `true`
468
474
 
475
+ - **`--performanceCrux`/ `--performance-crux`**
476
+ Set to false to disable sending URLs from performance traces to CrUX API to get field performance data.
477
+ - **Type:** boolean
478
+ - **Default:** `true`
479
+
469
480
  - **`--usageStatistics`/ `--usage-statistics`**
470
481
  Set to false to opt-out of usage statistics collection. Google collects usage data to improve the tool, handled under the Google Privacy Policy (https://policies.google.com/privacy). This is independent from Chrome browser metrics. Disabled if CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS or CI env variables are set.
471
482
  - **Type:** boolean
@@ -169,6 +169,119 @@ const SKIP_ALL_PAUSES = {
169
169
  // Do nothing.
170
170
  },
171
171
  };
172
+ /**
173
+ * Constructed from Runtime.ExceptionDetails of an uncaught error.
174
+ *
175
+ * TODO: Also construct from a RemoteObject of subtype 'error'.
176
+ *
177
+ * Consists of the message, a fully resolved stack trace and a fully resolved 'cause' chain.
178
+ */
179
+ export class SymbolizedError {
180
+ message;
181
+ stackTrace;
182
+ cause;
183
+ constructor(message, stackTrace, cause) {
184
+ this.message = message;
185
+ this.stackTrace = stackTrace;
186
+ this.cause = cause;
187
+ }
188
+ static async fromDetails(opts) {
189
+ const message = SymbolizedError.#getMessage(opts.details);
190
+ if (!opts.includeStackAndCause || !opts.devTools) {
191
+ return new SymbolizedError(message, opts.resolvedStackTraceForTesting, opts.resolvedCauseForTesting);
192
+ }
193
+ let stackTrace;
194
+ if (opts.resolvedStackTraceForTesting) {
195
+ stackTrace = opts.resolvedStackTraceForTesting;
196
+ }
197
+ else if (opts.details.stackTrace) {
198
+ try {
199
+ stackTrace = await createStackTrace(opts.devTools, opts.details.stackTrace, opts.targetId);
200
+ }
201
+ catch {
202
+ // ignore
203
+ }
204
+ }
205
+ // TODO: Turn opts.details.exception into a JSHandle and retrieve the 'cause' property.
206
+ // If its an Error, recursively create a SymbolizedError.
207
+ let cause;
208
+ if (opts.resolvedCauseForTesting) {
209
+ cause = opts.resolvedCauseForTesting;
210
+ }
211
+ else if (opts.details.exception) {
212
+ try {
213
+ const causeRemoteObj = await SymbolizedError.#lookupCause(opts.devTools, opts.details.exception, opts.targetId);
214
+ if (causeRemoteObj) {
215
+ cause = await SymbolizedError.fromError({
216
+ devTools: opts.devTools,
217
+ error: causeRemoteObj,
218
+ targetId: opts.targetId,
219
+ });
220
+ }
221
+ }
222
+ catch {
223
+ // Ignore
224
+ }
225
+ }
226
+ return new SymbolizedError(message, stackTrace, cause);
227
+ }
228
+ static async fromError(opts) {
229
+ const details = await SymbolizedError.#getExceptionDetails(opts.devTools, opts.error, opts.targetId);
230
+ if (details) {
231
+ return SymbolizedError.fromDetails({
232
+ details,
233
+ devTools: opts.devTools,
234
+ targetId: opts.targetId,
235
+ includeStackAndCause: true,
236
+ });
237
+ }
238
+ return new SymbolizedError(SymbolizedError.#getMessageFromException(opts.error));
239
+ }
240
+ static #getMessage(details) {
241
+ // For Runtime.exceptionThrown with a present exception object, `details.text` will be "Uncaught" and
242
+ // we have to manually parse out the error text from the exception description.
243
+ // In the case of Runtime.getExceptionDetails, `details.text` has the Error.message.
244
+ if (details.text === 'Uncaught' && details.exception) {
245
+ return ('Uncaught ' +
246
+ SymbolizedError.#getMessageFromException(details.exception));
247
+ }
248
+ return details.text;
249
+ }
250
+ static #getMessageFromException(error) {
251
+ const messageWithRest = error.description?.split('\n at ', 2) ?? [];
252
+ return messageWithRest[0] ?? '';
253
+ }
254
+ static async #getExceptionDetails(devTools, error, targetId) {
255
+ if (!devTools || (error.type !== 'object' && error.subtype !== 'error')) {
256
+ return null;
257
+ }
258
+ const targetManager = devTools.universe.context.get(DevTools.TargetManager);
259
+ const target = targetId
260
+ ? targetManager.targetById(targetId) || devTools.target
261
+ : devTools.target;
262
+ const model = target.model(DevTools.RuntimeModel);
263
+ return ((await model.getExceptionDetails(error.objectId)) ?? null);
264
+ }
265
+ static async #lookupCause(devTools, error, targetId) {
266
+ if (!devTools || (error.type !== 'object' && error.subtype !== 'error')) {
267
+ return null;
268
+ }
269
+ const targetManager = devTools.universe.context.get(DevTools.TargetManager);
270
+ const target = targetId
271
+ ? targetManager.targetById(targetId) || devTools.target
272
+ : devTools.target;
273
+ const properties = await target.runtimeAgent().invoke_getProperties({
274
+ objectId: error.objectId,
275
+ });
276
+ if (properties.getError()) {
277
+ return null;
278
+ }
279
+ return properties.result.find(prop => prop.name === 'cause')?.value ?? null;
280
+ }
281
+ static createForTesting(message, stackTrace, cause) {
282
+ return new SymbolizedError(message, stackTrace, cause);
283
+ }
284
+ }
172
285
  export async function createStackTraceForConsoleMessage(devTools, consoleMessage) {
173
286
  const message = consoleMessage;
174
287
  const rawStackTrace = message._rawStackTrace();
@@ -262,6 +262,9 @@ export class McpContext {
262
262
  isRunningPerformanceTrace() {
263
263
  return this.#isRunningTrace;
264
264
  }
265
+ isCruxEnabled() {
266
+ return this.#options.performanceCrux;
267
+ }
265
268
  getDialog() {
266
269
  return this.#dialog;
267
270
  }
@@ -194,11 +194,6 @@ export class McpResponse {
194
194
  }
195
195
  detailedConsoleMessage = formatter;
196
196
  }
197
- else {
198
- detailedConsoleMessage = await ConsoleFormatter.from(message, {
199
- id: consoleMessageStableId,
200
- });
201
- }
202
197
  }
203
198
  let extensions;
204
199
  if (this.#listExtensions) {
@@ -239,9 +234,7 @@ export class McpResponse {
239
234
  }
240
235
  return formatter;
241
236
  }
242
- return await ConsoleFormatter.from(item, {
243
- id: consoleMessageStableId,
244
- });
237
+ return null;
245
238
  }))).filter(item => item !== null);
246
239
  }
247
240
  let networkRequests;
@@ -7,12 +7,10 @@ import { FakeIssuesManager } from './DevtoolsUtils.js';
7
7
  import { logger } from './logger.js';
8
8
  import { DevTools } from './third_party/index.js';
9
9
  export class UncaughtError {
10
- message;
11
- stackTrace;
10
+ details;
12
11
  targetId;
13
- constructor(message, stackTrace, targetId) {
14
- this.message = message;
15
- this.stackTrace = stackTrace;
12
+ constructor(details, targetId) {
13
+ this.details = details;
16
14
  this.targetId = targetId;
17
15
  }
18
16
  }
@@ -238,10 +236,7 @@ class PageEventSubscriber {
238
236
  this.#page.emit('issue', event.data);
239
237
  };
240
238
  #onExceptionThrown = (event) => {
241
- const { exception, text, stackTrace } = event.exceptionDetails;
242
- const messageWithRest = exception?.description?.split('\n at ', 2) ?? [];
243
- const message = text + ' ' + (messageWithRest[0] ?? '');
244
- this.#page.emit('uncaughtError', new UncaughtError(message, stackTrace, this.#targetId));
239
+ this.#page.emit('uncaughtError', new UncaughtError(event.exceptionDetails, this.#targetId));
245
240
  };
246
241
  // On navigation, we reset issue aggregation.
247
242
  #onFrameNavigated = (frame) => {
package/build/src/cli.js CHANGED
@@ -188,6 +188,11 @@ export const cliOptions = {
188
188
  hidden: true,
189
189
  describe: 'Set to false to exclude tools related to extensions.',
190
190
  },
191
+ performanceCrux: {
192
+ type: 'boolean',
193
+ default: true,
194
+ describe: 'Set to false to disable sending URLs from performance traces to CrUX API to get field performance data.',
195
+ },
191
196
  usageStatistics: {
192
197
  type: 'boolean',
193
198
  default: true,
@@ -277,6 +282,10 @@ export function parseArguments(version, argv = process.argv) {
277
282
  '$0 --no-usage-statistics',
278
283
  'Do not send usage statistics https://github.com/ChromeDevTools/chrome-devtools-mcp#usage-statistics.',
279
284
  ],
285
+ [
286
+ '$0 --no-performance-crux',
287
+ 'Disable CrUX (field data) integration in performance tools.',
288
+ ],
280
289
  ]);
281
290
  return yargsInstance
282
291
  .wrap(Math.min(120, yargsInstance.terminalWidth()))
@@ -3,35 +3,80 @@
3
3
  * Copyright 2026 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { createStackTraceForConsoleMessage, createStackTrace, } from '../DevtoolsUtils.js';
6
+ var _a;
7
+ import { createStackTraceForConsoleMessage, SymbolizedError, } from '../DevtoolsUtils.js';
8
+ import { UncaughtError } from '../PageCollector.js';
9
+ import * as DevTools from '../third_party/index.js';
7
10
  export class ConsoleFormatter {
8
- #msg;
9
- #resolvedArgs = [];
10
- #resolvedStackTrace;
11
+ static #STACK_TRACE_MAX_LINES = 50;
11
12
  #id;
12
- constructor(msg, options) {
13
- this.#msg = msg;
14
- this.#id = options?.id;
15
- this.#resolvedStackTrace = options?.resolvedStackTraceForTesting;
13
+ #type;
14
+ #text;
15
+ #argCount;
16
+ #resolvedArgs;
17
+ #stack;
18
+ #cause;
19
+ #isIgnored;
20
+ constructor(params) {
21
+ this.#id = params.id;
22
+ this.#type = params.type;
23
+ this.#text = params.text;
24
+ this.#argCount = params.argCount ?? 0;
25
+ this.#resolvedArgs = params.resolvedArgs ?? [];
26
+ this.#stack = params.stack;
27
+ this.#cause = params.cause;
28
+ this.#isIgnored = params.isIgnored;
16
29
  }
17
30
  static async from(msg, options) {
18
- const formatter = new ConsoleFormatter(msg, options);
19
- if (options?.fetchDetailedData) {
20
- await formatter.#loadDetailedData(options?.devTools);
31
+ const ignoreListManager = options?.devTools?.universe.context.get(DevTools.DevTools.IgnoreListManager);
32
+ const isIgnored = options.isIgnoredForTesting ||
33
+ (frame => {
34
+ if (!ignoreListManager) {
35
+ return false;
36
+ }
37
+ if (frame.uiSourceCode) {
38
+ return ignoreListManager.isUserOrSourceMapIgnoreListedUISourceCode(frame.uiSourceCode);
39
+ }
40
+ if (frame.url) {
41
+ return ignoreListManager.isUserIgnoreListedURL(frame.url);
42
+ }
43
+ return false;
44
+ });
45
+ if (msg instanceof UncaughtError) {
46
+ const error = await SymbolizedError.fromDetails({
47
+ devTools: options?.devTools,
48
+ details: msg.details,
49
+ targetId: msg.targetId,
50
+ includeStackAndCause: options?.fetchDetailedData,
51
+ resolvedStackTraceForTesting: options?.resolvedStackTraceForTesting,
52
+ resolvedCauseForTesting: options?.resolvedCauseForTesting,
53
+ });
54
+ return new _a({
55
+ id: options.id,
56
+ type: 'error',
57
+ text: error.message,
58
+ stack: error.stackTrace,
59
+ cause: error.cause,
60
+ isIgnored,
61
+ });
21
62
  }
22
- return formatter;
23
- }
24
- #isConsoleMessage(msg) {
25
- // No `instanceof` as tests mock `ConsoleMessage`.
26
- return 'args' in msg && typeof msg.args === 'function';
27
- }
28
- async #loadDetailedData(devTools) {
29
- if (this.#msg instanceof Error) {
30
- return;
63
+ let resolvedArgs = [];
64
+ if (options.resolvedArgsForTesting) {
65
+ resolvedArgs = options.resolvedArgsForTesting;
31
66
  }
32
- if (this.#isConsoleMessage(this.#msg)) {
33
- this.#resolvedArgs = await Promise.all(this.#msg.args().map(async (arg, i) => {
67
+ else if (options.fetchDetailedData) {
68
+ resolvedArgs = await Promise.all(msg.args().map(async (arg, i) => {
34
69
  try {
70
+ const remoteObject = arg.remoteObject();
71
+ if (remoteObject.type === 'object' &&
72
+ remoteObject.subtype === 'error') {
73
+ return await SymbolizedError.fromError({
74
+ devTools: options.devTools,
75
+ error: remoteObject,
76
+ // @ts-expect-error Internal ConsoleMessage API
77
+ targetId: msg._targetId(),
78
+ });
79
+ }
35
80
  return await arg.jsonValue();
36
81
  }
37
82
  catch {
@@ -39,71 +84,66 @@ export class ConsoleFormatter {
39
84
  }
40
85
  }));
41
86
  }
42
- if (devTools) {
87
+ let stack;
88
+ if (options.resolvedStackTraceForTesting) {
89
+ stack = options.resolvedStackTraceForTesting;
90
+ }
91
+ else if (options.fetchDetailedData && options.devTools) {
43
92
  try {
44
- if (this.#isConsoleMessage(this.#msg)) {
45
- this.#resolvedStackTrace = await createStackTraceForConsoleMessage(devTools, this.#msg);
46
- }
47
- else if (this.#msg.stackTrace) {
48
- this.#resolvedStackTrace = await createStackTrace(devTools, this.#msg.stackTrace, this.#msg.targetId);
49
- }
93
+ stack = await createStackTraceForConsoleMessage(options.devTools, msg);
50
94
  }
51
95
  catch {
52
96
  // ignore
53
97
  }
54
98
  }
99
+ return new _a({
100
+ id: options.id,
101
+ type: msg.type(),
102
+ text: msg.text(),
103
+ argCount: resolvedArgs.length || msg.args().length,
104
+ resolvedArgs,
105
+ stack,
106
+ isIgnored,
107
+ });
55
108
  }
56
109
  // The short format for a console message.
57
110
  toString() {
58
- const type = this.#getType();
59
- const text = this.#getText();
60
- const argsCount = this.#getArgsCount();
61
- const idPart = this.#id !== undefined ? `msgid=${this.#id} ` : '';
62
- return `${idPart}[${type}] ${text} (${argsCount} args)`;
111
+ return `msgid=${this.#id} [${this.#type}] ${this.#text} (${this.#argCount} args)`;
63
112
  }
64
113
  // The verbose format for a console message, including all details.
65
114
  toStringDetailed() {
66
115
  const result = [
67
- this.#id !== undefined ? `ID: ${this.#id}` : '',
68
- `Message: ${this.#getType()}> ${this.#getText()}`,
116
+ `ID: ${this.#id}`,
117
+ `Message: ${this.#type}> ${this.#text}`,
69
118
  this.#formatArgs(),
70
- this.#formatStackTrace(this.#resolvedStackTrace),
119
+ this.#formatStackTrace(this.#stack, this.#cause, {
120
+ includeHeading: true,
121
+ }),
71
122
  ].filter(line => !!line);
72
123
  return result.join('\n');
73
124
  }
74
- #getType() {
75
- if (!this.#isConsoleMessage(this.#msg)) {
76
- return 'error';
77
- }
78
- return this.#msg.type();
79
- }
80
- #getText() {
81
- if (!this.#isConsoleMessage(this.#msg)) {
82
- return this.#msg.message;
83
- }
84
- return this.#msg.text();
85
- }
86
125
  #getArgs() {
87
- if (!this.#isConsoleMessage(this.#msg)) {
88
- return [];
89
- }
90
126
  if (this.#resolvedArgs.length > 0) {
91
127
  const args = [...this.#resolvedArgs];
92
128
  // If there is no text, the first argument serves as text (see formatMessage).
93
- if (!this.#msg.text()) {
129
+ if (!this.#text) {
94
130
  args.shift();
95
131
  }
96
132
  return args;
97
133
  }
98
134
  return [];
99
135
  }
100
- #getArgsCount() {
101
- if (!this.#isConsoleMessage(this.#msg)) {
102
- return 0;
103
- }
104
- return this.#resolvedArgs.length || this.#msg.args().length;
105
- }
106
136
  #formatArg(arg) {
137
+ if (arg instanceof SymbolizedError) {
138
+ return [
139
+ arg.message,
140
+ this.#formatStackTrace(arg.stackTrace, arg.cause, {
141
+ includeHeading: false,
142
+ }),
143
+ ]
144
+ .filter(line => !!line)
145
+ .join('\n');
146
+ }
107
147
  return typeof arg === 'object' ? JSON.stringify(arg) : String(arg);
108
148
  }
109
149
  #formatArgs() {
@@ -117,25 +157,47 @@ export class ConsoleFormatter {
117
157
  }
118
158
  return result.join('\n');
119
159
  }
120
- #formatStackTrace(stackTrace) {
160
+ #formatStackTrace(stackTrace, cause, opts) {
121
161
  if (!stackTrace) {
122
162
  return '';
123
163
  }
164
+ const lines = this.#formatStackTraceInner(stackTrace, cause);
165
+ const includedLines = lines.slice(0, _a.#STACK_TRACE_MAX_LINES);
166
+ const reminderCount = lines.length - includedLines.length;
124
167
  return [
125
- '### Stack trace',
126
- this.#formatFragment(stackTrace.syncFragment),
127
- ...stackTrace.asyncFragments.map(this.#formatAsyncFragment.bind(this)),
168
+ opts.includeHeading ? '### Stack trace' : '',
169
+ ...includedLines,
170
+ reminderCount > 0 ? `... and ${reminderCount} more frames` : '',
128
171
  'Note: line and column numbers use 1-based indexing',
129
- ].join('\n');
172
+ ]
173
+ .filter(line => !!line)
174
+ .join('\n');
175
+ }
176
+ #formatStackTraceInner(stackTrace, cause) {
177
+ if (!stackTrace) {
178
+ return [];
179
+ }
180
+ return [
181
+ ...this.#formatFragment(stackTrace.syncFragment),
182
+ ...stackTrace.asyncFragments
183
+ .map(this.#formatAsyncFragment.bind(this))
184
+ .flat(),
185
+ ...this.#formatCause(cause),
186
+ ];
130
187
  }
131
188
  #formatFragment(fragment) {
132
- return fragment.frames.map(this.#formatFrame.bind(this)).join('\n');
189
+ const frames = fragment.frames.filter(frame => !this.#isIgnored(frame));
190
+ return frames.map(this.#formatFrame.bind(this));
133
191
  }
134
192
  #formatAsyncFragment(fragment) {
193
+ const formattedFrames = this.#formatFragment(fragment);
194
+ if (formattedFrames.length === 0) {
195
+ return [];
196
+ }
135
197
  const separatorLineLength = 40;
136
198
  const prefix = `--- ${fragment.description || 'async'} `;
137
199
  const separator = prefix + '-'.repeat(separatorLineLength - prefix.length);
138
- return separator + '\n' + this.#formatFragment(fragment);
200
+ return [separator, ...formattedFrames];
139
201
  }
140
202
  #formatFrame(frame) {
141
203
  let result = `at ${frame.name ?? '<anonymous>'}`;
@@ -148,21 +210,31 @@ export class ConsoleFormatter {
148
210
  }
149
211
  return result;
150
212
  }
213
+ #formatCause(cause) {
214
+ if (!cause) {
215
+ return [];
216
+ }
217
+ return [
218
+ `Caused by: ${cause.message}`,
219
+ ...this.#formatStackTraceInner(cause.stackTrace, cause.cause),
220
+ ];
221
+ }
151
222
  toJSON() {
152
223
  return {
153
- type: this.#getType(),
154
- text: this.#getText(),
155
- argsCount: this.#getArgsCount(),
224
+ type: this.#type,
225
+ text: this.#text,
226
+ argsCount: this.#argCount,
156
227
  id: this.#id,
157
228
  };
158
229
  }
159
230
  toJSONDetailed() {
160
231
  return {
161
232
  id: this.#id,
162
- type: this.#getType(),
163
- text: this.#getText(),
233
+ type: this.#type,
234
+ text: this.#text,
164
235
  args: this.#getArgs().map(arg => typeof arg === 'object' ? arg : String(arg)),
165
- stackTrace: this.#resolvedStackTrace,
236
+ stackTrace: this.#stack,
166
237
  };
167
238
  }
168
239
  }
240
+ _a = ConsoleFormatter;
package/build/src/main.js CHANGED
@@ -20,7 +20,7 @@ import { ToolCategory } from './tools/categories.js';
20
20
  import { tools } from './tools/tools.js';
21
21
  // If moved update release-please config
22
22
  // x-release-please-start-version
23
- const VERSION = '0.16.0';
23
+ const VERSION = '0.17.0';
24
24
  // x-release-please-end
25
25
  export const args = parseArguments(VERSION);
26
26
  const logFile = args.logFile ? saveLogsToFile(args.logFile) : undefined;
@@ -87,6 +87,7 @@ async function getContext() {
87
87
  context = await McpContext.from(browser, logger, {
88
88
  experimentalDevToolsDebugging: devtools,
89
89
  experimentalIncludeAllPages: args.experimentalIncludeAllPages,
90
+ performanceCrux: args.performanceCrux,
90
91
  });
91
92
  }
92
93
  return context;
@@ -95,6 +96,9 @@ const logDisclaimers = () => {
95
96
  console.error(`chrome-devtools-mcp exposes content of the browser instance to the MCP clients allowing them to inspect,
96
97
  debug, and modify any data in the browser or DevTools.
97
98
  Avoid sharing sensitive or personal information that you do not want to share with MCP clients.`);
99
+ if (args.performanceCrux) {
100
+ 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.`);
101
+ }
98
102
  if (args.usageStatistics) {
99
103
  console.error(`
100
104
  Google collects usage statistics to improve Chrome DevTools MCP. To opt-out, run with --no-usage-statistics.
@@ -422,7 +422,7 @@ SOFTWARE.
422
422
 
423
423
  Name: @modelcontextprotocol/sdk
424
424
  URL: https://modelcontextprotocol.io
425
- Version: 1.25.3
425
+ Version: 1.26.0
426
426
  License: MIT
427
427
 
428
428
  MIT License
@@ -452,7 +452,7 @@ SOFTWARE.
452
452
 
453
453
  Name: zod-to-json-schema
454
454
  URL: https://github.com/StefanTerdell/zod-to-json-schema
455
- Version: 3.25.0
455
+ Version: 3.25.1
456
456
  License: ISC
457
457
 
458
458
  ISC License
@@ -636,14 +636,14 @@ SOFTWARE.
636
636
 
637
637
  Name: puppeteer-core
638
638
  URL: https://github.com/puppeteer/puppeteer/tree/main/packages/puppeteer-core
639
- Version: 24.36.1
639
+ Version: 24.37.2
640
640
  License: Apache-2.0
641
641
 
642
642
  -------------------- DEPENDENCY DIVIDER --------------------
643
643
 
644
644
  Name: @puppeteer/browsers
645
645
  URL: https://github.com/puppeteer/puppeteer/tree/main/packages/browsers
646
- Version: 2.11.2
646
+ Version: 2.12.0
647
647
  License: Apache-2.0
648
648
 
649
649
  -------------------- DEPENDENCY DIVIDER --------------------
@@ -1,8 +1,8 @@
1
1
  {
2
- "@modelcontextprotocol/sdk": "1.25.3",
3
- "chrome-devtools-frontend": "1.0.1576915",
2
+ "@modelcontextprotocol/sdk": "1.26.0",
3
+ "chrome-devtools-frontend": "1.0.1581449",
4
4
  "core-js": "3.48.0",
5
5
  "debug": "4.4.3",
6
6
  "yargs": "18.0.0",
7
- "puppeteer-core": "24.36.1"
7
+ "puppeteer-core": "24.37.2"
8
8
  }
@@ -12447,7 +12447,6 @@ const UIStrings$2 = {
12447
12447
  networkPanel: 'Network panel',
12448
12448
  requestConditionsDrawer: 'Request conditions drawer',
12449
12449
  applicationPanel: 'Application panel',
12450
- securityPanel: 'Security panel',
12451
12450
  sourcesPanel: 'Sources panel',
12452
12451
  timelinePanel: 'Performance panel',
12453
12452
  memoryInspectorPanel: 'Memory inspector panel',
@@ -12467,7 +12466,6 @@ const i18nLazyString$1 = getLazilyComputedLocalizedString.bind(undefined, str_$2
12467
12466
  TIMELINE_PANEL: i18nLazyString$1(UIStrings$2.timelinePanel),
12468
12467
  APPLICATION_PANEL: i18nLazyString$1(UIStrings$2.applicationPanel),
12469
12468
  SOURCES_PANEL: i18nLazyString$1(UIStrings$2.sourcesPanel),
12470
- SECURITY_PANEL: i18nLazyString$1(UIStrings$2.securityPanel),
12471
12469
  MEMORY_INSPECTOR_PANEL: i18nLazyString$1(UIStrings$2.memoryInspectorPanel),
12472
12470
  ANIMATIONS_PANEL: i18nLazyString$1(UIStrings$2.animationsPanel),
12473
12471
  });