Skip to main content
Glama
mario-andreschak

MCP Windows Desktop Automation

control.ts11.8 kB
/** * Control-related tools for MCP Windows Desktop Automation */ import * as autoIt from 'node-autoit-koffi'; import { z } from 'zod'; import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { createToolResponse, createErrorResponse, schemas } from '../utils/types'; import { log } from '../utils/logger/logger'; /** * Register control-related tools with the MCP server */ export function registerControlTools(server: McpServer): void { // controlClick - Click on a control server.tool( 'controlClick', { title: schemas.windowTitle, text: schemas.windowText, control: schemas.controlName, button: schemas.mouseButton, clicks: schemas.mouseClicks, x: z.number().optional().describe('X coordinate within control'), y: z.number().optional().describe('Y coordinate within control') }, async ({ title, text, control, button, clicks, x, y }) => { try { log.verbose('controlClick called', { title, text, control, button, clicks, x, y }); await autoIt.init(); const result = await autoIt.controlClick(title, text, control, button, clicks, x, y); const success = result === 1; return createToolResponse( success ? `Clicked on control "${control}" in window "${title}"` : `Failed to click on control "${control}" in window "${title}"` ); } catch (error) { log.error('controlClick failed', error); return createErrorResponse(error instanceof Error ? error : String(error)); } } ); // controlClickByHandle - Click on a control by handle server.tool( 'controlClickByHandle', { windowHandle: schemas.handle, controlHandle: schemas.handle, button: schemas.mouseButton, clicks: schemas.mouseClicks, x: z.number().optional().describe('X coordinate within control'), y: z.number().optional().describe('Y coordinate within control') }, async ({ windowHandle, controlHandle, button, clicks, x, y }) => { try { log.verbose('controlClickByHandle called', { windowHandle, controlHandle, button, clicks, x, y }); await autoIt.init(); const result = await autoIt.controlClickByHandle(windowHandle, controlHandle, button, clicks, x, y); const success = result === 1; return createToolResponse( success ? `Clicked on control handle ${controlHandle} in window handle ${windowHandle}` : `Failed to click on control handle ${controlHandle} in window handle ${windowHandle}` ); } catch (error) { log.error('controlClickByHandle failed', error); return createErrorResponse(error instanceof Error ? error : String(error)); } } ); // controlCommand - Send a command to a control server.tool( 'controlCommand', { title: schemas.windowTitle, text: schemas.windowText, control: schemas.controlName, command: z.string().describe('Command to send'), extra: z.string().optional().describe('Extra parameter for the command'), bufSize: schemas.bufferSize }, async ({ title, text, control, command, extra, bufSize }) => { try { log.verbose('controlCommand called', { title, text, control, command, extra, bufSize }); await autoIt.init(); const result = await autoIt.controlCommand(title, text, control, command, extra, bufSize); log.verbose('controlCommand result', JSON.stringify({ result })); return createToolResponse(`Command "${command}" sent to control "${control}" with result: ${result}`); } catch (error) { log.error('controlCommand failed', error); return createErrorResponse(error instanceof Error ? error : String(error)); } } ); // controlGetText - Get text from a control server.tool( 'controlGetText', { title: schemas.windowTitle, text: schemas.windowText, control: schemas.controlName, bufSize: schemas.bufferSize }, async ({ title, text, control, bufSize }) => { try { log.verbose('controlGetText called', { title, text, control, bufSize }); await autoIt.init(); const controlText = await autoIt.controlGetText(title, text, control, bufSize); log.verbose('controlGetText result', JSON.stringify({ controlText })); return createToolResponse(`Text from control "${control}": "${controlText}"`); } catch (error) { log.error('controlGetText failed', error); return createErrorResponse(error instanceof Error ? error : String(error)); } } ); // controlSetText - Set text in a control server.tool( 'controlSetText', { title: schemas.windowTitle, text: schemas.windowText, control: schemas.controlName, controlText: schemas.controlText }, async ({ title, text, control, controlText }) => { try { log.verbose('controlSetText called', { title, text, control, controlText }); await autoIt.init(); const result = await autoIt.controlSetText(title, text, control, controlText); const success = result === 1; return createToolResponse( success ? `Text set in control "${control}" to "${controlText}"` : `Failed to set text in control "${control}"` ); } catch (error) { log.error('controlSetText failed', error); return createErrorResponse(error instanceof Error ? error : String(error)); } } ); // controlSend - Send keystrokes to a control server.tool( 'controlSend', { title: schemas.windowTitle, text: schemas.windowText, control: schemas.controlName, sendText: schemas.controlText, mode: z.number().optional().describe('Send mode flag') }, async ({ title, text, control, sendText, mode }) => { try { log.verbose('controlSend called', { title, text, control, sendText, mode }); await autoIt.init(); const result = await autoIt.controlSend(title, text, control, sendText, mode); const success = result === 1; return createToolResponse( success ? `Keystrokes "${sendText}" sent to control "${control}"` : `Failed to send keystrokes to control "${control}"` ); } catch (error) { log.error('controlSend failed', error); return createErrorResponse(error instanceof Error ? error : String(error)); } } ); // controlFocus - Set focus to a control server.tool( 'controlFocus', { title: schemas.windowTitle, text: schemas.windowText, control: schemas.controlName }, async ({ title, text, control }) => { try { log.verbose('controlFocus called', { title, text, control }); await autoIt.init(); const result = await autoIt.controlFocus(title, text, control); const success = result === 1; return createToolResponse( success ? `Focus set to control "${control}"` : `Failed to set focus to control "${control}"` ); } catch (error) { log.error('controlFocus failed', error); return createErrorResponse(error instanceof Error ? error : String(error)); } } ); // controlGetHandle - Get a control handle server.tool( 'controlGetHandle', { windowHandle: schemas.handle, control: schemas.controlName }, async ({ windowHandle, control }) => { try { log.verbose('controlGetHandle called', { windowHandle, control }); await autoIt.init(); const handle = await autoIt.controlGetHandle(windowHandle, control); log.verbose('controlGetHandle result', JSON.stringify({ handle })); return createToolResponse(`Control "${control}" handle: ${handle}`); } catch (error) { log.error('controlGetHandle failed', error); return createErrorResponse(error instanceof Error ? error : String(error)); } } ); // controlGetPos - Get control position and size server.tool( 'controlGetPos', { title: schemas.windowTitle, text: schemas.windowText, control: schemas.controlName }, async ({ title, text, control }) => { try { log.verbose('controlGetPos called', { title, text, control }); await autoIt.init(); const rect = await autoIt.controlGetPos(title, text, control); log.verbose('controlGetPos result', JSON.stringify(rect)); const width = rect.right - rect.left; const height = rect.bottom - rect.top; return createToolResponse( `Control "${control}" position: Left=${rect.left}, Top=${rect.top}, Width=${width}, Height=${height}` ); } catch (error) { log.error('controlGetPos failed', error); return createErrorResponse(error instanceof Error ? error : String(error)); } } ); // controlMove - Move and resize a control server.tool( 'controlMove', { title: schemas.windowTitle, text: schemas.windowText, control: schemas.controlName, x: z.number().describe('X coordinate'), y: z.number().describe('Y coordinate'), width: z.number().optional().describe('Control width'), height: z.number().optional().describe('Control height') }, async ({ title, text, control, x, y, width, height }) => { try { log.verbose('controlMove called', { title, text, control, x, y, width, height }); await autoIt.init(); const result = await autoIt.controlMove(title, text, control, x, y, width, height); const success = result === 1; const sizeInfo = width && height ? ` and resized to ${width}x${height}` : ''; return createToolResponse( success ? `Control "${control}" moved to (${x}, ${y})${sizeInfo}` : `Failed to move control "${control}"` ); } catch (error) { log.error('controlMove failed', error); return createErrorResponse(error instanceof Error ? error : String(error)); } } ); // controlShow - Show a control server.tool( 'controlShow', { title: schemas.windowTitle, text: schemas.windowText, control: schemas.controlName }, async ({ title, text, control }) => { try { log.verbose('controlShow called', { title, text, control }); await autoIt.init(); const result = await autoIt.controlShow(title, text, control); const success = result === 1; return createToolResponse( success ? `Control "${control}" shown` : `Failed to show control "${control}"` ); } catch (error) { log.error('controlShow failed', error); return createErrorResponse(error instanceof Error ? error : String(error)); } } ); // controlHide - Hide a control server.tool( 'controlHide', { title: schemas.windowTitle, text: schemas.windowText, control: schemas.controlName }, async ({ title, text, control }) => { try { log.verbose('controlHide called', { title, text, control }); await autoIt.init(); const result = await autoIt.controlHide(title, text, control); const success = result === 1; return createToolResponse( success ? `Control "${control}" hidden` : `Failed to hide control "${control}"` ); } catch (error) { log.error('controlHide failed', error); return createErrorResponse(error instanceof Error ? error : String(error)); } } ); }

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/mario-andreschak/mcp-windows-desktop-automation'

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