Skip to main content
Glama

take_screenshot

Capture a screenshot of any Electron application window and return base64 image data. Optionally save the image to a specified path for further AI analysis or processing.

Instructions

Take a screenshot of any running Electron application window. Returns base64 image data for AI analysis. No files created unless outputPath is specified.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
outputPathNoPath to save the screenshot (optional, defaults to temp directory)
windowTitleNoSpecific window title to screenshot (optional)

Implementation Reference

  • Core handler function that connects to running Electron apps via Chrome DevTools Protocol (CDP), takes a screenshot of the target page, encrypts the image data, optionally saves to file, and returns base64-encoded image for AI analysis.
    export async function takeScreenshot( outputPath?: string, windowTitle?: string, ): Promise<{ filePath?: string; base64: string; data: string; error?: string; }> { // Validate output path for security if (outputPath && !validateScreenshotPath(outputPath)) { throw new Error( `Invalid output path: ${outputPath}. Path appears to target a restricted system location.`, ); } // Inform user about screenshot logger.info('📸 Taking screenshot of Electron application', { outputPath, windowTitle, timestamp: new Date().toISOString(), }); try { // Find running Electron applications const apps = await scanForElectronApps(); if (apps.length === 0) { throw new Error('No running Electron applications found with remote debugging enabled'); } // Use the first app found (or find by title if specified) let targetApp = apps[0]; if (windowTitle) { const namedApp = apps.find((app) => app.targets.some((target) => target.title?.toLowerCase().includes(windowTitle.toLowerCase()), ), ); if (namedApp) { targetApp = namedApp; } } // Connect to the Electron app's debugging port const browser = await chromium.connectOverCDP(`http://localhost:${targetApp.port}`); const contexts = browser.contexts(); if (contexts.length === 0) { throw new Error( 'No browser contexts found - make sure Electron app is running with remote debugging enabled', ); } const context = contexts[0]; const pages = context.pages(); if (pages.length === 0) { throw new Error('No pages found in the browser context'); } // Find the main application page (skip DevTools pages) let targetPage = pages[0]; for (const page of pages) { const url = page.url(); const title = await page.title().catch(() => ''); // Skip DevTools and about:blank pages if ( !url.includes('devtools://') && !url.includes('about:blank') && title && !title.includes('DevTools') ) { // If windowTitle is specified, try to match it if (windowTitle && title.toLowerCase().includes(windowTitle.toLowerCase())) { targetPage = page; break; } else if (!windowTitle) { targetPage = page; break; } } } logger.info(`Taking screenshot of page: ${targetPage.url()} (${await targetPage.title()})`); // Take screenshot as buffer (in memory) const screenshotBuffer = await targetPage.screenshot({ type: 'png', fullPage: false, }); await browser.close(); // Encrypt screenshot data for security const encryptedScreenshot = encryptScreenshotData(screenshotBuffer); // Convert buffer to base64 for transmission const base64Data = screenshotBuffer.toString('base64'); logger.info( `Screenshot captured and encrypted successfully (${screenshotBuffer.length} bytes)`, ); // If outputPath is provided, save encrypted data to file if (outputPath) { await fs.writeFile(outputPath + '.encrypted', JSON.stringify(encryptedScreenshot)); // Also save unencrypted for compatibility (in production, consider removing this) await fs.writeFile(outputPath, screenshotBuffer); return { filePath: outputPath, base64: base64Data, data: `Screenshot saved to: ${outputPath} (encrypted backup: ${outputPath}.encrypted) and returned as base64 data`, }; } else { return { base64: base64Data, data: `Screenshot captured as base64 data (${screenshotBuffer.length} bytes) - no file saved`, }; } } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); throw new Error( `Screenshot failed: ${errorMessage}. Make sure the Electron app is running with remote debugging enabled (--remote-debugging-port=9222)`, ); } }
  • Zod schema defining the input parameters for the take_screenshot tool: optional outputPath and windowTitle.
    export const TakeScreenshotSchema = z.object({ outputPath: z .string() .optional() .describe('Path to save the screenshot (optional, defaults to temp directory)'), windowTitle: z.string().optional().describe('Specific window title to screenshot (optional)'), });
  • src/tools.ts:26-31 (registration)
    Tool registration in the tools array, defining name 'take_screenshot', description, and input schema.
    { name: ToolName.TAKE_SCREENSHOT, description: 'Take a screenshot of any running Electron application window. Returns base64 image data for AI analysis. No files created unless outputPath is specified.', inputSchema: zodToJsonSchema(TakeScreenshotSchema) as ToolInput, },
  • src/handlers.ts:62-109 (registration)
    Handler dispatch in handleToolCall switch statement: validates args, calls takeScreenshot, and formats MCP response with base64 image.
    case ToolName.TAKE_SCREENSHOT: { // Security check for screenshot operation const securityResult = await securityManager.executeSecurely({ command: 'take_screenshot', args, sourceIP, userAgent, operationType: 'screenshot', }); if (securityResult.blocked) { return { content: [ { type: 'text', text: `Screenshot blocked: ${securityResult.error}`, }, ], isError: true, }; } const { outputPath, windowTitle } = TakeScreenshotSchema.parse(args); const result = await takeScreenshot(outputPath, windowTitle); // Return the screenshot as base64 data for AI to evaluate const content: any[] = []; if (result.filePath) { content.push({ type: 'text', text: `Screenshot saved to: ${result.filePath}`, }); } else { content.push({ type: 'text', text: 'Screenshot captured in memory (no file saved)', }); } // Add the image data for AI evaluation content.push({ type: 'image', data: result.base64!, mimeType: 'image/png', }); return { content, isError: false }; }

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/halilural/electron-mcp-server'

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