Skip to content
Closed
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
108 changes: 107 additions & 1 deletion src/tools/ToolDefinition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import type {Dialog, ElementHandle, Page} from 'puppeteer-core';
import type {ConsoleMessageType, Dialog, ElementHandle, Page, ResourceType} from 'puppeteer-core';

import type {TextSnapshotNode} from '../McpContext.js';
import {zod} from '../third_party/modelcontextprotocol-sdk/index.js';
Expand Down Expand Up @@ -115,3 +115,109 @@ export const timeoutSchema = {
return value && value <= 0 ? undefined : value;
}),
};

export const snapshotSchema = {
verbose: zod
.boolean()
.optional()
.describe(
'Whether to include all possible information available in the full a11y tree. Default is false.',
),
};

const FILTERABLE_MESSAGE_TYPES: readonly [
ConsoleMessageType,
...ConsoleMessageType[],
] = [
'log',
'debug',
'info',
'error',
'warn',
'dir',
'dirxml',
'table',
'trace',
'clear',
'startGroup',
'startGroupCollapsed',
'endGroup',
'assert',
'profile',
'profileEnd',
'count',
'timeEnd',
'verbose',
]

export const consoleMessagesSchema = {
pageSize: zod
.number()
.int()
.positive()
.optional()
.describe(
'Maximum number of messages to return. When omitted, returns all requests.',
),
pageIdx: zod
.number()
.int()
.min(0)
.optional()
.describe(
'Page number to return (0-based). When omitted, returns the first page.',
),
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.',
),
};

const FILTERABLE_RESOURCE_TYPES: readonly [ResourceType, ...ResourceType[]] = [
'document',
'stylesheet',
'image',
'media',
'font',
'script',
'texttrack',
'xhr',
'fetch',
'prefetch',
'eventsource',
'websocket',
'manifest',
'signedexchange',
'ping',
'cspviolationreport',
'preflight',
'fedcm',
'other',
];

export const networkRequestsSchema = {
pageSize: zod
.number()
.int()
.positive()
.optional()
.describe(
'Maximum number of requests to return. When omitted, returns all requests.',
),
pageIdx: zod
.number()
.int()
.min(0)
.optional()
.describe(
'Page number to return (0-based). When omitted, returns the first page.',
),
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.',
),
}
54 changes: 2 additions & 52 deletions src/tools/console.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,8 @@
* SPDX-License-Identifier: Apache-2.0
*/

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

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

import {ToolCategories} from './categories.js';
import {defineTool} from './ToolDefinition.js';

const FILTERABLE_MESSAGE_TYPES: readonly [
ConsoleMessageType,
...ConsoleMessageType[],
] = [
'log',
'debug',
'info',
'error',
'warn',
'dir',
'dirxml',
'table',
'trace',
'clear',
'startGroup',
'startGroupCollapsed',
'endGroup',
'assert',
'profile',
'profileEnd',
'count',
'timeEnd',
'verbose',
];
import {consoleMessagesSchema, defineTool} from './ToolDefinition.js';

export const consoleTool = defineTool({
name: 'list_console_messages',
Expand All @@ -45,28 +16,7 @@ export const consoleTool = defineTool({
readOnlyHint: true,
},
schema: {
pageSize: zod
.number()
.int()
.positive()
.optional()
.describe(
'Maximum number of messages to return. When omitted, returns all requests.',
),
pageIdx: zod
.number()
.int()
.min(0)
.optional()
.describe(
'Page number to return (0-based). When omitted, returns the first page.',
),
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.',
),
...consoleMessagesSchema,
},
handler: async (request, response) => {
response.setIncludeConsoleData(true, {
Expand Down
32 changes: 25 additions & 7 deletions src/tools/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ 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';
import {defineTool, snapshotSchema} from './ToolDefinition.js';

export const click = defineTool({
name: 'click',
Expand All @@ -29,6 +29,9 @@ export const click = defineTool({
.boolean()
.optional()
.describe('Set to true for double clicks. Default is false.'),
snapshot: zod.object({
...snapshotSchema,
}).optional().describe('Options for the snapshot included in the response'),
},
handler: async (request, response, context) => {
const uid = request.params.uid;
Expand All @@ -44,7 +47,7 @@ export const click = defineTool({
? `Successfully double clicked on the element`
: `Successfully clicked on the element`,
);
response.setIncludeSnapshot(true);
response.setIncludeSnapshot(true, request.params.snapshot?.verbose ?? false);
} finally {
void handle.dispose();
}
Expand All @@ -64,6 +67,9 @@ export const hover = defineTool({
.describe(
'The uid of an element on the page from the page content snapshot',
),
snapshot: zod.object({
...snapshotSchema,
}).optional().describe('Options for the snapshot included in the response'),
},
handler: async (request, response, context) => {
const uid = request.params.uid;
Expand All @@ -73,7 +79,7 @@ export const hover = defineTool({
await handle.asLocator().hover();
});
response.appendResponseLine(`Successfully hovered over the element`);
response.setIncludeSnapshot(true);
response.setIncludeSnapshot(true, request.params.snapshot?.verbose ?? false);
} finally {
void handle.dispose();
}
Expand Down Expand Up @@ -149,6 +155,9 @@ export const fill = defineTool({
'The uid of an element on the page from the page content snapshot',
),
value: zod.string().describe('The value to fill in'),
snapshot: zod.object({
...snapshotSchema,
}).optional().describe('Options for the snapshot included in the response'),
},
handler: async (request, response, context) => {
await context.waitForEventsAfterAction(async () => {
Expand All @@ -159,7 +168,7 @@ export const fill = defineTool({
);
});
response.appendResponseLine(`Successfully filled out the element`);
response.setIncludeSnapshot(true);
response.setIncludeSnapshot(true, request.params.snapshot?.verbose ?? false);
},
});

Expand All @@ -173,6 +182,9 @@ export const drag = defineTool({
schema: {
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'),
snapshot: zod.object({
...snapshotSchema,
}).optional().describe('Options for the snapshot included in the response'),
},
handler: async (request, response, context) => {
const fromHandle = await context.getElementByUid(request.params.from_uid);
Expand All @@ -184,7 +196,7 @@ export const drag = defineTool({
await toHandle.drop(fromHandle);
});
response.appendResponseLine(`Successfully dragged an element`);
response.setIncludeSnapshot(true);
response.setIncludeSnapshot(true, request.params.snapshot?.verbose ?? false);
} finally {
void fromHandle.dispose();
void toHandle.dispose();
Expand All @@ -208,6 +220,9 @@ export const fillForm = defineTool({
}),
)
.describe('Elements from snapshot to fill out.'),
snapshot: zod.object({
...snapshotSchema,
}).optional().describe('Options for the snapshot included in the response'),
},
handler: async (request, response, context) => {
for (const element of request.params.elements) {
Expand All @@ -220,7 +235,7 @@ export const fillForm = defineTool({
});
}
response.appendResponseLine(`Successfully filled out the form`);
response.setIncludeSnapshot(true);
response.setIncludeSnapshot(true, request.params.snapshot?.verbose ?? false);
},
});

Expand All @@ -238,6 +253,9 @@ export const uploadFile = defineTool({
'The uid of the file input element or an element that will open file chooser on the page from the page content snapshot',
),
filePath: zod.string().describe('The local path of the file to upload'),
snapshot: zod.object({
...snapshotSchema,
}).optional().describe('Options for the snapshot included in the response'),
},
handler: async (request, response, context) => {
const {uid, filePath} = request.params;
Expand All @@ -264,7 +282,7 @@ export const uploadFile = defineTool({
);
}
}
response.setIncludeSnapshot(true);
response.setIncludeSnapshot(true, request.params.snapshot?.verbose ?? false);
response.appendResponseLine(`File uploaded from ${filePath}.`);
} finally {
void handle.dispose();
Expand Down
49 changes: 2 additions & 47 deletions src/tools/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,10 @@
* SPDX-License-Identifier: Apache-2.0
*/

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

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

import {ToolCategories} from './categories.js';
import {defineTool} from './ToolDefinition.js';

const FILTERABLE_RESOURCE_TYPES: readonly [ResourceType, ...ResourceType[]] = [
'document',
'stylesheet',
'image',
'media',
'font',
'script',
'texttrack',
'xhr',
'fetch',
'prefetch',
'eventsource',
'websocket',
'manifest',
'signedexchange',
'ping',
'cspviolationreport',
'preflight',
'fedcm',
'other',
];
import {defineTool, networkRequestsSchema} from './ToolDefinition.js';

export const listNetworkRequests = defineTool({
name: 'list_network_requests',
Expand All @@ -41,28 +17,7 @@ export const listNetworkRequests = defineTool({
readOnlyHint: true,
},
schema: {
pageSize: zod
.number()
.int()
.positive()
.optional()
.describe(
'Maximum number of requests to return. When omitted, returns all requests.',
),
pageIdx: zod
.number()
.int()
.min(0)
.optional()
.describe(
'Page number to return (0-based). When omitted, returns the first page.',
),
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.',
),
...networkRequestsSchema,
},
handler: async (request, response) => {
response.setIncludeNetworkRequests(true, {
Expand Down
Loading