Skip to main content
Glama

Electron MCP Server

by halilural
handlers.tsโ€ข5.95 kB
import { CallToolRequestSchema } from '@modelcontextprotocol/sdk/types'; import { z } from 'zod'; import { ToolName } from './tools'; import { SendCommandToElectronSchema, TakeScreenshotSchema, ReadElectronLogsSchema, GetElectronWindowInfoSchema, } from './schemas'; import { sendCommandToElectron } from './utils/electron-enhanced-commands'; import { getElectronWindowInfo } from './utils/electron-discovery'; import { readElectronLogs } from './utils/electron-logs'; import { takeScreenshot } from './screenshot'; import { logger } from './utils/logger'; import { securityManager } from './security/manager'; export async function handleToolCall(request: z.infer<typeof CallToolRequestSchema>) { const { name, arguments: args } = request.params; // Extract request metadata for security logging const sourceIP = (request as any).meta?.sourceIP; const userAgent = (request as any).meta?.userAgent; try { switch (name) { case ToolName.GET_ELECTRON_WINDOW_INFO: { // This is a low-risk read operation - basic validation only const { includeChildren } = GetElectronWindowInfoSchema.parse(args); const securityResult = await securityManager.executeSecurely({ command: 'get_window_info', args, sourceIP, userAgent, operationType: 'window_info', }); if (securityResult.blocked) { return { content: [ { type: 'text', text: `Operation blocked: ${securityResult.error}`, }, ], isError: true, }; } const result = await getElectronWindowInfo(includeChildren); return { content: [ { type: 'text', text: `Window Information:\n\n${JSON.stringify(result, null, 2)}`, }, ], isError: false, }; } 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 }; } case ToolName.SEND_COMMAND_TO_ELECTRON: { const { command, args: commandArgs } = SendCommandToElectronSchema.parse(args); // Execute command through security manager const securityResult = await securityManager.executeSecurely({ command, args: commandArgs, sourceIP, userAgent, operationType: 'command', }); if (securityResult.blocked) { return { content: [ { type: 'text', text: `Command blocked: ${securityResult.error}\nRisk Level: ${securityResult.riskLevel}`, }, ], isError: true, }; } if (!securityResult.success) { return { content: [ { type: 'text', text: `Command failed: ${securityResult.error}`, }, ], isError: true, }; } // Execute the actual command if security checks pass const result = await sendCommandToElectron(command, commandArgs); return { content: [{ type: 'text', text: result }], isError: false, }; } case ToolName.READ_ELECTRON_LOGS: { const { logType, lines, follow } = ReadElectronLogsSchema.parse(args); const logs = await readElectronLogs(logType, lines); if (follow) { return { content: [ { type: 'text', text: `Following logs (${logType}). This is a snapshot of recent logs:\n\n${logs}`, }, ], isError: false, }; } return { content: [ { type: 'text', text: `Electron logs (${logType}):\n\n${logs}`, }, ], isError: false, }; } default: return { content: [ { type: 'text', text: `Unknown tool: ${name}`, }, ], isError: true, }; } } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); const errorStack = error instanceof Error ? error.stack : undefined; logger.error(`Tool execution failed: ${name}`, { error: errorMessage, stack: errorStack, args, }); return { content: [ { type: 'text', text: `Error executing ${name}: ${errorMessage}`, }, ], isError: true, }; } }

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