#
tokens: 22201/50000 16/16 files
lines: on (toggle) GitHub
raw markdown copy reset
# Directory Structure

```
├── .gitattributes
├── .gitignore
├── LICENSE
├── package.json
├── README.md
├── src
│   ├── index.ts
│   ├── prompts
│   │   └── index.ts
│   ├── resources
│   │   └── index.ts
│   ├── server
│   │   └── server.ts
│   ├── tools
│   │   ├── control.ts
│   │   ├── index.ts
│   │   ├── keyboard.ts
│   │   ├── mouse.ts
│   │   ├── process.ts
│   │   └── window.ts
│   └── utils
│       ├── logger
│       │   └── logger.ts
│       └── types.ts
└── tsconfig.json
```

# Files

--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------

```
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 | 
```

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
  1 | # Logs
  2 | logs
  3 | *.log
  4 | npm-debug.log*
  5 | yarn-debug.log*
  6 | yarn-error.log*
  7 | lerna-debug.log*
  8 | .pnpm-debug.log*
  9 | 
 10 | # Diagnostic reports (https://nodejs.org/api/report.html)
 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
 12 | 
 13 | # Runtime data
 14 | pids
 15 | *.pid
 16 | *.seed
 17 | *.pid.lock
 18 | 
 19 | # Directory for instrumented libs generated by jscoverage/JSCover
 20 | lib-cov
 21 | 
 22 | # Coverage directory used by tools like istanbul
 23 | coverage
 24 | *.lcov
 25 | 
 26 | # nyc test coverage
 27 | .nyc_output
 28 | 
 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
 30 | .grunt
 31 | 
 32 | # Bower dependency directory (https://bower.io/)
 33 | bower_components
 34 | 
 35 | # node-waf configuration
 36 | .lock-wscript
 37 | 
 38 | # Compiled binary addons (https://nodejs.org/api/addons.html)
 39 | build/Release
 40 | 
 41 | # Dependency directories
 42 | node_modules/
 43 | jspm_packages/
 44 | 
 45 | # Snowpack dependency directory (https://snowpack.dev/)
 46 | web_modules/
 47 | 
 48 | # TypeScript cache
 49 | *.tsbuildinfo
 50 | 
 51 | # Optional npm cache directory
 52 | .npm
 53 | 
 54 | # Optional eslint cache
 55 | .eslintcache
 56 | 
 57 | # Optional stylelint cache
 58 | .stylelintcache
 59 | 
 60 | # Microbundle cache
 61 | .rpt2_cache/
 62 | .rts2_cache_cjs/
 63 | .rts2_cache_es/
 64 | .rts2_cache_umd/
 65 | 
 66 | # Optional REPL history
 67 | .node_repl_history
 68 | 
 69 | # Output of 'npm pack'
 70 | *.tgz
 71 | 
 72 | # Yarn Integrity file
 73 | .yarn-integrity
 74 | 
 75 | # dotenv environment variable files
 76 | .env
 77 | .env.development.local
 78 | .env.test.local
 79 | .env.production.local
 80 | .env.local
 81 | 
 82 | # parcel-bundler cache (https://parceljs.org/)
 83 | .cache
 84 | .parcel-cache
 85 | 
 86 | # Next.js build output
 87 | .next
 88 | out
 89 | 
 90 | # Nuxt.js build / generate output
 91 | .nuxt
 92 | dist
 93 | 
 94 | # Gatsby files
 95 | .cache/
 96 | # Comment in the public line in if your project uses Gatsby and not Next.js
 97 | # https://nextjs.org/blog/next-9-1#public-directory-support
 98 | # public
 99 | 
100 | # vuepress build output
101 | .vuepress/dist
102 | 
103 | # vuepress v2.x temp and cache directory
104 | .temp
105 | .cache
106 | 
107 | # Docusaurus cache and generated files
108 | .docusaurus
109 | 
110 | # Serverless directories
111 | .serverless/
112 | 
113 | # FuseBox cache
114 | .fusebox/
115 | 
116 | # DynamoDB Local files
117 | .dynamodb/
118 | 
119 | # TernJS port file
120 | .tern-port
121 | 
122 | # Stores VSCode versions used for testing VSCode extensions
123 | .vscode-test
124 | 
125 | # yarn v2
126 | .yarn/cache
127 | .yarn/unplugged
128 | .yarn/build-state.yml
129 | .yarn/install-state.gz
130 | .pnp.*
131 | 
```

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
  1 | # MCP Windows Desktop Automation
  2 | 
  3 | A Model Context Protocol (MCP) server for Windows desktop automation using AutoIt.
  4 | 
  5 | ## Overview
  6 | 
  7 | This project provides a TypeScript MCP server that wraps the [node-autoit-koffi](https://www.npmjs.com/package/node-autoit-koffi) package, allowing LLM applications to automate Windows desktop tasks through the MCP protocol.
  8 | 
  9 | The server exposes:
 10 | - **Tools**: All AutoIt functions as MCP tools
 11 | - **Resources**: File access and screenshot capabilities
 12 | - **Prompts**: Templates for common automation tasks
 13 | 
 14 | ## Features
 15 | 
 16 | - Full wrapping of all AutoIt functions as MCP tools
 17 | - Support for both stdio and WebSocket transports
 18 | - File access resources for reading files and directories
 19 | - Screenshot resources for capturing the screen or specific windows
 20 | - Prompt templates for common automation tasks
 21 | - Strict TypeScript typing throughout
 22 | 
 23 | ## Installation
 24 | 
 25 | ```bash
 26 | # Clone the repository
 27 | git clone https://github.com/yourusername/mcp-windows-desktop-automation.git
 28 | cd mcp-windows-desktop-automation
 29 | 
 30 | # Install dependencies
 31 | npm install
 32 | 
 33 | # Build the project
 34 | npm run build
 35 | ```
 36 | 
 37 | ## Usage
 38 | 
 39 | ### Starting the Server
 40 | 
 41 | ```bash
 42 | # Start with stdio transport (default)
 43 | npm start
 44 | 
 45 | # Start with WebSocket transport
 46 | npm start -- --transport=websocket --port=3000
 47 | 
 48 | # Enable verbose logging
 49 | npm start -- --verbose
 50 | ```
 51 | 
 52 | ### Command Line Options
 53 | 
 54 | - `--transport=stdio|websocket`: Specify the transport protocol (default: stdio)
 55 | - `--port=<number>`: Specify the port for WebSocket transport (default: 3000)
 56 | - `--verbose`: Enable verbose logging
 57 | 
 58 | ## Tools
 59 | 
 60 | The server provides tools for:
 61 | 
 62 | - **Mouse operations**: Move, click, drag, etc.
 63 | - **Keyboard operations**: Send keystrokes, clipboard operations, etc.
 64 | - **Window management**: Find, activate, close, resize windows, etc.
 65 | - **Control manipulation**: Interact with UI controls, buttons, text fields, etc.
 66 | - **Process management**: Start, stop, and monitor processes
 67 | - **System operations**: Shutdown, sleep, etc.
 68 | 
 69 | ## Resources
 70 | 
 71 | The server provides resources for:
 72 | 
 73 | - **File access**: Read files and list directories
 74 | - **Screenshots**: Capture the screen or specific windows
 75 | 
 76 | ## Prompts
 77 | 
 78 | The server provides prompt templates for:
 79 | 
 80 | - **Window interaction**: Find and interact with windows
 81 | - **Form filling**: Automate form filling tasks
 82 | - **Automation tasks**: Create scripts for repetitive tasks
 83 | - **Monitoring**: Wait for specific conditions
 84 | 
 85 | ## Development
 86 | 
 87 | ```bash
 88 | # Run in development mode
 89 | npm run dev
 90 | 
 91 | # Lint the code
 92 | npm run lint
 93 | 
 94 | # Run tests
 95 | npm run test
 96 | ```
 97 | 
 98 | ## License
 99 | 
100 | MIT
101 | 
```

--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "compilerOptions": {
 3 |     "target": "ES2020",
 4 |     "module": "NodeNext",
 5 |     "moduleResolution": "NodeNext",
 6 |     "esModuleInterop": true,
 7 |     "strict": true,
 8 |     "strictNullChecks": true,
 9 |     "strictFunctionTypes": true,
10 |     "strictPropertyInitialization": true,
11 |     "noImplicitAny": true,
12 |     "noImplicitThis": true,
13 |     "alwaysStrict": true,
14 |     "outDir": "./dist",
15 |     "sourceMap": true,
16 |     "declaration": true,
17 |     "resolveJsonModule": true
18 |   },
19 |   "include": ["src/**/*"],
20 |   "exclude": ["node_modules", "dist"]
21 | }
22 | 
```

--------------------------------------------------------------------------------
/src/tools/index.ts:
--------------------------------------------------------------------------------

```typescript
 1 | /**
 2 |  * Tools module for MCP Windows Desktop Automation
 3 |  */
 4 | 
 5 | import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
 6 | import { registerMouseTools } from './mouse';
 7 | import { registerKeyboardTools } from './keyboard';
 8 | import { registerWindowTools } from './window';
 9 | import { registerProcessTools } from './process';
10 | import { registerControlTools } from './control';
11 | 
12 | /**
13 |  * Register all AutoIt tools with the MCP server
14 |  */
15 | export function registerAllTools(server: McpServer): void {
16 |   registerMouseTools(server);
17 |   registerKeyboardTools(server);
18 |   registerWindowTools(server);
19 |   registerProcessTools(server);
20 |   registerControlTools(server);
21 | }
22 | 
```

--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "name": "mcp-windows-desktop-automation",
 3 |   "version": "0.1.0",
 4 |   "description": "MCP server for Windows desktop automation",
 5 |   "main": "dist/index.js",
 6 |   "scripts": {
 7 |     "build": "tsc",
 8 |     "start": "node dist/index.js",
 9 |     "dev": "ts-node src/index.ts",
10 |     "lint": "eslint src/**/*.ts",
11 |     "test": "jest"
12 |   },
13 |   "keywords": [
14 |     "mcp",
15 |     "windows",
16 |     "automation",
17 |     "autoit"
18 |   ],
19 |   "author": "",
20 |   "license": "MIT",
21 |   "dependencies": {
22 |     "@modelcontextprotocol/sdk": "^1.7.0",
23 |     "node-autoit-koffi": "^1.0.5",
24 |     "ws": "^8.18.1"
25 |   },
26 |   "devDependencies": {
27 |     "@types/express": "^4.17.17",
28 |     "@types/node": "^18.15.11",
29 |     "@types/ws": "^8.18.0",
30 |     "@typescript-eslint/eslint-plugin": "^5.57.1",
31 |     "@typescript-eslint/parser": "^5.57.1",
32 |     "eslint": "^8.38.0",
33 |     "jest": "^29.5.0",
34 |     "ts-jest": "^29.1.0",
35 |     "ts-node": "^10.9.1",
36 |     "typescript": "^5.0.4"
37 |   }
38 | }
39 | 
```

--------------------------------------------------------------------------------
/src/utils/logger/logger.ts:
--------------------------------------------------------------------------------

```typescript
 1 | /**
 2 |  * Logger utility for MCP Windows Desktop Automation
 3 |  */
 4 | 
 5 | enum LogLevel {
 6 |   VERBOSE = 0,
 7 |   DEBUG = 1,
 8 |   INFO = 2,
 9 |   WARN = 3,
10 |   ERROR = 4
11 | }
12 | 
13 | class Logger {
14 |   private level: LogLevel = LogLevel.INFO;
15 | 
16 |   /**
17 |    * Set the minimum log level
18 |    * @param level The minimum level to log
19 |    */
20 |   setLevel(level: LogLevel): void {
21 |     this.level = level;
22 |   }
23 | 
24 |   /**
25 |    * Log verbose information
26 |    * @param message The message to log
27 |    * @param data Additional data to log (will be JSON stringified)
28 |    */
29 |   verbose(message: string, data?: any): void {
30 |     if (this.level <= LogLevel.VERBOSE) {
31 |       console.log(`[VERBOSE] ${message}`, data ? JSON.stringify(data) : '');
32 |     }
33 |   }
34 | 
35 |   /**
36 |    * Log debug information
37 |    * @param message The message to log
38 |    * @param data Additional data to log
39 |    */
40 |   debug(message: string, data?: any): void {
41 |     if (this.level <= LogLevel.DEBUG) {
42 |       console.log(`[DEBUG] ${message}`, data || '');
43 |     }
44 |   }
45 | 
46 |   /**
47 |    * Log general information
48 |    * @param message The message to log
49 |    * @param data Additional data to log
50 |    */
51 |   info(message: string, data?: any): void {
52 |     if (this.level <= LogLevel.INFO) {
53 |       console.log(`[INFO] ${message}`, data || '');
54 |     }
55 |   }
56 | 
57 |   /**
58 |    * Log warnings
59 |    * @param message The message to log
60 |    * @param data Additional data to log
61 |    */
62 |   warn(message: string, data?: any): void {
63 |     if (this.level <= LogLevel.WARN) {
64 |       console.warn(`[WARN] ${message}`, data || '');
65 |     }
66 |   }
67 | 
68 |   /**
69 |    * Log errors
70 |    * @param message The message to log
71 |    * @param data Additional data to log
72 |    */
73 |   error(message: string, data?: any): void {
74 |     if (this.level <= LogLevel.ERROR) {
75 |       console.error(`[ERROR] ${message}`, data || '');
76 |     }
77 |   }
78 | }
79 | 
80 | export const log = new Logger();
81 | 
```

--------------------------------------------------------------------------------
/src/utils/types.ts:
--------------------------------------------------------------------------------

```typescript
 1 | /**
 2 |  * Shared type definitions for MCP Windows Desktop Automation
 3 |  */
 4 | 
 5 | import { z } from 'zod';
 6 | import { CallToolResult, TextContent } from '@modelcontextprotocol/sdk/types.js';
 7 | 
 8 | /**
 9 |  * Point coordinates
10 |  */
11 | export interface Point {
12 |   x: number;
13 |   y: number;
14 | }
15 | 
16 | /**
17 |  * Rectangle coordinates
18 |  */
19 | export interface Rect {
20 |   left: number;
21 |   top: number;
22 |   right: number;
23 |   bottom: number;
24 | }
25 | 
26 | /**
27 |  * Standard tool response creator
28 |  */
29 | export function createToolResponse(message: string): CallToolResult {
30 |   return {
31 |     content: [
32 |       {
33 |         type: 'text',
34 |         text: message
35 |       } as TextContent
36 |     ]
37 |   };
38 | }
39 | 
40 | /**
41 |  * Standard error response creator
42 |  */
43 | export function createErrorResponse(error: Error | string): CallToolResult {
44 |   const errorMessage = typeof error === 'string' ? error : error.message;
45 |   return {
46 |     content: [
47 |       {
48 |         type: 'text',
49 |         text: `Error: ${errorMessage}`
50 |       } as TextContent
51 |     ],
52 |     isError: true
53 |   };
54 | }
55 | 
56 | /**
57 |  * Common Zod schemas for tool parameters
58 |  */
59 | export const schemas = {
60 |   // Window identification
61 |   windowTitle: z.string().describe('Window title'),
62 |   windowText: z.string().optional().describe('Window text'),
63 |   
64 |   // Mouse parameters
65 |   mouseButton: z.enum(['left', 'right', 'middle']).optional().default('left').describe('Mouse button'),
66 |   mouseSpeed: z.number().min(1).max(100).optional().default(10).describe('Mouse movement speed (1-100)'),
67 |   mouseX: z.number().describe('X coordinate'),
68 |   mouseY: z.number().describe('Y coordinate'),
69 |   mouseClicks: z.number().min(1).optional().default(1).describe('Number of clicks'),
70 |   
71 |   // Control parameters
72 |   controlName: z.string().describe('Control identifier'),
73 |   controlText: z.string().describe('Text to set/send to control'),
74 |   
75 |   // Process parameters
76 |   processName: z.string().describe('Process name or executable path'),
77 |   processTimeout: z.number().optional().describe('Timeout in milliseconds'),
78 |   
79 |   // Common parameters
80 |   handle: z.number().describe('Window or control handle'),
81 |   bufferSize: z.number().optional().describe('Buffer size for string operations')
82 | };
83 | 
```

--------------------------------------------------------------------------------
/src/server/server.ts:
--------------------------------------------------------------------------------

```typescript
  1 | /**
  2 |  * MCP Server configuration for Windows Desktop Automation
  3 |  */
  4 | 
  5 | import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
  6 | import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
  7 | import { WebSocket, WebSocketServer, RawData } from 'ws';
  8 | import { createServer as createHttpServer, IncomingMessage, Server as HttpServer } from 'http';
  9 | import { log } from '../utils/logger/logger';
 10 | import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
 11 | import { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';
 12 | 
 13 | /**
 14 |  * Custom WebSocket transport for MCP
 15 |  */
 16 | class WebSocketServerTransport implements Transport {
 17 |   private ws: WebSocket | null = null;
 18 |   sessionId?: string;
 19 | 
 20 |   constructor(ws: WebSocket) {
 21 |     this.ws = ws;
 22 |     this.sessionId = Math.random().toString(36).substring(2, 15);
 23 |     
 24 |     ws.on('message', (data: RawData) => {
 25 |       try {
 26 |         const message = JSON.parse(data.toString()) as JSONRPCMessage;
 27 |         this.onmessage?.(message);
 28 |       } catch (error) {
 29 |         this.onerror?.(new Error(`Failed to parse message: ${error}`));
 30 |       }
 31 |     });
 32 | 
 33 |     ws.on('close', () => {
 34 |       this.ws = null;
 35 |       this.onclose?.();
 36 |     });
 37 | 
 38 |     ws.on('error', (error: Error) => {
 39 |       this.onerror?.(error);
 40 |     });
 41 |   }
 42 | 
 43 |   onclose?: () => void;
 44 |   onerror?: (error: Error) => void;
 45 |   onmessage?: (message: JSONRPCMessage) => void;
 46 | 
 47 |   async start(): Promise<void> {
 48 |     log.info('WebSocket transport started');
 49 |   }
 50 | 
 51 |   async send(message: JSONRPCMessage): Promise<void> {
 52 |     if (!this.ws) {
 53 |       throw new Error('WebSocket not connected');
 54 |     }
 55 |     
 56 |     return new Promise((resolve, reject) => {
 57 |       this.ws!.send(JSON.stringify(message), (error?: Error) => {
 58 |         if (error) {
 59 |           reject(error);
 60 |         } else {
 61 |           resolve();
 62 |         }
 63 |       });
 64 |     });
 65 |   }
 66 | 
 67 |   async close(): Promise<void> {
 68 |     if (this.ws) {
 69 |       this.ws.close();
 70 |       this.ws = null;
 71 |     }
 72 |   }
 73 | }
 74 | 
 75 | /**
 76 |  * Server configuration options
 77 |  */
 78 | export interface ServerConfig {
 79 |   name: string;
 80 |   version: string;
 81 |   transport: 'stdio' | 'websocket';
 82 |   port?: number;
 83 | }
 84 | 
 85 | /**
 86 |  * Create and configure an MCP server
 87 |  */
 88 | export async function setupServer(config: ServerConfig): Promise<{
 89 |   server: McpServer;
 90 |   httpServer?: HttpServer;
 91 | }> {
 92 |   // Create the MCP server
 93 |   const server = new McpServer({
 94 |     name: config.name,
 95 |     version: config.version
 96 |   }, {
 97 |     capabilities: {
 98 |       tools: {},
 99 |       resources: {
100 |         subscribe: true,
101 |         listChanged: true
102 |       },
103 |       prompts: {
104 |         listChanged: true
105 |       }
106 |     }
107 |   });
108 | 
109 |   // Configure the transport
110 |   if (config.transport === 'stdio') {
111 |     log.info('Using stdio transport');
112 |     const transport = new StdioServerTransport();
113 |     await server.connect(transport);
114 |     return { server };
115 |   } else if (config.transport === 'websocket') {
116 |     log.info(`Using WebSocket transport on port ${config.port}`);
117 |     
118 |     // Create HTTP server
119 |     const httpServer = createHttpServer();
120 |     const wss = new WebSocketServer({ server: httpServer });
121 |     
122 |     // Handle WebSocket connections
123 |     wss.on('connection', async (ws: WebSocket) => {
124 |       log.info('New WebSocket connection');
125 |       const transport = new WebSocketServerTransport(ws);
126 |       await server.connect(transport);
127 |     });
128 |     
129 |     // Start HTTP server
130 |     httpServer.listen(config.port || 3000);
131 |     
132 |     return { server, httpServer };
133 |   } else {
134 |     throw new Error(`Unsupported transport: ${config.transport}`);
135 |   }
136 | }
137 | 
```

--------------------------------------------------------------------------------
/src/tools/keyboard.ts:
--------------------------------------------------------------------------------

```typescript
  1 | /**
  2 |  * Keyboard-related tools for MCP Windows Desktop Automation
  3 |  */
  4 | 
  5 | import * as autoIt from 'node-autoit-koffi';
  6 | import { z } from 'zod';
  7 | import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
  8 | import { createToolResponse, createErrorResponse } from '../utils/types';
  9 | import { log } from '../utils/logger/logger';
 10 | 
 11 | /**
 12 |  * Register keyboard-related tools with the MCP server
 13 |  */
 14 | export function registerKeyboardTools(server: McpServer): void {
 15 |   // send - Send keystrokes to the active window
 16 |   server.tool(
 17 |     'send',
 18 |     {
 19 |       text: z.string().describe('Text or keys to send'),
 20 |       mode: z.number().optional().default(0).describe('Send mode flag')
 21 |     },
 22 |     async ({ text, mode }) => {
 23 |       try {
 24 |         log.verbose('send called', { text, mode });
 25 |         await autoIt.init();
 26 |         await autoIt.send(text, mode);
 27 |         return createToolResponse(`Sent keystrokes: "${text}" with mode ${mode}`);
 28 |       } catch (error) {
 29 |         log.error('send failed', error);
 30 |         return createErrorResponse(error instanceof Error ? error : String(error));
 31 |       }
 32 |     }
 33 |   );
 34 | 
 35 |   // clipGet - Get the text from the clipboard
 36 |   server.tool(
 37 |     'clipGet',
 38 |     {
 39 |       bufSize: z.number().optional().describe('Buffer size for clipboard content')
 40 |     },
 41 |     async ({ bufSize }) => {
 42 |       try {
 43 |         log.verbose('clipGet called', { bufSize });
 44 |         await autoIt.init();
 45 |         const clipboardContent = await autoIt.clipGet(bufSize);
 46 |         log.verbose('clipGet result', JSON.stringify({ clipboardContent }));
 47 |         return createToolResponse(`Clipboard content: "${clipboardContent}"`);
 48 |       } catch (error) {
 49 |         log.error('clipGet failed', error);
 50 |         return createErrorResponse(error instanceof Error ? error : String(error));
 51 |       }
 52 |     }
 53 |   );
 54 | 
 55 |   // clipPut - Put text into the clipboard
 56 |   server.tool(
 57 |     'clipPut',
 58 |     {
 59 |       text: z.string().describe('Text to put in the clipboard')
 60 |     },
 61 |     async ({ text }) => {
 62 |       try {
 63 |         log.verbose('clipPut called', { text });
 64 |         await autoIt.init();
 65 |         await autoIt.clipPut(text);
 66 |         return createToolResponse(`Text set to clipboard: "${text}"`);
 67 |       } catch (error) {
 68 |         log.error('clipPut failed', error);
 69 |         return createErrorResponse(error instanceof Error ? error : String(error));
 70 |       }
 71 |     }
 72 |   );
 73 | 
 74 |   // autoItSetOption - Set AutoIt options
 75 |   server.tool(
 76 |     'autoItSetOption',
 77 |     {
 78 |       option: z.string().describe('Option name'),
 79 |       value: z.number().describe('Option value')
 80 |     },
 81 |     async ({ option, value }) => {
 82 |       try {
 83 |         log.verbose('autoItSetOption called', { option, value });
 84 |         await autoIt.init();
 85 |         const result = await autoIt.autoItSetOption(option, value);
 86 |         return createToolResponse(`AutoIt option "${option}" set to ${value} with result: ${result}`);
 87 |       } catch (error) {
 88 |         log.error('autoItSetOption failed', error);
 89 |         return createErrorResponse(error instanceof Error ? error : String(error));
 90 |       }
 91 |     }
 92 |   );
 93 | 
 94 |   // opt - Alias for autoItSetOption
 95 |   server.tool(
 96 |     'opt',
 97 |     {
 98 |       option: z.string().describe('Option name'),
 99 |       value: z.number().describe('Option value')
100 |     },
101 |     async ({ option, value }) => {
102 |       try {
103 |         log.verbose('opt called', { option, value });
104 |         await autoIt.init();
105 |         const result = await autoIt.opt(option, value);
106 |         return createToolResponse(`AutoIt option "${option}" set to ${value} with result: ${result}`);
107 |       } catch (error) {
108 |         log.error('opt failed', error);
109 |         return createErrorResponse(error instanceof Error ? error : String(error));
110 |       }
111 |     }
112 |   );
113 | 
114 |   // toolTip - Display a tooltip
115 |   server.tool(
116 |     'toolTip',
117 |     {
118 |       text: z.string().describe('Tooltip text'),
119 |       x: z.number().optional().describe('X coordinate'),
120 |       y: z.number().optional().describe('Y coordinate')
121 |     },
122 |     async ({ text, x, y }) => {
123 |       try {
124 |         log.verbose('toolTip called', { text, x, y });
125 |         await autoIt.init();
126 |         await autoIt.toolTip(text, x, y);
127 |         const position = x !== undefined && y !== undefined ? ` at position (${x}, ${y})` : '';
128 |         return createToolResponse(`Tooltip displayed: "${text}"${position}`);
129 |       } catch (error) {
130 |         log.error('toolTip failed', error);
131 |         return createErrorResponse(error instanceof Error ? error : String(error));
132 |       }
133 |     }
134 |   );
135 | }
136 | 
```

--------------------------------------------------------------------------------
/src/tools/mouse.ts:
--------------------------------------------------------------------------------

```typescript
  1 | /**
  2 |  * Mouse-related tools for MCP Windows Desktop Automation
  3 |  */
  4 | 
  5 | import * as autoIt from 'node-autoit-koffi';
  6 | import { z } from 'zod';
  7 | import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
  8 | import { createToolResponse, createErrorResponse, schemas } from '../utils/types';
  9 | import { log } from '../utils/logger/logger';
 10 | 
 11 | /**
 12 |  * Register mouse-related tools with the MCP server
 13 |  */
 14 | export function registerMouseTools(server: McpServer): void {
 15 |   // mouseMove - Move the mouse cursor to the specified coordinates
 16 |   server.tool(
 17 |     'mouseMove',
 18 |     {
 19 |       x: schemas.mouseX,
 20 |       y: schemas.mouseY,
 21 |       speed: schemas.mouseSpeed
 22 |     },
 23 |     async ({ x, y, speed }) => {
 24 |       try {
 25 |         log.verbose('mouseMove called', { x, y, speed });
 26 |         await autoIt.init();
 27 |         const result = await autoIt.mouseMove(x, y, speed);
 28 |         return createToolResponse(`Mouse moved to (${x}, ${y}) with result: ${result}`);
 29 |       } catch (error) {
 30 |         log.error('mouseMove failed', error);
 31 |         return createErrorResponse(error instanceof Error ? error : String(error));
 32 |       }
 33 |     }
 34 |   );
 35 | 
 36 |   // mouseClick - Click the mouse at the current or specified position
 37 |   server.tool(
 38 |     'mouseClick',
 39 |     {
 40 |       button: schemas.mouseButton,
 41 |       x: schemas.mouseX.optional(),
 42 |       y: schemas.mouseY.optional(),
 43 |       clicks: schemas.mouseClicks,
 44 |       speed: schemas.mouseSpeed
 45 |     },
 46 |     async ({ button, x, y, clicks, speed }) => {
 47 |       try {
 48 |         log.verbose('mouseClick called', { button, x, y, clicks, speed });
 49 |         await autoIt.init();
 50 |         const result = await autoIt.mouseClick(button, x, y, clicks, speed);
 51 |         return createToolResponse(`Mouse clicked ${button} button ${clicks} time(s) with result: ${result}`);
 52 |       } catch (error) {
 53 |         log.error('mouseClick failed', error);
 54 |         return createErrorResponse(error instanceof Error ? error : String(error));
 55 |       }
 56 |     }
 57 |   );
 58 | 
 59 |   // mouseClickDrag - Click and drag the mouse from one position to another
 60 |   server.tool(
 61 |     'mouseClickDrag',
 62 |     {
 63 |       button: schemas.mouseButton,
 64 |       x1: schemas.mouseX,
 65 |       y1: schemas.mouseY,
 66 |       x2: schemas.mouseX,
 67 |       y2: schemas.mouseY,
 68 |       speed: schemas.mouseSpeed
 69 |     },
 70 |     async ({ button, x1, y1, x2, y2, speed }) => {
 71 |       try {
 72 |         log.verbose('mouseClickDrag called', { button, x1, y1, x2, y2, speed });
 73 |         await autoIt.init();
 74 |         const result = await autoIt.mouseClickDrag(button, x1, y1, x2, y2, speed);
 75 |         return createToolResponse(`Mouse dragged from (${x1}, ${y1}) to (${x2}, ${y2}) with result: ${result}`);
 76 |       } catch (error) {
 77 |         log.error('mouseClickDrag failed', error);
 78 |         return createErrorResponse(error instanceof Error ? error : String(error));
 79 |       }
 80 |     }
 81 |   );
 82 | 
 83 |   // mouseDown - Press and hold the specified mouse button
 84 |   server.tool(
 85 |     'mouseDown',
 86 |     {
 87 |       button: schemas.mouseButton
 88 |     },
 89 |     async ({ button }) => {
 90 |       try {
 91 |         log.verbose('mouseDown called', { button });
 92 |         await autoIt.init();
 93 |         await autoIt.mouseDown(button);
 94 |         return createToolResponse(`Mouse ${button} button pressed down`);
 95 |       } catch (error) {
 96 |         log.error('mouseDown failed', error);
 97 |         return createErrorResponse(error instanceof Error ? error : String(error));
 98 |       }
 99 |     }
100 |   );
101 | 
102 |   // mouseUp - Release the specified mouse button
103 |   server.tool(
104 |     'mouseUp',
105 |     {
106 |       button: schemas.mouseButton
107 |     },
108 |     async ({ button }) => {
109 |       try {
110 |         log.verbose('mouseUp called', { button });
111 |         await autoIt.init();
112 |         await autoIt.mouseUp(button);
113 |         return createToolResponse(`Mouse ${button} button released`);
114 |       } catch (error) {
115 |         log.error('mouseUp failed', error);
116 |         return createErrorResponse(error instanceof Error ? error : String(error));
117 |       }
118 |     }
119 |   );
120 | 
121 |   // mouseGetPos - Get the current mouse cursor position
122 |   server.tool(
123 |     'mouseGetPos',
124 |     {},
125 |     async () => {
126 |       try {
127 |         log.verbose('mouseGetPos called');
128 |         await autoIt.init();
129 |         const position = await autoIt.mouseGetPos();
130 |         log.verbose('mouseGetPos result', JSON.stringify(position));
131 |         return createToolResponse(`Mouse position: (${position.x}, ${position.y})`);
132 |       } catch (error) {
133 |         log.error('mouseGetPos failed', error);
134 |         return createErrorResponse(error instanceof Error ? error : String(error));
135 |       }
136 |     }
137 |   );
138 | 
139 |   // mouseGetCursor - Get the current mouse cursor type
140 |   server.tool(
141 |     'mouseGetCursor',
142 |     {},
143 |     async () => {
144 |       try {
145 |         log.verbose('mouseGetCursor called');
146 |         await autoIt.init();
147 |         const cursor = await autoIt.mouseGetCursor();
148 |         log.verbose('mouseGetCursor result', JSON.stringify(cursor));
149 |         return createToolResponse(`Mouse cursor type: ${cursor}`);
150 |       } catch (error) {
151 |         log.error('mouseGetCursor failed', error);
152 |         return createErrorResponse(error instanceof Error ? error : String(error));
153 |       }
154 |     }
155 |   );
156 | 
157 |   // mouseWheel - Scroll the mouse wheel
158 |   server.tool(
159 |     'mouseWheel',
160 |     {
161 |       direction: z.enum(['up', 'down']).describe('Scroll direction'),
162 |       clicks: z.number().min(1).describe('Number of clicks to scroll')
163 |     },
164 |     async ({ direction, clicks }) => {
165 |       try {
166 |         log.verbose('mouseWheel called', { direction, clicks });
167 |         await autoIt.init();
168 |         await autoIt.mouseWheel(direction, clicks);
169 |         return createToolResponse(`Mouse wheel scrolled ${direction} ${clicks} click(s)`);
170 |       } catch (error) {
171 |         log.error('mouseWheel failed', error);
172 |         return createErrorResponse(error instanceof Error ? error : String(error));
173 |       }
174 |     }
175 |   );
176 | }
177 | 
```

--------------------------------------------------------------------------------
/src/resources/index.ts:
--------------------------------------------------------------------------------

```typescript
  1 | /**
  2 |  * Resources module for MCP Windows Desktop Automation
  3 |  */
  4 | 
  5 | import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
  6 | import * as fs from 'fs/promises';
  7 | import * as path from 'path';
  8 | import * as autoIt from 'node-autoit-koffi';
  9 | import { log } from '../utils/logger/logger';
 10 | 
 11 | /**
 12 |  * Register all resources with the MCP server
 13 |  */
 14 | export function registerAllResources(server: McpServer): void {
 15 |   // Register file resources
 16 |   registerFileResources(server);
 17 |   
 18 |   // Register screenshot resources
 19 |   registerScreenshotResources(server);
 20 | }
 21 | 
 22 | /**
 23 |  * Register file resources
 24 |  */
 25 | function registerFileResources(server: McpServer): void {
 26 |   server.resource(
 27 |     'file',
 28 |     new ResourceTemplate('file://{path*}', { 
 29 |       list: async () => {
 30 |         return { resources: [] }; // Empty list by default
 31 |       }
 32 |     }),
 33 |     async (uri, params) => {
 34 |       try {
 35 |         // Ensure filePath is a string
 36 |         const filePath = Array.isArray(params.path) ? params.path.join('/') : params.path;
 37 |         log.verbose('Reading file resource', JSON.stringify({ uri: uri.href, filePath }));
 38 |         
 39 |         // Check if file exists
 40 |         const stats = await fs.stat(filePath);
 41 |         
 42 |         if (stats.isDirectory()) {
 43 |           // List directory contents
 44 |           const files = await fs.readdir(filePath);
 45 |           const resources = await Promise.all(
 46 |             files.map(async (file) => {
 47 |               const fullPath = path.join(filePath, file);
 48 |               const fileStats = await fs.stat(fullPath);
 49 |               return {
 50 |                 uri: `file://${fullPath.replace(/\\/g, '/')}`,
 51 |                 name: file,
 52 |                 description: fileStats.isDirectory() ? 'Directory' : 'File'
 53 |               };
 54 |             })
 55 |           );
 56 |           
 57 |           return {
 58 |             contents: [{
 59 |               uri: uri.href,
 60 |               text: `Directory: ${filePath}\n${files.join('\n')}`,
 61 |               mimeType: 'text/plain'
 62 |             }]
 63 |           };
 64 |         } else {
 65 |           // Read file content
 66 |           const content = await fs.readFile(filePath);
 67 |           const extension = path.extname(filePath).toLowerCase();
 68 |           
 69 |           // Determine if it's a text or binary file
 70 |           const isTextFile = [
 71 |             '.txt', '.md', '.js', '.ts', '.html', '.css', '.json', '.xml', 
 72 |             '.csv', '.log', '.ini', '.cfg', '.conf', '.py', '.c', '.cpp', 
 73 |             '.h', '.java', '.sh', '.bat', '.ps1'
 74 |           ].includes(extension);
 75 |           
 76 |           if (isTextFile) {
 77 |             return {
 78 |               contents: [{
 79 |                 uri: uri.href,
 80 |                 text: content.toString('utf-8'),
 81 |                 mimeType: getMimeType(extension)
 82 |               }]
 83 |             };
 84 |           } else {
 85 |             return {
 86 |               contents: [{
 87 |                 uri: uri.href,
 88 |                 blob: content.toString('base64'),
 89 |                 mimeType: getMimeType(extension)
 90 |               }]
 91 |             };
 92 |           }
 93 |         }
 94 |       } catch (error) {
 95 |         log.error('Error reading file resource', error);
 96 |         throw new Error(`Failed to read file: ${error instanceof Error ? error.message : String(error)}`);
 97 |       }
 98 |     }
 99 |   );
100 | }
101 | 
102 | /**
103 |  * Register screenshot resources
104 |  */
105 | function registerScreenshotResources(server: McpServer): void {
106 |   server.resource(
107 |     'screenshot',
108 |     new ResourceTemplate('screenshot://{window?}', { 
109 |       list: async () => {
110 |         return { resources: [] }; // Empty list by default
111 |       }
112 |     }),
113 |     async (uri, params) => {
114 |       try {
115 |         await autoIt.init();
116 |         // Ensure window is a string if provided
117 |         const windowName = params.window ? String(params.window) : undefined;
118 |         log.verbose('Taking screenshot', JSON.stringify({ uri: uri.href, window: windowName }));
119 |         
120 |         // If window parameter is provided, activate that window first
121 |         if (windowName) {
122 |           const windowExists = await autoIt.winExists(windowName);
123 |           if (windowExists) {
124 |             await autoIt.winActivate(windowName);
125 |             // Wait a moment for the window to activate
126 |             await new Promise(resolve => setTimeout(resolve, 500));
127 |           } else {
128 |             throw new Error(`Window "${windowName}" not found`);
129 |           }
130 |         }
131 |         
132 |         // TODO: Implement actual screenshot capture
133 |         // This is a placeholder - in a real implementation, you would use
134 |         // a library like 'screenshot-desktop' or other Windows API bindings
135 |         // to capture the screen or specific window
136 |         
137 |         // For now, we'll return a placeholder message
138 |         return {
139 |           contents: [{
140 |             uri: uri.href,
141 |             text: `Screenshot of ${windowName || 'full screen'} would be captured here`,
142 |             mimeType: 'text/plain'
143 |           }]
144 |         };
145 |         
146 |         // In a real implementation, you would return something like:
147 |         /*
148 |         return {
149 |           contents: [{
150 |             uri: uri.href,
151 |             blob: screenshotBase64Data,
152 |             mimeType: 'image/png'
153 |           }]
154 |         };
155 |         */
156 |       } catch (error) {
157 |         log.error('Error taking screenshot', error);
158 |         throw new Error(`Failed to take screenshot: ${error instanceof Error ? error.message : String(error)}`);
159 |       }
160 |     }
161 |   );
162 | }
163 | 
164 | /**
165 |  * Get MIME type based on file extension
166 |  */
167 | function getMimeType(extension: string): string {
168 |   const mimeTypes: Record<string, string> = {
169 |     '.txt': 'text/plain',
170 |     '.html': 'text/html',
171 |     '.css': 'text/css',
172 |     '.js': 'application/javascript',
173 |     '.ts': 'application/typescript',
174 |     '.json': 'application/json',
175 |     '.xml': 'application/xml',
176 |     '.md': 'text/markdown',
177 |     '.csv': 'text/csv',
178 |     '.png': 'image/png',
179 |     '.jpg': 'image/jpeg',
180 |     '.jpeg': 'image/jpeg',
181 |     '.gif': 'image/gif',
182 |     '.svg': 'image/svg+xml',
183 |     '.pdf': 'application/pdf',
184 |     '.doc': 'application/msword',
185 |     '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
186 |     '.xls': 'application/vnd.ms-excel',
187 |     '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
188 |     '.ppt': 'application/vnd.ms-powerpoint',
189 |     '.pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
190 |     '.zip': 'application/zip',
191 |     '.rar': 'application/x-rar-compressed',
192 |     '.7z': 'application/x-7z-compressed',
193 |     '.tar': 'application/x-tar',
194 |     '.gz': 'application/gzip'
195 |   };
196 |   
197 |   return mimeTypes[extension] || 'application/octet-stream';
198 | }
199 | 
```

--------------------------------------------------------------------------------
/src/prompts/index.ts:
--------------------------------------------------------------------------------

```typescript
  1 | /**
  2 |  * Prompts module for MCP Windows Desktop Automation
  3 |  */
  4 | 
  5 | import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
  6 | import { z } from 'zod';
  7 | import { log } from '../utils/logger/logger';
  8 | 
  9 | /**
 10 |  * Register all prompts with the MCP server
 11 |  */
 12 | export function registerAllPrompts(server: McpServer): void {
 13 |   // Register window interaction prompts
 14 |   registerWindowPrompts(server);
 15 |   
 16 |   // Register form filling prompts
 17 |   registerFormPrompts(server);
 18 |   
 19 |   // Register automation task prompts
 20 |   registerAutomationPrompts(server);
 21 | }
 22 | 
 23 | /**
 24 |  * Register window interaction prompts
 25 |  */
 26 | function registerWindowPrompts(server: McpServer): void {
 27 |   // Prompt for finding and interacting with a window
 28 |   server.prompt(
 29 |     'findWindow',
 30 |     {
 31 |       windowTitle: z.string().describe('Title or partial title of the window to find'),
 32 |       action: z.enum(['activate', 'close', 'minimize', 'maximize']).describe('Action to perform on the window')
 33 |     },
 34 |     ({ windowTitle, action }) => {
 35 |       log.verbose('findWindow prompt called', { windowTitle, action });
 36 |       
 37 |       let actionDescription: string;
 38 |       switch (action) {
 39 |         case 'activate':
 40 |           actionDescription = 'activate (bring to front)';
 41 |           break;
 42 |         case 'close':
 43 |           actionDescription = 'close';
 44 |           break;
 45 |         case 'minimize':
 46 |           actionDescription = 'minimize';
 47 |           break;
 48 |         case 'maximize':
 49 |           actionDescription = 'maximize';
 50 |           break;
 51 |       }
 52 |       
 53 |       return {
 54 |         description: `Find a window with title "${windowTitle}" and ${actionDescription} it`,
 55 |         messages: [
 56 |           {
 57 |             role: 'user',
 58 |             content: {
 59 |               type: 'text',
 60 |               text: `I need to find a window with the title "${windowTitle}" and ${actionDescription} it. Can you help me with the steps to do this using AutoIt functions?`
 61 |             }
 62 |           }
 63 |         ]
 64 |       };
 65 |     }
 66 |   );
 67 |   
 68 |   // Prompt for getting information about a window
 69 |   server.prompt(
 70 |     'windowInfo',
 71 |     {
 72 |       windowTitle: z.string().describe('Title or partial title of the window')
 73 |     },
 74 |     ({ windowTitle }) => {
 75 |       log.verbose('windowInfo prompt called', { windowTitle });
 76 |       
 77 |       return {
 78 |         description: `Get information about a window with title "${windowTitle}"`,
 79 |         messages: [
 80 |           {
 81 |             role: 'user',
 82 |             content: {
 83 |               type: 'text',
 84 |               text: `I need to get information about a window with the title "${windowTitle}". Can you help me retrieve details like its position, size, state, and text content using AutoIt functions?`
 85 |             }
 86 |           }
 87 |         ]
 88 |       };
 89 |     }
 90 |   );
 91 | }
 92 | 
 93 | /**
 94 |  * Register form filling prompts
 95 |  */
 96 | function registerFormPrompts(server: McpServer): void {
 97 |   // Prompt for filling out a form
 98 |   server.prompt(
 99 |     'fillForm',
100 |     {
101 |       windowTitle: z.string().describe('Title of the window containing the form'),
102 |       formFields: z.string().describe('Description of form fields and values to fill in')
103 |     },
104 |     ({ windowTitle, formFields }) => {
105 |       log.verbose('fillForm prompt called', { windowTitle, formFields });
106 |       
107 |       return {
108 |         description: `Fill out a form in window "${windowTitle}"`,
109 |         messages: [
110 |           {
111 |             role: 'user',
112 |             content: {
113 |               type: 'text',
114 |               text: `I need to fill out a form in a window with the title "${windowTitle}". The form has the following fields that need to be filled:\n\n${formFields}\n\nCan you help me automate filling out this form using AutoIt functions?`
115 |             }
116 |           }
117 |         ]
118 |       };
119 |     }
120 |   );
121 |   
122 |   // Prompt for submitting a form
123 |   server.prompt(
124 |     'submitForm',
125 |     {
126 |       windowTitle: z.string().describe('Title of the window containing the form'),
127 |       submitButtonText: z.string().describe('Text on the submit button')
128 |     },
129 |     ({ windowTitle, submitButtonText }) => {
130 |       log.verbose('submitForm prompt called', { windowTitle, submitButtonText });
131 |       
132 |       return {
133 |         description: `Submit a form in window "${windowTitle}"`,
134 |         messages: [
135 |           {
136 |             role: 'user',
137 |             content: {
138 |               type: 'text',
139 |               text: `I need to submit a form in a window with the title "${windowTitle}" by clicking the "${submitButtonText}" button. Can you help me automate this using AutoIt functions?`
140 |             }
141 |           }
142 |         ]
143 |       };
144 |     }
145 |   );
146 | }
147 | 
148 | /**
149 |  * Register automation task prompts
150 |  */
151 | function registerAutomationPrompts(server: McpServer): void {
152 |   // Prompt for automating a repetitive task
153 |   server.prompt(
154 |     'automateTask',
155 |     {
156 |       taskDescription: z.string().describe('Description of the repetitive task to automate'),
157 |       repetitions: z.string().describe('Number of times to repeat the task')
158 |     },
159 |     ({ taskDescription, repetitions }) => {
160 |       log.verbose('automateTask prompt called', { taskDescription, repetitions });
161 |       
162 |       return {
163 |         description: `Automate a repetitive task: ${taskDescription}`,
164 |         messages: [
165 |           {
166 |             role: 'user',
167 |             content: {
168 |               type: 'text',
169 |               text: `I need to automate the following repetitive task ${repetitions} times:\n\n${taskDescription}\n\nCan you help me create an automation script using AutoIt functions to accomplish this?`
170 |             }
171 |           }
172 |         ]
173 |       };
174 |     }
175 |   );
176 |   
177 |   // Prompt for monitoring a window or process
178 |   server.prompt(
179 |     'monitorWindow',
180 |     {
181 |       windowTitle: z.string().describe('Title of the window to monitor'),
182 |       condition: z.string().describe('Condition to monitor for (e.g., "appears", "disappears", "contains text X")')
183 |     },
184 |     ({ windowTitle, condition }) => {
185 |       log.verbose('monitorWindow prompt called', { windowTitle, condition });
186 |       
187 |       return {
188 |         description: `Monitor window "${windowTitle}" for condition: ${condition}`,
189 |         messages: [
190 |           {
191 |             role: 'user',
192 |             content: {
193 |               type: 'text',
194 |               text: `I need to monitor a window with the title "${windowTitle}" and wait until the following condition is met: ${condition}. Can you help me create an automation script using AutoIt functions to accomplish this?`
195 |             }
196 |           }
197 |         ]
198 |       };
199 |     }
200 |   );
201 |   
202 |   // Prompt for taking a screenshot
203 |   server.prompt(
204 |     'takeScreenshot',
205 |     {
206 |       target: z.enum(['fullscreen', 'window', 'region']).describe('What to capture in the screenshot'),
207 |       windowTitle: z.string().optional().describe('Title of the window to capture (if target is "window")')
208 |     },
209 |     ({ target, windowTitle }) => {
210 |       log.verbose('takeScreenshot prompt called', { target, windowTitle });
211 |       
212 |       let promptText: string;
213 |       if (target === 'fullscreen') {
214 |         promptText = 'I need to take a screenshot of the entire screen.';
215 |       } else if (target === 'window' && windowTitle) {
216 |         promptText = `I need to take a screenshot of a window with the title "${windowTitle}".`;
217 |       } else if (target === 'region') {
218 |         promptText = 'I need to take a screenshot of a specific region of the screen.';
219 |       } else {
220 |         promptText = 'I need to take a screenshot.';
221 |       }
222 |       
223 |       return {
224 |         description: `Take a screenshot of ${target === 'window' ? `window "${windowTitle}"` : target}`,
225 |         messages: [
226 |           {
227 |             role: 'user',
228 |             content: {
229 |               type: 'text',
230 |               text: `${promptText} Can you help me do this using AutoIt functions?`
231 |             }
232 |           }
233 |         ]
234 |       };
235 |     }
236 |   );
237 | }
238 | 
```

--------------------------------------------------------------------------------
/src/tools/process.ts:
--------------------------------------------------------------------------------

```typescript
  1 | /**
  2 |  * Process-related tools for MCP Windows Desktop Automation
  3 |  */
  4 | 
  5 | import * as autoIt from 'node-autoit-koffi';
  6 | import { z } from 'zod';
  7 | import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
  8 | import { createToolResponse, createErrorResponse, schemas } from '../utils/types';
  9 | import { log } from '../utils/logger/logger';
 10 | 
 11 | /**
 12 |  * Register process-related tools with the MCP server
 13 |  */
 14 | export function registerProcessTools(server: McpServer): void {
 15 |   // run - Run a program
 16 |   server.tool(
 17 |     'run',
 18 |     {
 19 |       program: z.string().describe('Program path or command'),
 20 |       workingDir: z.string().optional().describe('Working directory'),
 21 |       showFlag: z.number().optional().describe('Window show flag')
 22 |     },
 23 |     async ({ program, workingDir, showFlag }) => {
 24 |       try {
 25 |         log.verbose('run called', { program, workingDir, showFlag });
 26 |         await autoIt.init();
 27 |         const result = await autoIt.run(program, workingDir, showFlag);
 28 |         return createToolResponse(`Program "${program}" started with process ID: ${result}`);
 29 |       } catch (error) {
 30 |         log.error('run failed', error);
 31 |         return createErrorResponse(error instanceof Error ? error : String(error));
 32 |       }
 33 |     }
 34 |   );
 35 | 
 36 |   // runWait - Run a program and wait for it to complete
 37 |   server.tool(
 38 |     'runWait',
 39 |     {
 40 |       program: z.string().describe('Program path or command'),
 41 |       workingDir: z.string().optional().describe('Working directory'),
 42 |       showFlag: z.number().optional().describe('Window show flag')
 43 |     },
 44 |     async ({ program, workingDir, showFlag }) => {
 45 |       try {
 46 |         log.verbose('runWait called', { program, workingDir, showFlag });
 47 |         await autoIt.init();
 48 |         const result = await autoIt.runWait(program, workingDir, showFlag);
 49 |         return createToolResponse(`Program "${program}" completed with exit code: ${result}`);
 50 |       } catch (error) {
 51 |         log.error('runWait failed', error);
 52 |         return createErrorResponse(error instanceof Error ? error : String(error));
 53 |       }
 54 |     }
 55 |   );
 56 | 
 57 |   // runAs - Run a program as a different user
 58 |   server.tool(
 59 |     'runAs',
 60 |     {
 61 |       user: z.string().describe('Username'),
 62 |       domain: z.string().describe('Domain'),
 63 |       password: z.string().describe('Password'),
 64 |       logonFlag: z.number().describe('Logon flag'),
 65 |       program: z.string().describe('Program path or command'),
 66 |       workingDir: z.string().optional().describe('Working directory'),
 67 |       showFlag: z.number().optional().describe('Window show flag')
 68 |     },
 69 |     async ({ user, domain, password, logonFlag, program, workingDir, showFlag }) => {
 70 |       try {
 71 |         log.verbose('runAs called', { user, domain, logonFlag, program, workingDir, showFlag });
 72 |         await autoIt.init();
 73 |         const result = await autoIt.runAs(user, domain, password, logonFlag, program, workingDir, showFlag);
 74 |         return createToolResponse(`Program "${program}" started as user "${user}" with process ID: ${result}`);
 75 |       } catch (error) {
 76 |         log.error('runAs failed', error);
 77 |         return createErrorResponse(error instanceof Error ? error : String(error));
 78 |       }
 79 |     }
 80 |   );
 81 | 
 82 |   // runAsWait - Run a program as a different user and wait for it to complete
 83 |   server.tool(
 84 |     'runAsWait',
 85 |     {
 86 |       user: z.string().describe('Username'),
 87 |       domain: z.string().describe('Domain'),
 88 |       password: z.string().describe('Password'),
 89 |       logonFlag: z.number().describe('Logon flag'),
 90 |       program: z.string().describe('Program path or command'),
 91 |       workingDir: z.string().optional().describe('Working directory'),
 92 |       showFlag: z.number().optional().describe('Window show flag')
 93 |     },
 94 |     async ({ user, domain, password, logonFlag, program, workingDir, showFlag }) => {
 95 |       try {
 96 |         log.verbose('runAsWait called', { user, domain, logonFlag, program, workingDir, showFlag });
 97 |         await autoIt.init();
 98 |         const result = await autoIt.runAsWait(user, domain, password, logonFlag, program, workingDir, showFlag);
 99 |         return createToolResponse(`Program "${program}" completed as user "${user}" with exit code: ${result}`);
100 |       } catch (error) {
101 |         log.error('runAsWait failed', error);
102 |         return createErrorResponse(error instanceof Error ? error : String(error));
103 |       }
104 |     }
105 |   );
106 | 
107 |   // processExists - Check if a process exists
108 |   server.tool(
109 |     'processExists',
110 |     {
111 |       process: schemas.processName
112 |     },
113 |     async ({ process }) => {
114 |       try {
115 |         log.verbose('processExists called', { process });
116 |         await autoIt.init();
117 |         const result = await autoIt.processExists(process);
118 |         const exists = result !== 0;
119 |         return createToolResponse(
120 |           exists
121 |             ? `Process "${process}" exists with PID: ${result}`
122 |             : `Process "${process}" does not exist`
123 |         );
124 |       } catch (error) {
125 |         log.error('processExists failed', error);
126 |         return createErrorResponse(error instanceof Error ? error : String(error));
127 |       }
128 |     }
129 |   );
130 | 
131 |   // processClose - Close a process
132 |   server.tool(
133 |     'processClose',
134 |     {
135 |       process: schemas.processName
136 |     },
137 |     async ({ process }) => {
138 |       try {
139 |         log.verbose('processClose called', { process });
140 |         await autoIt.init();
141 |         const result = await autoIt.processClose(process);
142 |         const success = result === 1;
143 |         return createToolResponse(
144 |           success
145 |             ? `Process "${process}" closed successfully`
146 |             : `Failed to close process "${process}"`
147 |         );
148 |       } catch (error) {
149 |         log.error('processClose failed', error);
150 |         return createErrorResponse(error instanceof Error ? error : String(error));
151 |       }
152 |     }
153 |   );
154 | 
155 |   // processSetPriority - Set process priority
156 |   server.tool(
157 |     'processSetPriority',
158 |     {
159 |       process: schemas.processName,
160 |       priority: z.number().describe('Priority level (0-4)')
161 |     },
162 |     async ({ process, priority }) => {
163 |       try {
164 |         log.verbose('processSetPriority called', { process, priority });
165 |         await autoIt.init();
166 |         const result = await autoIt.processSetPriority(process, priority);
167 |         const success = result === 1;
168 |         return createToolResponse(
169 |           success
170 |             ? `Priority for process "${process}" set to ${priority}`
171 |             : `Failed to set priority for process "${process}"`
172 |         );
173 |       } catch (error) {
174 |         log.error('processSetPriority failed', error);
175 |         return createErrorResponse(error instanceof Error ? error : String(error));
176 |       }
177 |     }
178 |   );
179 | 
180 |   // processWait - Wait for a process to exist
181 |   server.tool(
182 |     'processWait',
183 |     {
184 |       process: schemas.processName,
185 |       timeout: schemas.processTimeout
186 |     },
187 |     async ({ process, timeout }) => {
188 |       try {
189 |         log.verbose('processWait called', { process, timeout });
190 |         await autoIt.init();
191 |         const result = await autoIt.processWait(process, timeout);
192 |         const success = result !== 0;
193 |         return createToolResponse(
194 |           success
195 |             ? `Process "${process}" exists with PID: ${result}`
196 |             : `Timed out waiting for process "${process}"`
197 |         );
198 |       } catch (error) {
199 |         log.error('processWait failed', error);
200 |         return createErrorResponse(error instanceof Error ? error : String(error));
201 |       }
202 |     }
203 |   );
204 | 
205 |   // processWaitClose - Wait for a process to close
206 |   server.tool(
207 |     'processWaitClose',
208 |     {
209 |       process: schemas.processName,
210 |       timeout: schemas.processTimeout
211 |     },
212 |     async ({ process, timeout }) => {
213 |       try {
214 |         log.verbose('processWaitClose called', { process, timeout });
215 |         await autoIt.init();
216 |         const result = await autoIt.processWaitClose(process, timeout);
217 |         const success = result === 1;
218 |         return createToolResponse(
219 |           success
220 |             ? `Process "${process}" closed within the timeout`
221 |             : `Timed out waiting for process "${process}" to close`
222 |         );
223 |       } catch (error) {
224 |         log.error('processWaitClose failed', error);
225 |         return createErrorResponse(error instanceof Error ? error : String(error));
226 |       }
227 |     }
228 |   );
229 | 
230 |   // shutdown - Shut down the system
231 |   server.tool(
232 |     'shutdown',
233 |     {
234 |       flags: z.number().describe('Shutdown flags')
235 |     },
236 |     async ({ flags }) => {
237 |       try {
238 |         log.verbose('shutdown called', { flags });
239 |         await autoIt.init();
240 |         const result = await autoIt.shutdown(flags);
241 |         const success = result === 1;
242 |         return createToolResponse(
243 |           success
244 |             ? `System shutdown initiated with flags: ${flags}`
245 |             : `Failed to initiate system shutdown`
246 |         );
247 |       } catch (error) {
248 |         log.error('shutdown failed', error);
249 |         return createErrorResponse(error instanceof Error ? error : String(error));
250 |       }
251 |     }
252 |   );
253 | }
254 | 
```

--------------------------------------------------------------------------------
/src/tools/window.ts:
--------------------------------------------------------------------------------

```typescript
  1 | /**
  2 |  * Window-related tools for MCP Windows Desktop Automation
  3 |  */
  4 | 
  5 | import * as autoIt from 'node-autoit-koffi';
  6 | import { z } from 'zod';
  7 | import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
  8 | import { createToolResponse, createErrorResponse, schemas } from '../utils/types';
  9 | import { log } from '../utils/logger/logger';
 10 | 
 11 | /**
 12 |  * Register window-related tools with the MCP server
 13 |  */
 14 | export function registerWindowTools(server: McpServer): void {
 15 |   // winActivate - Activate a window
 16 |   server.tool(
 17 |     'winActivate',
 18 |     {
 19 |       title: schemas.windowTitle,
 20 |       text: schemas.windowText
 21 |     },
 22 |     async ({ title, text }) => {
 23 |       try {
 24 |         log.verbose('winActivate called', { title, text });
 25 |         await autoIt.init();
 26 |         const result = await autoIt.winActivate(title, text);
 27 |         return createToolResponse(`Window "${title}" activated with result: ${result}`);
 28 |       } catch (error) {
 29 |         log.error('winActivate failed', error);
 30 |         return createErrorResponse(error instanceof Error ? error : String(error));
 31 |       }
 32 |     }
 33 |   );
 34 | 
 35 |   // winActivateByHandle - Activate a window by handle
 36 |   server.tool(
 37 |     'winActivateByHandle',
 38 |     {
 39 |       handle: schemas.handle
 40 |     },
 41 |     async ({ handle }) => {
 42 |       try {
 43 |         log.verbose('winActivateByHandle called', { handle });
 44 |         await autoIt.init();
 45 |         const result = await autoIt.winActivateByHandle(handle);
 46 |         return createToolResponse(`Window with handle ${handle} activated with result: ${result}`);
 47 |       } catch (error) {
 48 |         log.error('winActivateByHandle failed', error);
 49 |         return createErrorResponse(error instanceof Error ? error : String(error));
 50 |       }
 51 |     }
 52 |   );
 53 | 
 54 |   // winActive - Check if a window is active
 55 |   server.tool(
 56 |     'winActive',
 57 |     {
 58 |       title: schemas.windowTitle,
 59 |       text: z.string().describe('Window text')
 60 |     },
 61 |     async ({ title, text }) => {
 62 |       try {
 63 |         log.verbose('winActive called', { title, text });
 64 |         await autoIt.init();
 65 |         const result = await autoIt.winActive(title, text);
 66 |         const isActive = result === 1;
 67 |         return createToolResponse(`Window "${title}" is ${isActive ? 'active' : 'not active'}`);
 68 |       } catch (error) {
 69 |         log.error('winActive failed', error);
 70 |         return createErrorResponse(error instanceof Error ? error : String(error));
 71 |       }
 72 |     }
 73 |   );
 74 | 
 75 |   // winClose - Close a window
 76 |   server.tool(
 77 |     'winClose',
 78 |     {
 79 |       title: schemas.windowTitle,
 80 |       text: schemas.windowText
 81 |     },
 82 |     async ({ title, text }) => {
 83 |       try {
 84 |         log.verbose('winClose called', { title, text });
 85 |         await autoIt.init();
 86 |         const result = await autoIt.winClose(title, text);
 87 |         return createToolResponse(`Window "${title}" closed with result: ${result}`);
 88 |       } catch (error) {
 89 |         log.error('winClose failed', error);
 90 |         return createErrorResponse(error instanceof Error ? error : String(error));
 91 |       }
 92 |     }
 93 |   );
 94 | 
 95 |   // winExists - Check if a window exists
 96 |   server.tool(
 97 |     'winExists',
 98 |     {
 99 |       title: schemas.windowTitle,
100 |       text: schemas.windowText
101 |     },
102 |     async ({ title, text }) => {
103 |       try {
104 |         log.verbose('winExists called', { title, text });
105 |         await autoIt.init();
106 |         const result = await autoIt.winExists(title, text);
107 |         const exists = result === 1;
108 |         return createToolResponse(`Window "${title}" ${exists ? 'exists' : 'does not exist'}`);
109 |       } catch (error) {
110 |         log.error('winExists failed', error);
111 |         return createErrorResponse(error instanceof Error ? error : String(error));
112 |       }
113 |     }
114 |   );
115 | 
116 |   // winGetHandle - Get a window handle
117 |   server.tool(
118 |     'winGetHandle',
119 |     {
120 |       title: schemas.windowTitle,
121 |       text: schemas.windowText
122 |     },
123 |     async ({ title, text }) => {
124 |       try {
125 |         log.verbose('winGetHandle called', { title, text });
126 |         await autoIt.init();
127 |         const handle = await autoIt.winGetHandle(title, text);
128 |         log.verbose('winGetHandle result', JSON.stringify({ handle }));
129 |         return createToolResponse(`Window "${title}" handle: ${handle}`);
130 |       } catch (error) {
131 |         log.error('winGetHandle failed', error);
132 |         return createErrorResponse(error instanceof Error ? error : String(error));
133 |       }
134 |     }
135 |   );
136 | 
137 |   // winGetPos - Get window position and size
138 |   server.tool(
139 |     'winGetPos',
140 |     {
141 |       title: schemas.windowTitle,
142 |       text: schemas.windowText
143 |     },
144 |     async ({ title, text }) => {
145 |       try {
146 |         log.verbose('winGetPos called', { title, text });
147 |         await autoIt.init();
148 |         const rect = await autoIt.winGetPos(title, text);
149 |         log.verbose('winGetPos result', JSON.stringify(rect));
150 |         const width = rect.right - rect.left;
151 |         const height = rect.bottom - rect.top;
152 |         return createToolResponse(
153 |           `Window "${title}" position: Left=${rect.left}, Top=${rect.top}, Width=${width}, Height=${height}`
154 |         );
155 |       } catch (error) {
156 |         log.error('winGetPos failed', error);
157 |         return createErrorResponse(error instanceof Error ? error : String(error));
158 |       }
159 |     }
160 |   );
161 | 
162 |   // winGetText - Get window text
163 |   server.tool(
164 |     'winGetText',
165 |     {
166 |       title: schemas.windowTitle,
167 |       text: schemas.windowText,
168 |       bufSize: schemas.bufferSize
169 |     },
170 |     async ({ title, text, bufSize }) => {
171 |       try {
172 |         log.verbose('winGetText called', { title, text, bufSize });
173 |         await autoIt.init();
174 |         const windowText = await autoIt.winGetText(title, text, bufSize);
175 |         log.verbose('winGetText result', JSON.stringify({ windowText }));
176 |         return createToolResponse(`Window "${title}" text: "${windowText}"`);
177 |       } catch (error) {
178 |         log.error('winGetText failed', error);
179 |         return createErrorResponse(error instanceof Error ? error : String(error));
180 |       }
181 |     }
182 |   );
183 | 
184 |   // winGetTitle - Get window title
185 |   server.tool(
186 |     'winGetTitle',
187 |     {
188 |       title: schemas.windowTitle,
189 |       text: schemas.windowText,
190 |       bufSize: schemas.bufferSize
191 |     },
192 |     async ({ title, text, bufSize }) => {
193 |       try {
194 |         log.verbose('winGetTitle called', { title, text, bufSize });
195 |         await autoIt.init();
196 |         const windowTitle = await autoIt.winGetTitle(title, text, bufSize);
197 |         log.verbose('winGetTitle result', JSON.stringify({ windowTitle }));
198 |         return createToolResponse(`Window "${title}" title: "${windowTitle}"`);
199 |       } catch (error) {
200 |         log.error('winGetTitle failed', error);
201 |         return createErrorResponse(error instanceof Error ? error : String(error));
202 |       }
203 |     }
204 |   );
205 | 
206 |   // winMove - Move and resize a window
207 |   server.tool(
208 |     'winMove',
209 |     {
210 |       title: schemas.windowTitle,
211 |       text: schemas.windowText,
212 |       x: z.number().describe('X coordinate'),
213 |       y: z.number().describe('Y coordinate'),
214 |       width: z.number().optional().describe('Window width'),
215 |       height: z.number().optional().describe('Window height')
216 |     },
217 |     async ({ title, text, x, y, width, height }) => {
218 |       try {
219 |         log.verbose('winMove called', { title, text, x, y, width, height });
220 |         await autoIt.init();
221 |         const result = await autoIt.winMove(title, text, x, y, width, height);
222 |         const sizeInfo = width && height ? ` and resized to ${width}x${height}` : '';
223 |         return createToolResponse(`Window "${title}" moved to (${x}, ${y})${sizeInfo} with result: ${result}`);
224 |       } catch (error) {
225 |         log.error('winMove failed', error);
226 |         return createErrorResponse(error instanceof Error ? error : String(error));
227 |       }
228 |     }
229 |   );
230 | 
231 |   // winSetState - Set window state (minimized, maximized, etc.)
232 |   server.tool(
233 |     'winSetState',
234 |     {
235 |       title: schemas.windowTitle,
236 |       text: schemas.windowText,
237 |       flags: z.number().describe('State flags')
238 |     },
239 |     async ({ title, text, flags }) => {
240 |       try {
241 |         log.verbose('winSetState called', { title, text, flags });
242 |         await autoIt.init();
243 |         const result = await autoIt.winSetState(title, text, flags);
244 |         return createToolResponse(`Window "${title}" state set to ${flags} with result: ${result}`);
245 |       } catch (error) {
246 |         log.error('winSetState failed', error);
247 |         return createErrorResponse(error instanceof Error ? error : String(error));
248 |       }
249 |     }
250 |   );
251 | 
252 |   // winWait - Wait for a window to exist
253 |   server.tool(
254 |     'winWait',
255 |     {
256 |       title: schemas.windowTitle,
257 |       text: schemas.windowText,
258 |       timeout: z.number().optional().describe('Timeout in seconds')
259 |     },
260 |     async ({ title, text, timeout }) => {
261 |       try {
262 |         log.verbose('winWait called', { title, text, timeout });
263 |         await autoIt.init();
264 |         const result = await autoIt.winWait(title, text, timeout);
265 |         const success = result === 1;
266 |         return createToolResponse(
267 |           success
268 |             ? `Window "${title}" appeared within the timeout`
269 |             : `Window "${title}" did not appear within the timeout`
270 |         );
271 |       } catch (error) {
272 |         log.error('winWait failed', error);
273 |         return createErrorResponse(error instanceof Error ? error : String(error));
274 |       }
275 |     }
276 |   );
277 | 
278 |   // winWaitActive - Wait for a window to be active
279 |   server.tool(
280 |     'winWaitActive',
281 |     {
282 |       title: schemas.windowTitle,
283 |       text: schemas.windowText,
284 |       timeout: z.number().optional().describe('Timeout in seconds')
285 |     },
286 |     async ({ title, text, timeout }) => {
287 |       try {
288 |         log.verbose('winWaitActive called', { title, text, timeout });
289 |         await autoIt.init();
290 |         const result = await autoIt.winWaitActive(title, text, timeout);
291 |         const success = result === 1;
292 |         return createToolResponse(
293 |           success
294 |             ? `Window "${title}" became active within the timeout`
295 |             : `Window "${title}" did not become active within the timeout`
296 |         );
297 |       } catch (error) {
298 |         log.error('winWaitActive failed', error);
299 |         return createErrorResponse(error instanceof Error ? error : String(error));
300 |       }
301 |     }
302 |   );
303 | 
304 |   // winWaitClose - Wait for a window to close
305 |   server.tool(
306 |     'winWaitClose',
307 |     {
308 |       title: schemas.windowTitle,
309 |       text: schemas.windowText,
310 |       timeout: z.number().optional().describe('Timeout in seconds')
311 |     },
312 |     async ({ title, text, timeout }) => {
313 |       try {
314 |         log.verbose('winWaitClose called', { title, text, timeout });
315 |         await autoIt.init();
316 |         const result = await autoIt.winWaitClose(title, text, timeout);
317 |         const success = result === 1;
318 |         return createToolResponse(
319 |           success
320 |             ? `Window "${title}" closed within the timeout`
321 |             : `Window "${title}" did not close within the timeout`
322 |         );
323 |       } catch (error) {
324 |         log.error('winWaitClose failed', error);
325 |         return createErrorResponse(error instanceof Error ? error : String(error));
326 |       }
327 |     }
328 |   );
329 | }
330 | 
```

--------------------------------------------------------------------------------
/src/tools/control.ts:
--------------------------------------------------------------------------------

```typescript
  1 | /**
  2 |  * Control-related tools for MCP Windows Desktop Automation
  3 |  */
  4 | 
  5 | import * as autoIt from 'node-autoit-koffi';
  6 | import { z } from 'zod';
  7 | import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
  8 | import { createToolResponse, createErrorResponse, schemas } from '../utils/types';
  9 | import { log } from '../utils/logger/logger';
 10 | 
 11 | /**
 12 |  * Register control-related tools with the MCP server
 13 |  */
 14 | export function registerControlTools(server: McpServer): void {
 15 |   // controlClick - Click on a control
 16 |   server.tool(
 17 |     'controlClick',
 18 |     {
 19 |       title: schemas.windowTitle,
 20 |       text: schemas.windowText,
 21 |       control: schemas.controlName,
 22 |       button: schemas.mouseButton,
 23 |       clicks: schemas.mouseClicks,
 24 |       x: z.number().optional().describe('X coordinate within control'),
 25 |       y: z.number().optional().describe('Y coordinate within control')
 26 |     },
 27 |     async ({ title, text, control, button, clicks, x, y }) => {
 28 |       try {
 29 |         log.verbose('controlClick called', { title, text, control, button, clicks, x, y });
 30 |         await autoIt.init();
 31 |         const result = await autoIt.controlClick(title, text, control, button, clicks, x, y);
 32 |         const success = result === 1;
 33 |         return createToolResponse(
 34 |           success
 35 |             ? `Clicked on control "${control}" in window "${title}"`
 36 |             : `Failed to click on control "${control}" in window "${title}"`
 37 |         );
 38 |       } catch (error) {
 39 |         log.error('controlClick failed', error);
 40 |         return createErrorResponse(error instanceof Error ? error : String(error));
 41 |       }
 42 |     }
 43 |   );
 44 | 
 45 |   // controlClickByHandle - Click on a control by handle
 46 |   server.tool(
 47 |     'controlClickByHandle',
 48 |     {
 49 |       windowHandle: schemas.handle,
 50 |       controlHandle: schemas.handle,
 51 |       button: schemas.mouseButton,
 52 |       clicks: schemas.mouseClicks,
 53 |       x: z.number().optional().describe('X coordinate within control'),
 54 |       y: z.number().optional().describe('Y coordinate within control')
 55 |     },
 56 |     async ({ windowHandle, controlHandle, button, clicks, x, y }) => {
 57 |       try {
 58 |         log.verbose('controlClickByHandle called', { windowHandle, controlHandle, button, clicks, x, y });
 59 |         await autoIt.init();
 60 |         const result = await autoIt.controlClickByHandle(windowHandle, controlHandle, button, clicks, x, y);
 61 |         const success = result === 1;
 62 |         return createToolResponse(
 63 |           success
 64 |             ? `Clicked on control handle ${controlHandle} in window handle ${windowHandle}`
 65 |             : `Failed to click on control handle ${controlHandle} in window handle ${windowHandle}`
 66 |         );
 67 |       } catch (error) {
 68 |         log.error('controlClickByHandle failed', error);
 69 |         return createErrorResponse(error instanceof Error ? error : String(error));
 70 |       }
 71 |     }
 72 |   );
 73 | 
 74 |   // controlCommand - Send a command to a control
 75 |   server.tool(
 76 |     'controlCommand',
 77 |     {
 78 |       title: schemas.windowTitle,
 79 |       text: schemas.windowText,
 80 |       control: schemas.controlName,
 81 |       command: z.string().describe('Command to send'),
 82 |       extra: z.string().optional().describe('Extra parameter for the command'),
 83 |       bufSize: schemas.bufferSize
 84 |     },
 85 |     async ({ title, text, control, command, extra, bufSize }) => {
 86 |       try {
 87 |         log.verbose('controlCommand called', { title, text, control, command, extra, bufSize });
 88 |         await autoIt.init();
 89 |         const result = await autoIt.controlCommand(title, text, control, command, extra, bufSize);
 90 |         log.verbose('controlCommand result', JSON.stringify({ result }));
 91 |         return createToolResponse(`Command "${command}" sent to control "${control}" with result: ${result}`);
 92 |       } catch (error) {
 93 |         log.error('controlCommand failed', error);
 94 |         return createErrorResponse(error instanceof Error ? error : String(error));
 95 |       }
 96 |     }
 97 |   );
 98 | 
 99 |   // controlGetText - Get text from a control
100 |   server.tool(
101 |     'controlGetText',
102 |     {
103 |       title: schemas.windowTitle,
104 |       text: schemas.windowText,
105 |       control: schemas.controlName,
106 |       bufSize: schemas.bufferSize
107 |     },
108 |     async ({ title, text, control, bufSize }) => {
109 |       try {
110 |         log.verbose('controlGetText called', { title, text, control, bufSize });
111 |         await autoIt.init();
112 |         const controlText = await autoIt.controlGetText(title, text, control, bufSize);
113 |         log.verbose('controlGetText result', JSON.stringify({ controlText }));
114 |         return createToolResponse(`Text from control "${control}": "${controlText}"`);
115 |       } catch (error) {
116 |         log.error('controlGetText failed', error);
117 |         return createErrorResponse(error instanceof Error ? error : String(error));
118 |       }
119 |     }
120 |   );
121 | 
122 |   // controlSetText - Set text in a control
123 |   server.tool(
124 |     'controlSetText',
125 |     {
126 |       title: schemas.windowTitle,
127 |       text: schemas.windowText,
128 |       control: schemas.controlName,
129 |       controlText: schemas.controlText
130 |     },
131 |     async ({ title, text, control, controlText }) => {
132 |       try {
133 |         log.verbose('controlSetText called', { title, text, control, controlText });
134 |         await autoIt.init();
135 |         const result = await autoIt.controlSetText(title, text, control, controlText);
136 |         const success = result === 1;
137 |         return createToolResponse(
138 |           success
139 |             ? `Text set in control "${control}" to "${controlText}"`
140 |             : `Failed to set text in control "${control}"`
141 |         );
142 |       } catch (error) {
143 |         log.error('controlSetText failed', error);
144 |         return createErrorResponse(error instanceof Error ? error : String(error));
145 |       }
146 |     }
147 |   );
148 | 
149 |   // controlSend - Send keystrokes to a control
150 |   server.tool(
151 |     'controlSend',
152 |     {
153 |       title: schemas.windowTitle,
154 |       text: schemas.windowText,
155 |       control: schemas.controlName,
156 |       sendText: schemas.controlText,
157 |       mode: z.number().optional().describe('Send mode flag')
158 |     },
159 |     async ({ title, text, control, sendText, mode }) => {
160 |       try {
161 |         log.verbose('controlSend called', { title, text, control, sendText, mode });
162 |         await autoIt.init();
163 |         const result = await autoIt.controlSend(title, text, control, sendText, mode);
164 |         const success = result === 1;
165 |         return createToolResponse(
166 |           success
167 |             ? `Keystrokes "${sendText}" sent to control "${control}"`
168 |             : `Failed to send keystrokes to control "${control}"`
169 |         );
170 |       } catch (error) {
171 |         log.error('controlSend failed', error);
172 |         return createErrorResponse(error instanceof Error ? error : String(error));
173 |       }
174 |     }
175 |   );
176 | 
177 |   // controlFocus - Set focus to a control
178 |   server.tool(
179 |     'controlFocus',
180 |     {
181 |       title: schemas.windowTitle,
182 |       text: schemas.windowText,
183 |       control: schemas.controlName
184 |     },
185 |     async ({ title, text, control }) => {
186 |       try {
187 |         log.verbose('controlFocus called', { title, text, control });
188 |         await autoIt.init();
189 |         const result = await autoIt.controlFocus(title, text, control);
190 |         const success = result === 1;
191 |         return createToolResponse(
192 |           success
193 |             ? `Focus set to control "${control}"`
194 |             : `Failed to set focus to control "${control}"`
195 |         );
196 |       } catch (error) {
197 |         log.error('controlFocus failed', error);
198 |         return createErrorResponse(error instanceof Error ? error : String(error));
199 |       }
200 |     }
201 |   );
202 | 
203 |   // controlGetHandle - Get a control handle
204 |   server.tool(
205 |     'controlGetHandle',
206 |     {
207 |       windowHandle: schemas.handle,
208 |       control: schemas.controlName
209 |     },
210 |     async ({ windowHandle, control }) => {
211 |       try {
212 |         log.verbose('controlGetHandle called', { windowHandle, control });
213 |         await autoIt.init();
214 |         const handle = await autoIt.controlGetHandle(windowHandle, control);
215 |         log.verbose('controlGetHandle result', JSON.stringify({ handle }));
216 |         return createToolResponse(`Control "${control}" handle: ${handle}`);
217 |       } catch (error) {
218 |         log.error('controlGetHandle failed', error);
219 |         return createErrorResponse(error instanceof Error ? error : String(error));
220 |       }
221 |     }
222 |   );
223 | 
224 |   // controlGetPos - Get control position and size
225 |   server.tool(
226 |     'controlGetPos',
227 |     {
228 |       title: schemas.windowTitle,
229 |       text: schemas.windowText,
230 |       control: schemas.controlName
231 |     },
232 |     async ({ title, text, control }) => {
233 |       try {
234 |         log.verbose('controlGetPos called', { title, text, control });
235 |         await autoIt.init();
236 |         const rect = await autoIt.controlGetPos(title, text, control);
237 |         log.verbose('controlGetPos result', JSON.stringify(rect));
238 |         const width = rect.right - rect.left;
239 |         const height = rect.bottom - rect.top;
240 |         return createToolResponse(
241 |           `Control "${control}" position: Left=${rect.left}, Top=${rect.top}, Width=${width}, Height=${height}`
242 |         );
243 |       } catch (error) {
244 |         log.error('controlGetPos failed', error);
245 |         return createErrorResponse(error instanceof Error ? error : String(error));
246 |       }
247 |     }
248 |   );
249 | 
250 |   // controlMove - Move and resize a control
251 |   server.tool(
252 |     'controlMove',
253 |     {
254 |       title: schemas.windowTitle,
255 |       text: schemas.windowText,
256 |       control: schemas.controlName,
257 |       x: z.number().describe('X coordinate'),
258 |       y: z.number().describe('Y coordinate'),
259 |       width: z.number().optional().describe('Control width'),
260 |       height: z.number().optional().describe('Control height')
261 |     },
262 |     async ({ title, text, control, x, y, width, height }) => {
263 |       try {
264 |         log.verbose('controlMove called', { title, text, control, x, y, width, height });
265 |         await autoIt.init();
266 |         const result = await autoIt.controlMove(title, text, control, x, y, width, height);
267 |         const success = result === 1;
268 |         const sizeInfo = width && height ? ` and resized to ${width}x${height}` : '';
269 |         return createToolResponse(
270 |           success
271 |             ? `Control "${control}" moved to (${x}, ${y})${sizeInfo}`
272 |             : `Failed to move control "${control}"`
273 |         );
274 |       } catch (error) {
275 |         log.error('controlMove failed', error);
276 |         return createErrorResponse(error instanceof Error ? error : String(error));
277 |       }
278 |     }
279 |   );
280 | 
281 |   // controlShow - Show a control
282 |   server.tool(
283 |     'controlShow',
284 |     {
285 |       title: schemas.windowTitle,
286 |       text: schemas.windowText,
287 |       control: schemas.controlName
288 |     },
289 |     async ({ title, text, control }) => {
290 |       try {
291 |         log.verbose('controlShow called', { title, text, control });
292 |         await autoIt.init();
293 |         const result = await autoIt.controlShow(title, text, control);
294 |         const success = result === 1;
295 |         return createToolResponse(
296 |           success
297 |             ? `Control "${control}" shown`
298 |             : `Failed to show control "${control}"`
299 |         );
300 |       } catch (error) {
301 |         log.error('controlShow failed', error);
302 |         return createErrorResponse(error instanceof Error ? error : String(error));
303 |       }
304 |     }
305 |   );
306 | 
307 |   // controlHide - Hide a control
308 |   server.tool(
309 |     'controlHide',
310 |     {
311 |       title: schemas.windowTitle,
312 |       text: schemas.windowText,
313 |       control: schemas.controlName
314 |     },
315 |     async ({ title, text, control }) => {
316 |       try {
317 |         log.verbose('controlHide called', { title, text, control });
318 |         await autoIt.init();
319 |         const result = await autoIt.controlHide(title, text, control);
320 |         const success = result === 1;
321 |         return createToolResponse(
322 |           success
323 |             ? `Control "${control}" hidden`
324 |             : `Failed to hide control "${control}"`
325 |         );
326 |       } catch (error) {
327 |         log.error('controlHide failed', error);
328 |         return createErrorResponse(error instanceof Error ? error : String(error));
329 |       }
330 |     }
331 |   );
332 | }
333 | 
```