Files
mcp_web_dev_server/src/tools/browser/baseline.ts
T
2026-07-31 13:12:54 -04:00

54 lines
2.0 KiB
TypeScript

import { z } from 'zod';
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { writeBaseline, listBaselines } from '../../lib/baselines.js';
import { errorResult, jsonResult, toErrorMessage } from '../shared.js';
import { browserManager } from './browserManager.js';
export function registerBrowserScreenshotBaselineTool(server: McpServer): void {
server.registerTool(
'browser_screenshot_baseline',
{
title: 'Save Screenshot Baseline',
description:
'Capture the current page (or a CSS selector) and save it as a PNG baseline under `.web-dev-mcp/baselines/{name}.png` for later visual diffs.',
inputSchema: {
name: z
.string()
.min(1)
.describe('Baseline name (no path separators), e.g. "home" or "login-form".'),
selector: z.string().optional().describe('Optional CSS selector; if omitted, captures the page.'),
fullPage: z
.boolean()
.optional()
.default(false)
.describe('Capture the full scrollable page when selector is omitted.'),
},
},
async ({ name, selector, fullPage }) => {
try {
const session = await browserManager.getSession();
let buffer: Buffer;
if (selector) {
const element = await session.page.locator(selector).first();
await element.waitFor({ state: 'visible', timeout: 5000 });
buffer = await element.screenshot({ type: 'png' });
} else {
buffer = await session.page.screenshot({ fullPage, type: 'png' });
}
const saved = writeBaseline(name, buffer);
return jsonResult({
name,
selector: selector ?? null,
fullPage: selector ? false : fullPage,
sizeBytes: buffer.length,
relativePath: saved.relativePath,
baselines: listBaselines(),
});
} catch (error) {
return errorResult(toErrorMessage(error));
}
},
);
}