Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@
"core-js": "3.46.0",
"debug": "4.4.3",
"puppeteer-core": "^24.24.1",
"yargs": "18.0.0",
"zod": "^3.25.76"
"yargs": "18.0.0"
},
"devDependencies": {
"@eslint/js": "^9.35.0",
Expand Down
1 change: 1 addition & 0 deletions src/third_party/modelcontextprotocol-sdk/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ export {
type ImageContent,
type TextContent,
} from '@modelcontextprotocol/sdk/types.js';
export {z as zod} from 'zod';
14 changes: 8 additions & 6 deletions src/tools/ToolDefinition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@
*/

import type {Dialog, ElementHandle, Page} from 'puppeteer-core';
import z from 'zod';

import type {TextSnapshotNode} from '../McpContext.js';
import {zod} from '../third_party/modelcontextprotocol-sdk/index.js';
import type {TraceResult} from '../trace-processing/parse.js';
import type {PaginationOptions} from '../utils/types.js';

import type {ToolCategories} from './categories.js';

export interface ToolDefinition<Schema extends z.ZodRawShape = z.ZodRawShape> {
export interface ToolDefinition<
Schema extends zod.ZodRawShape = zod.ZodRawShape,
> {
name: string;
description: string;
annotations: {
Expand All @@ -32,8 +34,8 @@ export interface ToolDefinition<Schema extends z.ZodRawShape = z.ZodRawShape> {
) => Promise<void>;
}

export interface Request<Schema extends z.ZodRawShape> {
params: z.objectOutputType<Schema, z.ZodTypeAny>;
export interface Request<Schema extends zod.ZodRawShape> {
params: zod.objectOutputType<Schema, zod.ZodTypeAny>;
}

export interface ImageContentData {
Expand Down Expand Up @@ -92,7 +94,7 @@ export type Context = Readonly<{
waitForEventsAfterAction(action: () => Promise<unknown>): Promise<void>;
}>;

export function defineTool<Schema extends z.ZodRawShape>(
export function defineTool<Schema extends zod.ZodRawShape>(
definition: ToolDefinition<Schema>,
) {
return definition;
Expand All @@ -102,7 +104,7 @@ export const CLOSE_PAGE_ERROR =
'The last open page cannot be closed. It is fine to keep it open.';

export const timeoutSchema = {
timeout: z
timeout: zod
.number()
.int()
.optional()
Expand Down
11 changes: 6 additions & 5 deletions src/tools/console.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
*/

import type {ConsoleMessageType} from 'puppeteer-core';
import z from 'zod';

import {zod} from '../third_party/modelcontextprotocol-sdk/index.js';

import {ToolCategories} from './categories.js';
import {defineTool} from './ToolDefinition.js';
Expand Down Expand Up @@ -44,24 +45,24 @@ export const consoleTool = defineTool({
readOnlyHint: true,
},
schema: {
pageSize: z
pageSize: zod
.number()
.int()
.positive()
.optional()
.describe(
'Maximum number of messages to return. When omitted, returns all requests.',
),
pageIdx: z
pageIdx: zod
.number()
.int()
.min(0)
.optional()
.describe(
'Page number to return (0-based). When omitted, returns the first page.',
),
types: z
.array(z.enum(FILTERABLE_MESSAGE_TYPES))
types: zod
.array(zod.enum(FILTERABLE_MESSAGE_TYPES))
.optional()
.describe(
'Filter messages to only return messages of the specified resource types. When omitted or empty, returns all messages.',
Expand Down
7 changes: 4 additions & 3 deletions src/tools/emulation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
*/

import {PredefinedNetworkConditions} from 'puppeteer-core';
import z from 'zod';

import {zod} from '../third_party/modelcontextprotocol-sdk/index.js';

import {ToolCategories} from './categories.js';
import {defineTool} from './ToolDefinition.js';
Expand All @@ -24,7 +25,7 @@ export const emulateNetwork = defineTool({
readOnlyHint: false,
},
schema: {
throttlingOption: z
throttlingOption: zod
.enum(throttlingOptions)
.describe(
`The network throttling option to emulate. Available throttling options are: ${throttlingOptions.join(', ')}. Set to "No emulation" to disable. Set to "Offline" to simulate offline network conditions.`,
Expand Down Expand Up @@ -70,7 +71,7 @@ export const emulateCpu = defineTool({
readOnlyHint: false,
},
schema: {
throttlingRate: z
throttlingRate: zod
.number()
.min(1)
.max(20)
Expand Down
28 changes: 14 additions & 14 deletions src/tools/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
*/

import type {ElementHandle} from 'puppeteer-core';
import z from 'zod';

import type {McpContext, TextSnapshotNode} from '../McpContext.js';
import {zod} from '../third_party/modelcontextprotocol-sdk/index.js';

import {ToolCategories} from './categories.js';
import {defineTool} from './ToolDefinition.js';
Expand All @@ -20,12 +20,12 @@ export const click = defineTool({
readOnlyHint: false,
},
schema: {
uid: z
uid: zod
.string()
.describe(
'The uid of an element on the page from the page content snapshot',
),
dblClick: z
dblClick: zod
.boolean()
.optional()
.describe('Set to true for double clicks. Default is false.'),
Expand Down Expand Up @@ -59,7 +59,7 @@ export const hover = defineTool({
readOnlyHint: false,
},
schema: {
uid: z
uid: zod
.string()
.describe(
'The uid of an element on the page from the page content snapshot',
Expand Down Expand Up @@ -143,12 +143,12 @@ export const fill = defineTool({
readOnlyHint: false,
},
schema: {
uid: z
uid: zod
.string()
.describe(
'The uid of an element on the page from the page content snapshot',
),
value: z.string().describe('The value to fill in'),
value: zod.string().describe('The value to fill in'),
},
handler: async (request, response, context) => {
await context.waitForEventsAfterAction(async () => {
Expand All @@ -171,8 +171,8 @@ export const drag = defineTool({
readOnlyHint: false,
},
schema: {
from_uid: z.string().describe('The uid of the element to drag'),
to_uid: z.string().describe('The uid of the element to drop into'),
from_uid: zod.string().describe('The uid of the element to drag'),
to_uid: zod.string().describe('The uid of the element to drop into'),
},
handler: async (request, response, context) => {
const fromHandle = await context.getElementByUid(request.params.from_uid);
Expand Down Expand Up @@ -200,11 +200,11 @@ export const fillForm = defineTool({
readOnlyHint: false,
},
schema: {
elements: z
elements: zod
.array(
z.object({
uid: z.string().describe('The uid of the element to fill out'),
value: z.string().describe('Value for the element'),
zod.object({
uid: zod.string().describe('The uid of the element to fill out'),
value: zod.string().describe('Value for the element'),
}),
)
.describe('Elements from snapshot to fill out.'),
Expand Down Expand Up @@ -232,12 +232,12 @@ export const uploadFile = defineTool({
readOnlyHint: false,
},
schema: {
uid: z
uid: zod
.string()
.describe(
'The uid of the file input element or an element that will open file chooser on the page from the page content snapshot',
),
filePath: z.string().describe('The local path of the file to upload'),
filePath: zod.string().describe('The local path of the file to upload'),
},
handler: async (request, response, context) => {
const {uid, filePath} = request.params;
Expand Down
13 changes: 7 additions & 6 deletions src/tools/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
*/

import type {ResourceType} from 'puppeteer-core';
import z from 'zod';

import {zod} from '../third_party/modelcontextprotocol-sdk/index.js';

import {ToolCategories} from './categories.js';
import {defineTool} from './ToolDefinition.js';
Expand Down Expand Up @@ -40,24 +41,24 @@ export const listNetworkRequests = defineTool({
readOnlyHint: true,
},
schema: {
pageSize: z
pageSize: zod
.number()
.int()
.positive()
.optional()
.describe(
'Maximum number of requests to return. When omitted, returns all requests.',
),
pageIdx: z
pageIdx: zod
.number()
.int()
.min(0)
.optional()
.describe(
'Page number to return (0-based). When omitted, returns the first page.',
),
resourceTypes: z
.array(z.enum(FILTERABLE_RESOURCE_TYPES))
resourceTypes: zod
.array(zod.enum(FILTERABLE_RESOURCE_TYPES))
.optional()
.describe(
'Filter requests to only return requests of the specified resource types. When omitted or empty, returns all requests.',
Expand All @@ -80,7 +81,7 @@ export const getNetworkRequest = defineTool({
readOnlyHint: true,
},
schema: {
reqid: z
reqid: zod
.number()
.describe(
'The reqid of a request on the page from the listed network requests',
Expand Down
21 changes: 10 additions & 11 deletions src/tools/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
* SPDX-License-Identifier: Apache-2.0
*/

import z from 'zod';

import {logger} from '../logger.js';
import {zod} from '../third_party/modelcontextprotocol-sdk/index.js';

import {ToolCategories} from './categories.js';
import {CLOSE_PAGE_ERROR, defineTool, timeoutSchema} from './ToolDefinition.js';
Expand All @@ -32,7 +31,7 @@ export const selectPage = defineTool({
readOnlyHint: true,
},
schema: {
pageIdx: z
pageIdx: zod
.number()
.describe(
'The index of the page to select. Call list_pages to list pages.',
Expand All @@ -54,7 +53,7 @@ export const closePage = defineTool({
readOnlyHint: false,
},
schema: {
pageIdx: z
pageIdx: zod
.number()
.describe(
'The index of the page to close. Call list_pages to list pages.',
Expand Down Expand Up @@ -82,7 +81,7 @@ export const newPage = defineTool({
readOnlyHint: false,
},
schema: {
url: z.string().describe('URL to load in a new page.'),
url: zod.string().describe('URL to load in a new page.'),
...timeoutSchema,
},
handler: async (request, response, context) => {
Expand All @@ -106,7 +105,7 @@ export const navigatePage = defineTool({
readOnlyHint: false,
},
schema: {
url: z.string().describe('URL to navigate the page to'),
url: zod.string().describe('URL to navigate the page to'),
...timeoutSchema,
},
handler: async (request, response, context) => {
Expand All @@ -130,7 +129,7 @@ export const navigatePageHistory = defineTool({
readOnlyHint: false,
},
schema: {
navigate: z
navigate: zod
.enum(['back', 'forward'])
.describe(
'Whether to navigate back or navigate forward in the selected pages history',
Expand Down Expand Up @@ -167,8 +166,8 @@ export const resizePage = defineTool({
readOnlyHint: false,
},
schema: {
width: z.number().describe('Page width'),
height: z.number().describe('Page height'),
width: zod.number().describe('Page width'),
height: zod.number().describe('Page height'),
},
handler: async (request, response, context) => {
const page = context.getSelectedPage();
Expand All @@ -191,10 +190,10 @@ export const handleDialog = defineTool({
readOnlyHint: false,
},
schema: {
action: z
action: zod
.enum(['accept', 'dismiss'])
.describe('Whether to dismiss or accept the dialog'),
promptText: z
promptText: zod
.string()
.optional()
.describe('Optional prompt text to enter into the dialog.'),
Expand Down
8 changes: 4 additions & 4 deletions src/tools/performance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
*/

import type {Page} from 'puppeteer-core';
import z from 'zod';

import {logger} from '../logger.js';
import {zod} from '../third_party/modelcontextprotocol-sdk/index.js';
import type {InsightName} from '../trace-processing/parse.js';
import {
getInsightOutput,
Expand All @@ -29,12 +29,12 @@ export const startTrace = defineTool({
readOnlyHint: true,
},
schema: {
reload: z
reload: zod
.boolean()
.describe(
'Determines if, once tracing has started, the page should be automatically reloaded.',
),
autoStop: z
autoStop: zod
.boolean()
.describe(
'Determines if the trace recording should be automatically stopped.',
Expand Down Expand Up @@ -128,7 +128,7 @@ export const analyzeInsight = defineTool({
readOnlyHint: true,
},
schema: {
insightName: z
insightName: zod
.string()
.describe(
'The name of the Insight you want more information on. For example: "DocumentLatency" or "LCPBreakdown"',
Expand Down
Loading