From ede0312e3c865e73d6c61e7d9b66882d4aad4fe0 Mon Sep 17 00:00:00 2001 From: Piotr Paulski Date: Fri, 17 Oct 2025 15:51:27 +0000 Subject: [PATCH 01/10] refactor: bundle puppeteer-core --- rollup.config.mjs | 19 ++++++++++++------- src/browser.ts | 3 ++- src/third_party/puppeteer-core/index.ts | 8 ++++++++ src/tools/emulation.ts | 2 +- src/tools/snapshot.ts | 2 +- 5 files changed, 24 insertions(+), 10 deletions(-) create mode 100644 src/third_party/puppeteer-core/index.ts diff --git a/rollup.config.mjs b/rollup.config.mjs index b03ee2762..274a93c1b 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -29,11 +29,14 @@ import license from 'rollup-plugin-license'; const isProduction = process.env.NODE_ENV === 'production'; -/** @type {import('rollup').RollupOptions} */ -const sdk = { - input: './build/src/third_party/modelcontextprotocol-sdk/index.js', +const allowed_licenses = ['MIT', 'Apache 2.0', 'Apache-2.0', 'BSD-3-Clause', 'BSD-2-Clause', 'ISC', '0BSD']; + +/** @returns {import('rollup').RollupOptions} */ +const bundleDependency = (wrapperIndexPath, extraOutputOptions = {}) => ({ + input: wrapperIndexPath, output: { - file: './build/src/third_party/modelcontextprotocol-sdk/index.js', + ...extraOutputOptions, + file: wrapperIndexPath, sourcemap: !isProduction, format: 'esm', }, @@ -48,7 +51,6 @@ const sdk = { thirdParty: { allow: { test: dependency => { - let allowed_licenses = ['MIT', 'Apache 2.0', 'BSD-2-Clause', 'ISC']; return allowed_licenses.includes(dependency.license); }, failOnUnlicensed: true, @@ -90,6 +92,9 @@ const sdk = { json(), nodeResolve(), ], -}; +}); -export default [sdk]; +export default [ + bundleDependency('./build/src/third_party/modelcontextprotocol-sdk/index.js'), + bundleDependency('./build/src/third_party/puppeteer-core/index.js', {inlineDynamicImports: true}), +]; diff --git a/src/browser.ts b/src/browser.ts index d76d5a9f5..f129ec76d 100644 --- a/src/browser.ts +++ b/src/browser.ts @@ -14,7 +14,8 @@ import type { LaunchOptions, Target, } from 'puppeteer-core'; -import puppeteer from 'puppeteer-core'; + +import {puppeteer} from './third_party/puppeteer-core/index.js'; let browser: Browser | undefined; diff --git a/src/third_party/puppeteer-core/index.ts b/src/third_party/puppeteer-core/index.ts new file mode 100644 index 000000000..42718705a --- /dev/null +++ b/src/third_party/puppeteer-core/index.ts @@ -0,0 +1,8 @@ +/** + * @license + * Copyright 2025 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +export {Locator,PredefinedNetworkConditions} from 'puppeteer-core'; +export {default as puppeteer} from 'puppeteer-core'; diff --git a/src/tools/emulation.ts b/src/tools/emulation.ts index d65ac5e89..fed24a00f 100644 --- a/src/tools/emulation.ts +++ b/src/tools/emulation.ts @@ -4,9 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {PredefinedNetworkConditions} from 'puppeteer-core'; import {zod} from '../third_party/modelcontextprotocol-sdk/index.js'; +import {PredefinedNetworkConditions} from '../third_party/puppeteer-core/index.js'; import {ToolCategories} from './categories.js'; import {defineTool} from './ToolDefinition.js'; diff --git a/src/tools/snapshot.ts b/src/tools/snapshot.ts index fb774f78f..bd1481257 100644 --- a/src/tools/snapshot.ts +++ b/src/tools/snapshot.ts @@ -4,9 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {Locator} from 'puppeteer-core'; import {zod} from '../third_party/modelcontextprotocol-sdk/index.js'; +import {Locator} from '../third_party/puppeteer-core/index.js'; import {ToolCategories} from './categories.js'; import {defineTool, timeoutSchema} from './ToolDefinition.js'; From d5f8a1e2aab857acef761f3c93c27e65f3fedb89 Mon Sep 17 00:00:00 2001 From: Piotr Paulski Date: Mon, 20 Oct 2025 14:16:24 +0000 Subject: [PATCH 02/10] Work around overly strict check in puppeteer. --- src/McpContext.ts | 28 +++++++++++++++++++++++++--- src/tools/ToolDefinition.ts | 1 + src/tools/snapshot.ts | 16 +--------------- tests/utils.ts | 4 ++-- 4 files changed, 29 insertions(+), 20 deletions(-) diff --git a/src/McpContext.ts b/src/McpContext.ts index 29170568d..d5cae792e 100644 --- a/src/McpContext.ts +++ b/src/McpContext.ts @@ -21,6 +21,7 @@ import type { import type {ListenerMap} from './PageCollector.js'; import {NetworkCollector, PageCollector} from './PageCollector.js'; +import {Locator} from './third_party/puppeteer-core/index.js'; import {listPages} from './tools/pages.js'; import {takeSnapshot} from './tools/snapshot.js'; import {CLOSE_PAGE_ERROR} from './tools/ToolDefinition.js'; @@ -91,9 +92,12 @@ export class McpContext implements Context { #nextSnapshotId = 1; #traceResults: TraceResult[] = []; - private constructor(browser: Browser, logger: Debugger) { + #locatorClass: typeof Locator; + + private constructor(browser: Browser, logger: Debugger, locatorClass: typeof Locator) { this.browser = browser; this.logger = logger; + this.#locatorClass = locatorClass; this.#networkCollector = new NetworkCollector(this.browser); @@ -122,8 +126,8 @@ export class McpContext implements Context { await this.#consoleCollector.init(); } - static async from(browser: Browser, logger: Debugger) { - const context = new McpContext(browser, logger); + static async from(browser: Browser, logger: Debugger, locatorClass: typeof Locator = Locator) { + const context = new McpContext(browser, logger, locatorClass); await context.#init(); return context; } @@ -428,4 +432,22 @@ export class McpContext implements Context { getNetworkRequestStableId(request: HTTPRequest): number { return this.#networkCollector.getIdForResource(request); } + + waitForTextOnPage({text, timeout}: {text: string, timeout?: number|undefined}): Promise { + const page = this.getSelectedPage(); + const frames = page.frames(); + + const locator = this.#locatorClass.race( + frames.flatMap(frame => [ + frame.locator(`aria/${text}`), + frame.locator(`text/${text}`), + ]), + ); + + if (timeout) { + locator.setTimeout(timeout); + } + + return locator.wait(); + } } diff --git a/src/tools/ToolDefinition.ts b/src/tools/ToolDefinition.ts index e90264a7e..6ff2dc73c 100644 --- a/src/tools/ToolDefinition.ts +++ b/src/tools/ToolDefinition.ts @@ -93,6 +93,7 @@ export type Context = Readonly<{ filename: string, ): Promise<{filename: string}>; waitForEventsAfterAction(action: () => Promise): Promise; + waitForTextOnPage(params: {text: string, timeout?: number|undefined}): Promise; }>; export function defineTool( diff --git a/src/tools/snapshot.ts b/src/tools/snapshot.ts index bd1481257..b6e745ab3 100644 --- a/src/tools/snapshot.ts +++ b/src/tools/snapshot.ts @@ -44,21 +44,7 @@ export const waitFor = defineTool({ ...timeoutSchema, }, handler: async (request, response, context) => { - const page = context.getSelectedPage(); - const frames = page.frames(); - - const locator = Locator.race( - frames.flatMap(frame => [ - frame.locator(`aria/${request.params.text}`), - frame.locator(`text/${request.params.text}`), - ]), - ); - - if (request.params.timeout) { - locator.setTimeout(request.params.timeout); - } - - await locator.wait(); + await context.waitForTextOnPage(request.params); response.appendResponseLine( `Element with text "${request.params.text}" found.`, diff --git a/tests/utils.ts b/tests/utils.ts index 6c8744fb0..7adaaf533 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -5,7 +5,7 @@ */ import logger from 'debug'; import type {Browser} from 'puppeteer'; -import puppeteer from 'puppeteer'; +import puppeteer, {Locator} from 'puppeteer'; import type {Frame, HTTPRequest, HTTPResponse} from 'puppeteer-core'; import {McpContext} from '../src/McpContext.js'; @@ -36,7 +36,7 @@ export async function withBrowser( }), ); const response = new McpResponse(); - const context = await McpContext.from(browser, logger('test')); + const context = await McpContext.from(browser, logger('test'), Locator); await cb(response, context); } From 99052a2295d111c9bf75d0bea17ea97ac0f6763a Mon Sep 17 00:00:00 2001 From: Piotr Paulski Date: Mon, 20 Oct 2025 14:33:27 +0000 Subject: [PATCH 03/10] Remove unused import --- src/tools/snapshot.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tools/snapshot.ts b/src/tools/snapshot.ts index b6e745ab3..32cbefbab 100644 --- a/src/tools/snapshot.ts +++ b/src/tools/snapshot.ts @@ -6,7 +6,6 @@ import {zod} from '../third_party/modelcontextprotocol-sdk/index.js'; -import {Locator} from '../third_party/puppeteer-core/index.js'; import {ToolCategories} from './categories.js'; import {defineTool, timeoutSchema} from './ToolDefinition.js'; From 1fe3c81c1080384a2a3a083b7fd8d5b0760b4683 Mon Sep 17 00:00:00 2001 From: Piotr Paulski Date: Mon, 20 Oct 2025 14:38:46 +0000 Subject: [PATCH 04/10] Fix formatting --- rollup.config.mjs | 14 ++++++++++++-- src/McpContext.ts | 20 +++++++++++++++++--- src/third_party/puppeteer-core/index.ts | 2 +- src/tools/ToolDefinition.ts | 5 ++++- src/tools/emulation.ts | 1 - src/tools/snapshot.ts | 1 - 6 files changed, 34 insertions(+), 9 deletions(-) diff --git a/rollup.config.mjs b/rollup.config.mjs index 274a93c1b..50cc22586 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -29,7 +29,15 @@ import license from 'rollup-plugin-license'; const isProduction = process.env.NODE_ENV === 'production'; -const allowed_licenses = ['MIT', 'Apache 2.0', 'Apache-2.0', 'BSD-3-Clause', 'BSD-2-Clause', 'ISC', '0BSD']; +const allowed_licenses = [ + 'MIT', + 'Apache 2.0', + 'Apache-2.0', + 'BSD-3-Clause', + 'BSD-2-Clause', + 'ISC', + '0BSD', +]; /** @returns {import('rollup').RollupOptions} */ const bundleDependency = (wrapperIndexPath, extraOutputOptions = {}) => ({ @@ -96,5 +104,7 @@ const bundleDependency = (wrapperIndexPath, extraOutputOptions = {}) => ({ export default [ bundleDependency('./build/src/third_party/modelcontextprotocol-sdk/index.js'), - bundleDependency('./build/src/third_party/puppeteer-core/index.js', {inlineDynamicImports: true}), + bundleDependency('./build/src/third_party/puppeteer-core/index.js', { + inlineDynamicImports: true, + }), ]; diff --git a/src/McpContext.ts b/src/McpContext.ts index d5cae792e..2efaace00 100644 --- a/src/McpContext.ts +++ b/src/McpContext.ts @@ -94,7 +94,11 @@ export class McpContext implements Context { #locatorClass: typeof Locator; - private constructor(browser: Browser, logger: Debugger, locatorClass: typeof Locator) { + private constructor( + browser: Browser, + logger: Debugger, + locatorClass: typeof Locator, + ) { this.browser = browser; this.logger = logger; this.#locatorClass = locatorClass; @@ -126,7 +130,11 @@ export class McpContext implements Context { await this.#consoleCollector.init(); } - static async from(browser: Browser, logger: Debugger, locatorClass: typeof Locator = Locator) { + static async from( + browser: Browser, + logger: Debugger, + locatorClass: typeof Locator = Locator, + ) { const context = new McpContext(browser, logger, locatorClass); await context.#init(); return context; @@ -433,7 +441,13 @@ export class McpContext implements Context { return this.#networkCollector.getIdForResource(request); } - waitForTextOnPage({text, timeout}: {text: string, timeout?: number|undefined}): Promise { + waitForTextOnPage({ + text, + timeout, + }: { + text: string; + timeout?: number | undefined; + }): Promise { const page = this.getSelectedPage(); const frames = page.frames(); diff --git a/src/third_party/puppeteer-core/index.ts b/src/third_party/puppeteer-core/index.ts index 42718705a..e5e6ccae7 100644 --- a/src/third_party/puppeteer-core/index.ts +++ b/src/third_party/puppeteer-core/index.ts @@ -4,5 +4,5 @@ * SPDX-License-Identifier: Apache-2.0 */ -export {Locator,PredefinedNetworkConditions} from 'puppeteer-core'; +export {Locator, PredefinedNetworkConditions} from 'puppeteer-core'; export {default as puppeteer} from 'puppeteer-core'; diff --git a/src/tools/ToolDefinition.ts b/src/tools/ToolDefinition.ts index 6ff2dc73c..fc8529a04 100644 --- a/src/tools/ToolDefinition.ts +++ b/src/tools/ToolDefinition.ts @@ -93,7 +93,10 @@ export type Context = Readonly<{ filename: string, ): Promise<{filename: string}>; waitForEventsAfterAction(action: () => Promise): Promise; - waitForTextOnPage(params: {text: string, timeout?: number|undefined}): Promise; + waitForTextOnPage(params: { + text: string; + timeout?: number | undefined; + }): Promise; }>; export function defineTool( diff --git a/src/tools/emulation.ts b/src/tools/emulation.ts index fed24a00f..9287c00d6 100644 --- a/src/tools/emulation.ts +++ b/src/tools/emulation.ts @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - import {zod} from '../third_party/modelcontextprotocol-sdk/index.js'; import {PredefinedNetworkConditions} from '../third_party/puppeteer-core/index.js'; diff --git a/src/tools/snapshot.ts b/src/tools/snapshot.ts index 32cbefbab..0cf548b41 100644 --- a/src/tools/snapshot.ts +++ b/src/tools/snapshot.ts @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - import {zod} from '../third_party/modelcontextprotocol-sdk/index.js'; import {ToolCategories} from './categories.js'; From 5dc59863dafbb4c2f34500cbfd3a47824f50a047 Mon Sep 17 00:00:00 2001 From: Piotr Paulski Date: Mon, 20 Oct 2025 15:37:37 +0000 Subject: [PATCH 05/10] Export types from bundle again --- src/DevToolsConnectionAdapter.ts | 4 ++-- src/McpContext.ts | 10 +++++----- src/McpResponse.ts | 6 ++++-- src/PageCollector.ts | 2 +- src/WaitForHelper.ts | 2 +- src/browser.ts | 3 +-- src/formatters/networkFormatter.ts | 5 ++++- src/third_party/puppeteer-core/index.ts | 1 + src/tools/ToolDefinition.ts | 7 +++++-- src/tools/console.ts | 3 +-- src/tools/input.ts | 3 +-- src/tools/network.ts | 3 +-- src/tools/performance.ts | 3 +-- src/tools/screenshot.ts | 3 +-- src/tools/script.ts | 2 +- 15 files changed, 30 insertions(+), 27 deletions(-) diff --git a/src/DevToolsConnectionAdapter.ts b/src/DevToolsConnectionAdapter.ts index 814dc7f60..ec07d1a72 100644 --- a/src/DevToolsConnectionAdapter.ts +++ b/src/DevToolsConnectionAdapter.ts @@ -4,10 +4,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {type ConnectionTransport} from 'puppeteer-core'; - import {Connection} from '../node_modules/chrome-devtools-frontend/front_end/core/protocol_client/InspectorBackend.js'; +import {type ConnectionTransport} from './third_party/puppeteer-core/index.js'; + /** * Allows a puppeteer {@link ConnectionTransport} to act like a DevTools {@link Connection}. */ diff --git a/src/McpContext.ts b/src/McpContext.ts index 2efaace00..8fbb38c67 100644 --- a/src/McpContext.ts +++ b/src/McpContext.ts @@ -8,6 +8,10 @@ import os from 'node:os'; import path from 'node:path'; import type {Debugger} from 'debug'; + +import type {ListenerMap} from './PageCollector.js'; +import {NetworkCollector, PageCollector} from './PageCollector.js'; +import {Locator} from './third_party/puppeteer-core/index.js'; import type { Browser, ConsoleMessage, @@ -17,11 +21,7 @@ import type { Page, SerializedAXNode, PredefinedNetworkConditions, -} from 'puppeteer-core'; - -import type {ListenerMap} from './PageCollector.js'; -import {NetworkCollector, PageCollector} from './PageCollector.js'; -import {Locator} from './third_party/puppeteer-core/index.js'; +} from './third_party/puppeteer-core/index.js'; import {listPages} from './tools/pages.js'; import {takeSnapshot} from './tools/snapshot.js'; import {CLOSE_PAGE_ERROR} from './tools/ToolDefinition.js'; diff --git a/src/McpResponse.ts b/src/McpResponse.ts index 8a1b6dc94..31bbdcc5a 100644 --- a/src/McpResponse.ts +++ b/src/McpResponse.ts @@ -3,8 +3,6 @@ * Copyright 2025 Google LLC * SPDX-License-Identifier: Apache-2.0 */ -import type {ConsoleMessage, ResourceType} from 'puppeteer-core'; - import type {ConsoleMessageData} from './formatters/consoleFormatter.js'; import { formatConsoleEventShort, @@ -23,6 +21,10 @@ import type { ImageContent, TextContent, } from './third_party/modelcontextprotocol-sdk/index.js'; +import type { + ConsoleMessage, + ResourceType, +} from './third_party/puppeteer-core/index.js'; import {handleDialog} from './tools/pages.js'; import type {ImageContentData, Response} from './tools/ToolDefinition.js'; import {paginate} from './utils/pagination.js'; diff --git a/src/PageCollector.ts b/src/PageCollector.ts index b6b3d6798..44d1363f8 100644 --- a/src/PageCollector.ts +++ b/src/PageCollector.ts @@ -11,7 +11,7 @@ import { type HTTPRequest, type Page, type PageEvents, -} from 'puppeteer-core'; +} from './third_party/puppeteer-core/index.js'; export type ListenerMap = { [K in keyof EventMap]?: (event: EventMap[K]) => void; diff --git a/src/WaitForHelper.ts b/src/WaitForHelper.ts index 62cc83f03..a18f6448a 100644 --- a/src/WaitForHelper.ts +++ b/src/WaitForHelper.ts @@ -3,10 +3,10 @@ * Copyright 2025 Google LLC * SPDX-License-Identifier: Apache-2.0 */ -import type {Page, Protocol} from 'puppeteer-core'; import type {CdpPage} from 'puppeteer-core/internal/cdp/Page.js'; import {logger} from './logger.js'; +import type {Page, Protocol} from './third_party/puppeteer-core/index.js'; export class WaitForHelper { #abortController = new AbortController(); diff --git a/src/browser.ts b/src/browser.ts index f129ec76d..47afe5a93 100644 --- a/src/browser.ts +++ b/src/browser.ts @@ -13,8 +13,7 @@ import type { ChromeReleaseChannel, LaunchOptions, Target, -} from 'puppeteer-core'; - +} from './third_party/puppeteer-core/index.js'; import {puppeteer} from './third_party/puppeteer-core/index.js'; let browser: Browser | undefined; diff --git a/src/formatters/networkFormatter.ts b/src/formatters/networkFormatter.ts index 572797339..b3466e8c1 100644 --- a/src/formatters/networkFormatter.ts +++ b/src/formatters/networkFormatter.ts @@ -6,7 +6,10 @@ import {isUtf8} from 'node:buffer'; -import type {HTTPRequest, HTTPResponse} from 'puppeteer-core'; +import type { + HTTPRequest, + HTTPResponse, +} from '../third_party/puppeteer-core/index.js'; const BODY_CONTEXT_SIZE_LIMIT = 10000; diff --git a/src/third_party/puppeteer-core/index.ts b/src/third_party/puppeteer-core/index.ts index e5e6ccae7..92ae88ae7 100644 --- a/src/third_party/puppeteer-core/index.ts +++ b/src/third_party/puppeteer-core/index.ts @@ -6,3 +6,4 @@ export {Locator, PredefinedNetworkConditions} from 'puppeteer-core'; export {default as puppeteer} from 'puppeteer-core'; +export type * from 'puppeteer-core'; diff --git a/src/tools/ToolDefinition.ts b/src/tools/ToolDefinition.ts index fc8529a04..19415dd27 100644 --- a/src/tools/ToolDefinition.ts +++ b/src/tools/ToolDefinition.ts @@ -4,10 +4,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -import type {Dialog, ElementHandle, Page} from 'puppeteer-core'; - import type {TextSnapshotNode} from '../McpContext.js'; import {zod} from '../third_party/modelcontextprotocol-sdk/index.js'; +import type { + Dialog, + ElementHandle, + Page, +} from '../third_party/puppeteer-core/index.js'; import type {TraceResult} from '../trace-processing/parse.js'; import type {PaginationOptions} from '../utils/types.js'; diff --git a/src/tools/console.ts b/src/tools/console.ts index 3f8967eb9..8be953c89 100644 --- a/src/tools/console.ts +++ b/src/tools/console.ts @@ -4,9 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -import type {ConsoleMessageType} from 'puppeteer-core'; - import {zod} from '../third_party/modelcontextprotocol-sdk/index.js'; +import type {ConsoleMessageType} from '../third_party/puppeteer-core/index.js'; import {ToolCategories} from './categories.js'; import {defineTool} from './ToolDefinition.js'; diff --git a/src/tools/input.ts b/src/tools/input.ts index ffb1cbb7c..973eb829f 100644 --- a/src/tools/input.ts +++ b/src/tools/input.ts @@ -4,10 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -import type {ElementHandle} from 'puppeteer-core'; - import type {McpContext, TextSnapshotNode} from '../McpContext.js'; import {zod} from '../third_party/modelcontextprotocol-sdk/index.js'; +import type {ElementHandle} from '../third_party/puppeteer-core/index.js'; import {ToolCategories} from './categories.js'; import {defineTool} from './ToolDefinition.js'; diff --git a/src/tools/network.ts b/src/tools/network.ts index 0dbc7f7e7..d47fa9960 100644 --- a/src/tools/network.ts +++ b/src/tools/network.ts @@ -4,9 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -import type {ResourceType} from 'puppeteer-core'; - import {zod} from '../third_party/modelcontextprotocol-sdk/index.js'; +import type {ResourceType} from '../third_party/puppeteer-core/index.js'; import {ToolCategories} from './categories.js'; import {defineTool} from './ToolDefinition.js'; diff --git a/src/tools/performance.ts b/src/tools/performance.ts index 6c172fbb9..a76f30d5a 100644 --- a/src/tools/performance.ts +++ b/src/tools/performance.ts @@ -4,10 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -import type {Page} from 'puppeteer-core'; - import {logger} from '../logger.js'; import {zod} from '../third_party/modelcontextprotocol-sdk/index.js'; +import type {Page} from '../third_party/puppeteer-core/index.js'; import type {InsightName} from '../trace-processing/parse.js'; import { getInsightOutput, diff --git a/src/tools/screenshot.ts b/src/tools/screenshot.ts index 991fbd2b9..e053186f5 100644 --- a/src/tools/screenshot.ts +++ b/src/tools/screenshot.ts @@ -4,9 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -import type {ElementHandle, Page} from 'puppeteer-core'; - import {zod} from '../third_party/modelcontextprotocol-sdk/index.js'; +import type {ElementHandle, Page} from '../third_party/puppeteer-core/index.js'; import {ToolCategories} from './categories.js'; import {defineTool} from './ToolDefinition.js'; diff --git a/src/tools/script.ts b/src/tools/script.ts index 128363bdc..b32912ebe 100644 --- a/src/tools/script.ts +++ b/src/tools/script.ts @@ -3,9 +3,9 @@ * Copyright 2025 Google LLC * SPDX-License-Identifier: Apache-2.0 */ -import type {Frame, JSHandle, Page} from 'puppeteer-core'; import {zod} from '../third_party/modelcontextprotocol-sdk/index.js'; +import type {Frame, JSHandle, Page} from '../third_party/puppeteer-core/index.js'; import {ToolCategories} from './categories.js'; import {defineTool} from './ToolDefinition.js'; From 77ab97e8ccc3d59f6970259871643cf6e5122b62 Mon Sep 17 00:00:00 2001 From: Piotr Paulski Date: Mon, 20 Oct 2025 15:38:25 +0000 Subject: [PATCH 06/10] Cleanup deps, naming convention --- package.json | 1 - rollup.config.mjs | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 10e165f87..b0f02da38 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,6 @@ "dependencies": { "core-js": "3.46.0", "debug": "4.4.3", - "puppeteer-core": "^24.24.1", "yargs": "18.0.0" }, "devDependencies": { diff --git a/rollup.config.mjs b/rollup.config.mjs index 50cc22586..e014a8c9b 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -29,7 +29,7 @@ import license from 'rollup-plugin-license'; const isProduction = process.env.NODE_ENV === 'production'; -const allowed_licenses = [ +const allowedLicenses = [ 'MIT', 'Apache 2.0', 'Apache-2.0', @@ -59,7 +59,7 @@ const bundleDependency = (wrapperIndexPath, extraOutputOptions = {}) => ({ thirdParty: { allow: { test: dependency => { - return allowed_licenses.includes(dependency.license); + return allowedLicenses.includes(dependency.license); }, failOnUnlicensed: true, failOnViolation: true, From a9ecf8589038dcdbf468c0e2dd77f9ce4c36349d Mon Sep 17 00:00:00 2001 From: Piotr Paulski Date: Mon, 20 Oct 2025 15:46:11 +0000 Subject: [PATCH 07/10] Leave a descriptive comment on Locator workaround --- src/McpContext.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/McpContext.ts b/src/McpContext.ts index 8fbb38c67..4f7641d50 100644 --- a/src/McpContext.ts +++ b/src/McpContext.ts @@ -133,6 +133,7 @@ export class McpContext implements Context { static async from( browser: Browser, logger: Debugger, + /* Let tests use unbundled Locator class to avoid overly strict checks within puppeteer that fail when mixing bundled and unbundled class instances */ locatorClass: typeof Locator = Locator, ) { const context = new McpContext(browser, logger, locatorClass); From 42ecf65fa608d59b10614f3ddc25471fcfce2694 Mon Sep 17 00:00:00 2001 From: Piotr Paulski Date: Mon, 20 Oct 2025 16:52:03 +0000 Subject: [PATCH 08/10] Externalize bidi, fix THIRD_PARTY_NOTICES generation. --- rollup.config.mjs | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/rollup.config.mjs b/rollup.config.mjs index e014a8c9b..bacb28f8f 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -39,8 +39,17 @@ const allowedLicenses = [ '0BSD', ]; -/** @returns {import('rollup').RollupOptions} */ -const bundleDependency = (wrapperIndexPath, extraOutputOptions = {}) => ({ +/** + * @param {string} wrapperIndexPath + * @param {import('rollup').OutputOptions} [extraOutputOptions={}] + * @param {string[]} [external=[]] + * @returns {import('rollup').RollupOptions} + */ +const bundleDependency = ( + wrapperIndexPath, + extraOutputOptions = {}, + external = [] +) => ({ input: wrapperIndexPath, output: { ...extraOutputOptions, @@ -65,13 +74,7 @@ const bundleDependency = (wrapperIndexPath, extraOutputOptions = {}) => ({ failOnViolation: true, }, output: { - file: path.join( - 'build', - 'src', - 'third_party', - 'modelcontextprotocol-sdk', - 'THIRD_PARTY_NOTICES', - ), + file: path.join(path.dirname(wrapperIndexPath), 'THIRD_PARTY_NOTICES'), template(dependencies) { const stringified_dependencies = dependencies.map(dependency => { let arr = []; @@ -100,11 +103,16 @@ const bundleDependency = (wrapperIndexPath, extraOutputOptions = {}) => ({ json(), nodeResolve(), ], + external, }); export default [ bundleDependency('./build/src/third_party/modelcontextprotocol-sdk/index.js'), - bundleDependency('./build/src/third_party/puppeteer-core/index.js', { - inlineDynamicImports: true, - }), + bundleDependency( + './build/src/third_party/puppeteer-core/index.js', + { + inlineDynamicImports: true, + }, + ['./bidi.js', '../bidi/bidi.js'] + ), ]; From ac06ac466f06f574f116e62146952373bb1e04e0 Mon Sep 17 00:00:00 2001 From: Piotr Paulski Date: Mon, 20 Oct 2025 16:56:03 +0000 Subject: [PATCH 09/10] Fix prettier. --- rollup.config.mjs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/rollup.config.mjs b/rollup.config.mjs index bacb28f8f..9ca5ef30b 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -48,7 +48,7 @@ const allowedLicenses = [ const bundleDependency = ( wrapperIndexPath, extraOutputOptions = {}, - external = [] + external = [], ) => ({ input: wrapperIndexPath, output: { @@ -74,7 +74,10 @@ const bundleDependency = ( failOnViolation: true, }, output: { - file: path.join(path.dirname(wrapperIndexPath), 'THIRD_PARTY_NOTICES'), + file: path.join( + path.dirname(wrapperIndexPath), + 'THIRD_PARTY_NOTICES', + ), template(dependencies) { const stringified_dependencies = dependencies.map(dependency => { let arr = []; @@ -113,6 +116,6 @@ export default [ { inlineDynamicImports: true, }, - ['./bidi.js', '../bidi/bidi.js'] + ['./bidi.js', '../bidi/bidi.js'], ), ]; From 86518ac60c517b3fc67e067324273a2d2c9ecdfb Mon Sep 17 00:00:00 2001 From: Piotr Paulski Date: Tue, 21 Oct 2025 09:20:04 +0000 Subject: [PATCH 10/10] Fix prettier. --- src/tools/script.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tools/script.ts b/src/tools/script.ts index b32912ebe..6f08af08a 100644 --- a/src/tools/script.ts +++ b/src/tools/script.ts @@ -5,7 +5,11 @@ */ import {zod} from '../third_party/modelcontextprotocol-sdk/index.js'; -import type {Frame, JSHandle, Page} from '../third_party/puppeteer-core/index.js'; +import type { + Frame, + JSHandle, + Page, +} from '../third_party/puppeteer-core/index.js'; import {ToolCategories} from './categories.js'; import {defineTool} from './ToolDefinition.js';