Skip to main content
Glama

browserbase_screenshot

Capture full-page screenshots of websites for documentation, testing, or analysis purposes. This tool saves screenshots as resources for later reference.

Instructions

Capture a full-page screenshot and return it (and save as a resource).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
nameNoThe name of the screenshot

Implementation Reference

  • The core handler function `handleScreenshot` for the `browserbase_screenshot` tool. Captures a full-page screenshot of the active page using Chrome DevTools Protocol's Page.captureScreenshot, resizes the PNG image using Sharp if it exceeds Claude's vision API limits (1568px edge, 1.15MP), generates a timestamped name, registers the base64 image as an MCP resource via `registerScreenshot`, notifies the server of resource changes, and returns a ToolResult with text and image content.
    async function handleScreenshot( context: Context, params: ScreenshotInput, ): Promise<ToolResult> { const action = async (): Promise<ToolActionResult> => { try { const stagehand = await context.getStagehand(); const page = stagehand.context.pages()[0]; if (!page) { throw new Error("No active page available"); } // We're taking a full page screenshot to give context of the entire page, similar to a snapshot // Enable Page domain if needed await page.sendCDP("Page.enable"); // Use CDP to capture screenshot const { data } = await page.sendCDP<{ data: string }>( "Page.captureScreenshot", { format: "png", fromSurface: true, }, ); // data is already base64 string from CDP let screenshotBase64 = data; // Scale down image if needed for Claude's vision API // Claude constraints: max 1568px on any edge AND max 1.15 megapixels // Reference: https://docs.anthropic.com/en/docs/build-with-claude/vision#evaluate-image-size const imageBuffer = Buffer.from(data, "base64"); const metadata = await sharp(imageBuffer).metadata(); if (metadata.width && metadata.height) { const pixels = metadata.width * metadata.height; // Min of: width constraint, height constraint, and megapixel constraint const shrink = Math.min( 1568 / metadata.width, 1568 / metadata.height, Math.sqrt((1.15 * 1024 * 1024) / pixels), ); // Only resize if we need to shrink (shrink < 1) if (shrink < 1) { const newWidth = Math.floor(metadata.width * shrink); const newHeight = Math.floor(metadata.height * shrink); process.stderr.write( `[Screenshot] Scaling image from ${metadata.width}x${metadata.height} (${(pixels / (1024 * 1024)).toFixed(2)}MP) to ${newWidth}x${newHeight} (${((newWidth * newHeight) / (1024 * 1024)).toFixed(2)}MP) for Claude vision API\n`, ); const resizedBuffer = await sharp(imageBuffer) .resize(newWidth, newHeight, { fit: "inside", withoutEnlargement: true, }) .png() .toBuffer(); screenshotBase64 = resizedBuffer.toString("base64"); } } const name = params.name ? `screenshot-${params.name}-${new Date() .toISOString() .replace(/:/g, "-")}` : `screenshot-${new Date().toISOString().replace(/:/g, "-")}` + context.config.browserbaseProjectId; // Associate with current mcp session id and store in memory /src/mcp/resources.ts const sessionId = context.currentSessionId; registerScreenshot(sessionId, name, screenshotBase64); // Notify the client that the resources changed const serverInstance = context.getServer(); if (serverInstance) { serverInstance.notification({ method: "notifications/resources/list_changed", }); } return { content: [ { type: "text", text: `Screenshot taken with name: ${name}`, }, { type: "image", data: screenshotBase64, mimeType: "image/png", }, ], }; } catch (error) { const errorMsg = error instanceof Error ? error.message : String(error); throw new Error(`Failed to take screenshot: ${errorMsg}`); } }; return { action, waitForNetwork: false, }; }
  • Defines the input schema `ScreenshotInputSchema` (optional `name` string) using Zod and the `screenshotSchema` ToolSchema object with name `"browserbase_screenshot"`, description, and inputSchema.
    const ScreenshotInputSchema = z.object({ name: z.string().optional().describe("The name of the screenshot"), }); type ScreenshotInput = z.infer<typeof ScreenshotInputSchema>; const screenshotSchema: ToolSchema<typeof ScreenshotInputSchema> = { name: "browserbase_screenshot", description: `Capture a full-page screenshot and return it (and save as a resource).`, inputSchema: ScreenshotInputSchema, };
  • Creates and exports the `screenshotTool` Tool object, combining the `screenshotSchema` and `handleScreenshot` function for use in the tools index.
    const screenshotTool: Tool<typeof ScreenshotInputSchema> = { capability: "core", schema: screenshotSchema, handle: handleScreenshot, }; export default screenshotTool;
  • Includes `screenshotTool` in the `TOOLS` array (imported at line 5), which is consumed by the MCP server to register all tools.
    export const TOOLS = [ ...sessionTools, navigateTool, actTool, extractTool, observeTool, screenshotTool, getUrlTool, agentTool, ];
  • src/index.ts:168-198 (registration)
    Registers all tools from `TOOLS` (including `browserbase_screenshot`) with the MCP server using `server.tool()`, providing a wrapper handler that invokes `context.run(tool, params)`.
    const tools: MCPToolsArray = [...TOOLS]; // Register each tool with the Smithery server tools.forEach((tool) => { if (tool.schema.inputSchema instanceof z.ZodObject) { server.tool( tool.schema.name, tool.schema.description, tool.schema.inputSchema.shape, async (params: z.infer<typeof tool.schema.inputSchema>) => { try { const result = await context.run(tool, params); return result; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); process.stderr.write( `[Smithery Error] ${new Date().toISOString()} Error running tool ${tool.schema.name}: ${errorMessage}\n`, ); throw new Error( `Failed to run tool '${tool.schema.name}': ${errorMessage}`, ); } }, ); } else { console.warn( `Tool "${tool.schema.name}" has an input schema that is not a ZodObject. Schema type: ${tool.schema.inputSchema.constructor.name}`, ); } });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/MesuterPikin/mcp-server-browserbase'

If you have feedback or need assistance with the MCP directory API, please join our Discord server