Skip to main content
Glama
mzxrai

MCP Web Research Server

by mzxrai

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
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • 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
            };
        }
    }
  • 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
            },
        },
    ];
  • 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;
    }
Install Server

Other Tools

Related Tools

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/mzxrai/mcp-webresearch'

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