diff --git a/src/puppeteer/README.md b/src/puppeteer/README.md index 4eab314c..50f8b82e 100644 --- a/src/puppeteer/README.md +++ b/src/puppeteer/README.md @@ -21,6 +21,14 @@ A Model Context Protocol server that provides browser automation capabilities us - `width` (number, optional, default: 800): Screenshot width - `height` (number, optional, default: 600): Screenshot height +- **puppeteer_screenshot_encoded** + - Captures a screenshot of the entire page or a specific element and return it as a base64-encoded data URI. + - Inputs: + - `name` (string, required): Name for the screenshot + - `selector` (string, optional): CSS selector for element to screenshot + - `width` (number, optional, default: 800): Screenshot width + - `height` (number, optional, default: 600): Screenshot height + - **puppeteer_click** - Click elements on the page - Input: `selector` (string): CSS selector for element to click diff --git a/src/puppeteer/index.ts b/src/puppeteer/index.ts index 1849c783..feabec70 100644 --- a/src/puppeteer/index.ts +++ b/src/puppeteer/index.ts @@ -43,6 +43,20 @@ const TOOLS: Tool[] = [ required: ["name"], }, }, + { + name: "puppeteer_screenshot_encoded", + description: "Take a screenshot of the current page or a specific element and return it as a base64-encoded data URI", + inputSchema: { + type: "object", + properties: { + name: { type: "string", description: "Name for the screenshot" }, + selector: { type: "string", description: "CSS selector for element to screenshot" }, + width: { type: "number", description: "Width in pixels (default: 800)" }, + height: { type: "number", description: "Height in pixels (default: 600)" }, + }, + required: ["name"], + }, + }, { name: "puppeteer_click", description: "Click an element on the page", @@ -265,6 +279,47 @@ async function handleToolCall(name: string, args: any): Promise }; } + case "puppeteer_screenshot_encoded": { + const width = args.width ?? 800; + const height = args.height ?? 600; + await page.setViewport({ width, height }); + + const screenshot = await (args.selector + ? (await page.$(args.selector))?.screenshot({ encoding: "base64" }) + : page.screenshot({ encoding: "base64", fullPage: false })); + + if (!screenshot) { + return { + content: [ + { + type: "text", + text: args.selector ? `Element not found: ${args.selector}` : "Screenshot failed", + }, + ], + isError: true, + }; + } + + screenshots.set(args.name, screenshot as string); + server.notification({ + method: "notifications/resources/list_changed", + }); + + return { + content: [ + { + type: "text", + text: `Screenshot '${args.name}' taken at ${width}x${height}`, + } as TextContent, + { + type: "text", + text: `data:image/png;base64,${screenshot}`, + } as TextContent, + ], + isError: false, + }; + } + case "puppeteer_click": try { await page.click(args.selector);