take_screenshot
Capture a screenshot of the current webpage using the MCP Web Research Server, enabling quick visual documentation for research and analysis tasks.
Instructions
Take a screenshot of the current page
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- index.ts:1056-1113 (handler)Main handler for executing the 'take_screenshot' tool. Captures screenshot of current page, optimizes and saves it, stores in research session as a resource, notifies clients, and returns resource URI.case "take_screenshot": { try { // Step 1: Capture screenshot with retry mechanism const screenshot = await withRetry(async () => { // Take and optimize screenshot with default size limits return await takeScreenshotWithSizeLimit(page); }); // Step 2: Initialize session if needed if (!currentSession) { currentSession = { query: "Screenshot Session", // Session identifier results: [], // Empty results array lastUpdated: new Date().toISOString(), // Current timestamp }; } // Step 3: Get current page information const pageUrl = await page.url(); // Current page URL const pageTitle = await page.title(); // Current page title // Step 4: Save screenshot to disk const screenshotPath = await saveScreenshot(screenshot, pageTitle || 'untitled'); // Step 5: Create and store screenshot result const resultIndex = currentSession ? currentSession.results.length : 0; addResult({ url: pageUrl, title: pageTitle || "Untitled Page", // Fallback title if none available content: "Screenshot taken", // Simple content description timestamp: new Date().toISOString(), // Capture time screenshotPath // Path to screenshot file }); // Step 6: Notify clients about new screenshot resource server.notification({ method: "notifications/resources/list_changed" }); // Step 7: Return success message with resource URI const resourceUri = `research://screenshots/${resultIndex}`; return { content: [{ type: "text" as const, text: `Screenshot taken successfully. You can view it via *MCP Resources* (Paperclip icon) @ URI: ${resourceUri}` }] }; } catch (error) { // Handle and format screenshot errors return { content: [{ type: "text" as const, text: `Failed to take screenshot: ${(error as Error).message}` }], isError: true }; } }
- index.ts:479-562 (helper)Core helper function that captures the screenshot using Playwright page.screenshot(), automatically resizing the viewport to ensure the image is under 5MB, and returns base64-encoded PNG data.async function takeScreenshotWithSizeLimit(page: Page): Promise<string> { const MAX_SIZE = 5 * 1024 * 1024; const MAX_DIMENSION = 1920; const MIN_DIMENSION = 800; // Set viewport size await page.setViewportSize({ width: 1600, height: 900 }); // Take initial screenshot let screenshot = await page.screenshot({ type: 'png', fullPage: false }); // Handle buffer conversion let buffer = screenshot; let attempts = 0; const MAX_ATTEMPTS = 3; // While screenshot is too large, reduce size while (buffer.length > MAX_SIZE && attempts < MAX_ATTEMPTS) { // Get current viewport size const viewport = page.viewportSize(); if (!viewport) continue; // Calculate new dimensions const scaleFactor = Math.pow(0.75, attempts + 1); let newWidth = Math.round(viewport.width * scaleFactor); let newHeight = Math.round(viewport.height * scaleFactor); // Ensure dimensions are within bounds newWidth = Math.max(MIN_DIMENSION, Math.min(MAX_DIMENSION, newWidth)); newHeight = Math.max(MIN_DIMENSION, Math.min(MAX_DIMENSION, newHeight)); // Update viewport with new dimensions await page.setViewportSize({ width: newWidth, height: newHeight }); // Take new screenshot screenshot = await page.screenshot({ type: 'png', fullPage: false }); // Update buffer with new screenshot buffer = screenshot; // Increment retry attempts attempts++; } // Final attempt with minimum settings if (buffer.length > MAX_SIZE) { await page.setViewportSize({ width: MIN_DIMENSION, height: MIN_DIMENSION }); // Take final screenshot screenshot = await page.screenshot({ type: 'png', fullPage: false }); // Update buffer with final screenshot buffer = screenshot; // Throw error if final screenshot is still too large if (buffer.length > MAX_SIZE) { throw new McpError( ErrorCode.InvalidRequest, `Failed to reduce screenshot to under 5MB even with minimum settings` ); } } // Convert Buffer to base64 string before returning return buffer.toString('base64'); }
- index.ts:156-164 (registration)Tool registration in the TOOLS array, including name, description, and empty input schema (no parameters required). This is returned by the list_tools handler.{ name: "take_screenshot", description: "Take a screenshot of the current page", inputSchema: { type: "object", properties: {}, // No parameters needed }, }, ];
- index.ts:89-113 (helper)Helper function to save the base64 screenshot to disk in a temporary directory, with size validation and safe filename generation.async function saveScreenshot(screenshot: string, title: string): Promise<string> { // Convert screenshot from base64 to buffer const buffer = Buffer.from(screenshot, 'base64'); // Check size before saving const MAX_SIZE = 5 * 1024 * 1024; // 5MB if (buffer.length > MAX_SIZE) { throw new McpError( ErrorCode.InvalidRequest, `Screenshot too large: ${Math.round(buffer.length / (1024 * 1024))}MB exceeds ${MAX_SIZE / (1024 * 1024)}MB limit` ); } // Generate a safe filename const timestamp = new Date().getTime(); const safeTitle = title.replace(/[^a-z0-9]/gi, '_').toLowerCase(); const filename = `${safeTitle}-${timestamp}.png`; const filepath = path.join(SCREENSHOTS_DIR, filename); // Save the validated screenshot await fs.promises.writeFile(filepath, buffer); // Return the filepath to the saved screenshot return filepath; }