#
tokens: 16238/50000 16/16 files
lines: off (toggle) GitHub
raw markdown copy
# 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:
--------------------------------------------------------------------------------

```
# Auto detect text files and perform LF normalization
* text=auto

```

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

```
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)
web_modules/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional stylelint cache
.stylelintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache

# Next.js build output
.next
out

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# vuepress v2.x temp and cache directory
.temp
.cache

# Docusaurus cache and generated files
.docusaurus

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

```

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

```markdown
# MCP Windows Desktop Automation

A Model Context Protocol (MCP) server for Windows desktop automation using AutoIt.

## Overview

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.

The server exposes:
- **Tools**: All AutoIt functions as MCP tools
- **Resources**: File access and screenshot capabilities
- **Prompts**: Templates for common automation tasks

## Features

- Full wrapping of all AutoIt functions as MCP tools
- Support for both stdio and WebSocket transports
- File access resources for reading files and directories
- Screenshot resources for capturing the screen or specific windows
- Prompt templates for common automation tasks
- Strict TypeScript typing throughout

## Installation

```bash
# Clone the repository
git clone https://github.com/yourusername/mcp-windows-desktop-automation.git
cd mcp-windows-desktop-automation

# Install dependencies
npm install

# Build the project
npm run build
```

## Usage

### Starting the Server

```bash
# Start with stdio transport (default)
npm start

# Start with WebSocket transport
npm start -- --transport=websocket --port=3000

# Enable verbose logging
npm start -- --verbose
```

### Command Line Options

- `--transport=stdio|websocket`: Specify the transport protocol (default: stdio)
- `--port=<number>`: Specify the port for WebSocket transport (default: 3000)
- `--verbose`: Enable verbose logging

## Tools

The server provides tools for:

- **Mouse operations**: Move, click, drag, etc.
- **Keyboard operations**: Send keystrokes, clipboard operations, etc.
- **Window management**: Find, activate, close, resize windows, etc.
- **Control manipulation**: Interact with UI controls, buttons, text fields, etc.
- **Process management**: Start, stop, and monitor processes
- **System operations**: Shutdown, sleep, etc.

## Resources

The server provides resources for:

- **File access**: Read files and list directories
- **Screenshots**: Capture the screen or specific windows

## Prompts

The server provides prompt templates for:

- **Window interaction**: Find and interact with windows
- **Form filling**: Automate form filling tasks
- **Automation tasks**: Create scripts for repetitive tasks
- **Monitoring**: Wait for specific conditions

## Development

```bash
# Run in development mode
npm run dev

# Lint the code
npm run lint

# Run tests
npm run test
```

## License

MIT

```

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

```json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "esModuleInterop": true,
    "strict": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictPropertyInitialization": true,
    "noImplicitAny": true,
    "noImplicitThis": true,
    "alwaysStrict": true,
    "outDir": "./dist",
    "sourceMap": true,
    "declaration": true,
    "resolveJsonModule": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

```

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

```typescript
/**
 * Tools module for MCP Windows Desktop Automation
 */

import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { registerMouseTools } from './mouse';
import { registerKeyboardTools } from './keyboard';
import { registerWindowTools } from './window';
import { registerProcessTools } from './process';
import { registerControlTools } from './control';

/**
 * Register all AutoIt tools with the MCP server
 */
export function registerAllTools(server: McpServer): void {
  registerMouseTools(server);
  registerKeyboardTools(server);
  registerWindowTools(server);
  registerProcessTools(server);
  registerControlTools(server);
}

```

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

```json
{
  "name": "mcp-windows-desktop-automation",
  "version": "0.1.0",
  "description": "MCP server for Windows desktop automation",
  "main": "dist/index.js",
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js",
    "dev": "ts-node src/index.ts",
    "lint": "eslint src/**/*.ts",
    "test": "jest"
  },
  "keywords": [
    "mcp",
    "windows",
    "automation",
    "autoit"
  ],
  "author": "",
  "license": "MIT",
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.7.0",
    "node-autoit-koffi": "^1.0.5",
    "ws": "^8.18.1"
  },
  "devDependencies": {
    "@types/express": "^4.17.17",
    "@types/node": "^18.15.11",
    "@types/ws": "^8.18.0",
    "@typescript-eslint/eslint-plugin": "^5.57.1",
    "@typescript-eslint/parser": "^5.57.1",
    "eslint": "^8.38.0",
    "jest": "^29.5.0",
    "ts-jest": "^29.1.0",
    "ts-node": "^10.9.1",
    "typescript": "^5.0.4"
  }
}

```

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

```typescript
/**
 * Logger utility for MCP Windows Desktop Automation
 */

enum LogLevel {
  VERBOSE = 0,
  DEBUG = 1,
  INFO = 2,
  WARN = 3,
  ERROR = 4
}

class Logger {
  private level: LogLevel = LogLevel.INFO;

  /**
   * Set the minimum log level
   * @param level The minimum level to log
   */
  setLevel(level: LogLevel): void {
    this.level = level;
  }

  /**
   * Log verbose information
   * @param message The message to log
   * @param data Additional data to log (will be JSON stringified)
   */
  verbose(message: string, data?: any): void {
    if (this.level <= LogLevel.VERBOSE) {
      console.log(`[VERBOSE] ${message}`, data ? JSON.stringify(data) : '');
    }
  }

  /**
   * Log debug information
   * @param message The message to log
   * @param data Additional data to log
   */
  debug(message: string, data?: any): void {
    if (this.level <= LogLevel.DEBUG) {
      console.log(`[DEBUG] ${message}`, data || '');
    }
  }

  /**
   * Log general information
   * @param message The message to log
   * @param data Additional data to log
   */
  info(message: string, data?: any): void {
    if (this.level <= LogLevel.INFO) {
      console.log(`[INFO] ${message}`, data || '');
    }
  }

  /**
   * Log warnings
   * @param message The message to log
   * @param data Additional data to log
   */
  warn(message: string, data?: any): void {
    if (this.level <= LogLevel.WARN) {
      console.warn(`[WARN] ${message}`, data || '');
    }
  }

  /**
   * Log errors
   * @param message The message to log
   * @param data Additional data to log
   */
  error(message: string, data?: any): void {
    if (this.level <= LogLevel.ERROR) {
      console.error(`[ERROR] ${message}`, data || '');
    }
  }
}

export const log = new Logger();

```

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

```typescript
/**
 * Shared type definitions for MCP Windows Desktop Automation
 */

import { z } from 'zod';
import { CallToolResult, TextContent } from '@modelcontextprotocol/sdk/types.js';

/**
 * Point coordinates
 */
export interface Point {
  x: number;
  y: number;
}

/**
 * Rectangle coordinates
 */
export interface Rect {
  left: number;
  top: number;
  right: number;
  bottom: number;
}

/**
 * Standard tool response creator
 */
export function createToolResponse(message: string): CallToolResult {
  return {
    content: [
      {
        type: 'text',
        text: message
      } as TextContent
    ]
  };
}

/**
 * Standard error response creator
 */
export function createErrorResponse(error: Error | string): CallToolResult {
  const errorMessage = typeof error === 'string' ? error : error.message;
  return {
    content: [
      {
        type: 'text',
        text: `Error: ${errorMessage}`
      } as TextContent
    ],
    isError: true
  };
}

/**
 * Common Zod schemas for tool parameters
 */
export const schemas = {
  // Window identification
  windowTitle: z.string().describe('Window title'),
  windowText: z.string().optional().describe('Window text'),
  
  // Mouse parameters
  mouseButton: z.enum(['left', 'right', 'middle']).optional().default('left').describe('Mouse button'),
  mouseSpeed: z.number().min(1).max(100).optional().default(10).describe('Mouse movement speed (1-100)'),
  mouseX: z.number().describe('X coordinate'),
  mouseY: z.number().describe('Y coordinate'),
  mouseClicks: z.number().min(1).optional().default(1).describe('Number of clicks'),
  
  // Control parameters
  controlName: z.string().describe('Control identifier'),
  controlText: z.string().describe('Text to set/send to control'),
  
  // Process parameters
  processName: z.string().describe('Process name or executable path'),
  processTimeout: z.number().optional().describe('Timeout in milliseconds'),
  
  // Common parameters
  handle: z.number().describe('Window or control handle'),
  bufferSize: z.number().optional().describe('Buffer size for string operations')
};

```

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

```typescript
/**
 * MCP Server configuration for Windows Desktop Automation
 */

import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { WebSocket, WebSocketServer, RawData } from 'ws';
import { createServer as createHttpServer, IncomingMessage, Server as HttpServer } from 'http';
import { log } from '../utils/logger/logger';
import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
import { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';

/**
 * Custom WebSocket transport for MCP
 */
class WebSocketServerTransport implements Transport {
  private ws: WebSocket | null = null;
  sessionId?: string;

  constructor(ws: WebSocket) {
    this.ws = ws;
    this.sessionId = Math.random().toString(36).substring(2, 15);
    
    ws.on('message', (data: RawData) => {
      try {
        const message = JSON.parse(data.toString()) as JSONRPCMessage;
        this.onmessage?.(message);
      } catch (error) {
        this.onerror?.(new Error(`Failed to parse message: ${error}`));
      }
    });

    ws.on('close', () => {
      this.ws = null;
      this.onclose?.();
    });

    ws.on('error', (error: Error) => {
      this.onerror?.(error);
    });
  }

  onclose?: () => void;
  onerror?: (error: Error) => void;
  onmessage?: (message: JSONRPCMessage) => void;

  async start(): Promise<void> {
    log.info('WebSocket transport started');
  }

  async send(message: JSONRPCMessage): Promise<void> {
    if (!this.ws) {
      throw new Error('WebSocket not connected');
    }
    
    return new Promise((resolve, reject) => {
      this.ws!.send(JSON.stringify(message), (error?: Error) => {
        if (error) {
          reject(error);
        } else {
          resolve();
        }
      });
    });
  }

  async close(): Promise<void> {
    if (this.ws) {
      this.ws.close();
      this.ws = null;
    }
  }
}

/**
 * Server configuration options
 */
export interface ServerConfig {
  name: string;
  version: string;
  transport: 'stdio' | 'websocket';
  port?: number;
}

/**
 * Create and configure an MCP server
 */
export async function setupServer(config: ServerConfig): Promise<{
  server: McpServer;
  httpServer?: HttpServer;
}> {
  // Create the MCP server
  const server = new McpServer({
    name: config.name,
    version: config.version
  }, {
    capabilities: {
      tools: {},
      resources: {
        subscribe: true,
        listChanged: true
      },
      prompts: {
        listChanged: true
      }
    }
  });

  // Configure the transport
  if (config.transport === 'stdio') {
    log.info('Using stdio transport');
    const transport = new StdioServerTransport();
    await server.connect(transport);
    return { server };
  } else if (config.transport === 'websocket') {
    log.info(`Using WebSocket transport on port ${config.port}`);
    
    // Create HTTP server
    const httpServer = createHttpServer();
    const wss = new WebSocketServer({ server: httpServer });
    
    // Handle WebSocket connections
    wss.on('connection', async (ws: WebSocket) => {
      log.info('New WebSocket connection');
      const transport = new WebSocketServerTransport(ws);
      await server.connect(transport);
    });
    
    // Start HTTP server
    httpServer.listen(config.port || 3000);
    
    return { server, httpServer };
  } else {
    throw new Error(`Unsupported transport: ${config.transport}`);
  }
}

```

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

```typescript
/**
 * Keyboard-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 } from '../utils/types';
import { log } from '../utils/logger/logger';

/**
 * Register keyboard-related tools with the MCP server
 */
export function registerKeyboardTools(server: McpServer): void {
  // send - Send keystrokes to the active window
  server.tool(
    'send',
    {
      text: z.string().describe('Text or keys to send'),
      mode: z.number().optional().default(0).describe('Send mode flag')
    },
    async ({ text, mode }) => {
      try {
        log.verbose('send called', { text, mode });
        await autoIt.init();
        await autoIt.send(text, mode);
        return createToolResponse(`Sent keystrokes: "${text}" with mode ${mode}`);
      } catch (error) {
        log.error('send failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // clipGet - Get the text from the clipboard
  server.tool(
    'clipGet',
    {
      bufSize: z.number().optional().describe('Buffer size for clipboard content')
    },
    async ({ bufSize }) => {
      try {
        log.verbose('clipGet called', { bufSize });
        await autoIt.init();
        const clipboardContent = await autoIt.clipGet(bufSize);
        log.verbose('clipGet result', JSON.stringify({ clipboardContent }));
        return createToolResponse(`Clipboard content: "${clipboardContent}"`);
      } catch (error) {
        log.error('clipGet failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // clipPut - Put text into the clipboard
  server.tool(
    'clipPut',
    {
      text: z.string().describe('Text to put in the clipboard')
    },
    async ({ text }) => {
      try {
        log.verbose('clipPut called', { text });
        await autoIt.init();
        await autoIt.clipPut(text);
        return createToolResponse(`Text set to clipboard: "${text}"`);
      } catch (error) {
        log.error('clipPut failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // autoItSetOption - Set AutoIt options
  server.tool(
    'autoItSetOption',
    {
      option: z.string().describe('Option name'),
      value: z.number().describe('Option value')
    },
    async ({ option, value }) => {
      try {
        log.verbose('autoItSetOption called', { option, value });
        await autoIt.init();
        const result = await autoIt.autoItSetOption(option, value);
        return createToolResponse(`AutoIt option "${option}" set to ${value} with result: ${result}`);
      } catch (error) {
        log.error('autoItSetOption failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // opt - Alias for autoItSetOption
  server.tool(
    'opt',
    {
      option: z.string().describe('Option name'),
      value: z.number().describe('Option value')
    },
    async ({ option, value }) => {
      try {
        log.verbose('opt called', { option, value });
        await autoIt.init();
        const result = await autoIt.opt(option, value);
        return createToolResponse(`AutoIt option "${option}" set to ${value} with result: ${result}`);
      } catch (error) {
        log.error('opt failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // toolTip - Display a tooltip
  server.tool(
    'toolTip',
    {
      text: z.string().describe('Tooltip text'),
      x: z.number().optional().describe('X coordinate'),
      y: z.number().optional().describe('Y coordinate')
    },
    async ({ text, x, y }) => {
      try {
        log.verbose('toolTip called', { text, x, y });
        await autoIt.init();
        await autoIt.toolTip(text, x, y);
        const position = x !== undefined && y !== undefined ? ` at position (${x}, ${y})` : '';
        return createToolResponse(`Tooltip displayed: "${text}"${position}`);
      } catch (error) {
        log.error('toolTip failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );
}

```

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

```typescript
/**
 * Mouse-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 mouse-related tools with the MCP server
 */
export function registerMouseTools(server: McpServer): void {
  // mouseMove - Move the mouse cursor to the specified coordinates
  server.tool(
    'mouseMove',
    {
      x: schemas.mouseX,
      y: schemas.mouseY,
      speed: schemas.mouseSpeed
    },
    async ({ x, y, speed }) => {
      try {
        log.verbose('mouseMove called', { x, y, speed });
        await autoIt.init();
        const result = await autoIt.mouseMove(x, y, speed);
        return createToolResponse(`Mouse moved to (${x}, ${y}) with result: ${result}`);
      } catch (error) {
        log.error('mouseMove failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // mouseClick - Click the mouse at the current or specified position
  server.tool(
    'mouseClick',
    {
      button: schemas.mouseButton,
      x: schemas.mouseX.optional(),
      y: schemas.mouseY.optional(),
      clicks: schemas.mouseClicks,
      speed: schemas.mouseSpeed
    },
    async ({ button, x, y, clicks, speed }) => {
      try {
        log.verbose('mouseClick called', { button, x, y, clicks, speed });
        await autoIt.init();
        const result = await autoIt.mouseClick(button, x, y, clicks, speed);
        return createToolResponse(`Mouse clicked ${button} button ${clicks} time(s) with result: ${result}`);
      } catch (error) {
        log.error('mouseClick failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // mouseClickDrag - Click and drag the mouse from one position to another
  server.tool(
    'mouseClickDrag',
    {
      button: schemas.mouseButton,
      x1: schemas.mouseX,
      y1: schemas.mouseY,
      x2: schemas.mouseX,
      y2: schemas.mouseY,
      speed: schemas.mouseSpeed
    },
    async ({ button, x1, y1, x2, y2, speed }) => {
      try {
        log.verbose('mouseClickDrag called', { button, x1, y1, x2, y2, speed });
        await autoIt.init();
        const result = await autoIt.mouseClickDrag(button, x1, y1, x2, y2, speed);
        return createToolResponse(`Mouse dragged from (${x1}, ${y1}) to (${x2}, ${y2}) with result: ${result}`);
      } catch (error) {
        log.error('mouseClickDrag failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // mouseDown - Press and hold the specified mouse button
  server.tool(
    'mouseDown',
    {
      button: schemas.mouseButton
    },
    async ({ button }) => {
      try {
        log.verbose('mouseDown called', { button });
        await autoIt.init();
        await autoIt.mouseDown(button);
        return createToolResponse(`Mouse ${button} button pressed down`);
      } catch (error) {
        log.error('mouseDown failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // mouseUp - Release the specified mouse button
  server.tool(
    'mouseUp',
    {
      button: schemas.mouseButton
    },
    async ({ button }) => {
      try {
        log.verbose('mouseUp called', { button });
        await autoIt.init();
        await autoIt.mouseUp(button);
        return createToolResponse(`Mouse ${button} button released`);
      } catch (error) {
        log.error('mouseUp failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // mouseGetPos - Get the current mouse cursor position
  server.tool(
    'mouseGetPos',
    {},
    async () => {
      try {
        log.verbose('mouseGetPos called');
        await autoIt.init();
        const position = await autoIt.mouseGetPos();
        log.verbose('mouseGetPos result', JSON.stringify(position));
        return createToolResponse(`Mouse position: (${position.x}, ${position.y})`);
      } catch (error) {
        log.error('mouseGetPos failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // mouseGetCursor - Get the current mouse cursor type
  server.tool(
    'mouseGetCursor',
    {},
    async () => {
      try {
        log.verbose('mouseGetCursor called');
        await autoIt.init();
        const cursor = await autoIt.mouseGetCursor();
        log.verbose('mouseGetCursor result', JSON.stringify(cursor));
        return createToolResponse(`Mouse cursor type: ${cursor}`);
      } catch (error) {
        log.error('mouseGetCursor failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // mouseWheel - Scroll the mouse wheel
  server.tool(
    'mouseWheel',
    {
      direction: z.enum(['up', 'down']).describe('Scroll direction'),
      clicks: z.number().min(1).describe('Number of clicks to scroll')
    },
    async ({ direction, clicks }) => {
      try {
        log.verbose('mouseWheel called', { direction, clicks });
        await autoIt.init();
        await autoIt.mouseWheel(direction, clicks);
        return createToolResponse(`Mouse wheel scrolled ${direction} ${clicks} click(s)`);
      } catch (error) {
        log.error('mouseWheel failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );
}

```

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

```typescript
/**
 * Resources module for MCP Windows Desktop Automation
 */

import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
import * as fs from 'fs/promises';
import * as path from 'path';
import * as autoIt from 'node-autoit-koffi';
import { log } from '../utils/logger/logger';

/**
 * Register all resources with the MCP server
 */
export function registerAllResources(server: McpServer): void {
  // Register file resources
  registerFileResources(server);
  
  // Register screenshot resources
  registerScreenshotResources(server);
}

/**
 * Register file resources
 */
function registerFileResources(server: McpServer): void {
  server.resource(
    'file',
    new ResourceTemplate('file://{path*}', { 
      list: async () => {
        return { resources: [] }; // Empty list by default
      }
    }),
    async (uri, params) => {
      try {
        // Ensure filePath is a string
        const filePath = Array.isArray(params.path) ? params.path.join('/') : params.path;
        log.verbose('Reading file resource', JSON.stringify({ uri: uri.href, filePath }));
        
        // Check if file exists
        const stats = await fs.stat(filePath);
        
        if (stats.isDirectory()) {
          // List directory contents
          const files = await fs.readdir(filePath);
          const resources = await Promise.all(
            files.map(async (file) => {
              const fullPath = path.join(filePath, file);
              const fileStats = await fs.stat(fullPath);
              return {
                uri: `file://${fullPath.replace(/\\/g, '/')}`,
                name: file,
                description: fileStats.isDirectory() ? 'Directory' : 'File'
              };
            })
          );
          
          return {
            contents: [{
              uri: uri.href,
              text: `Directory: ${filePath}\n${files.join('\n')}`,
              mimeType: 'text/plain'
            }]
          };
        } else {
          // Read file content
          const content = await fs.readFile(filePath);
          const extension = path.extname(filePath).toLowerCase();
          
          // Determine if it's a text or binary file
          const isTextFile = [
            '.txt', '.md', '.js', '.ts', '.html', '.css', '.json', '.xml', 
            '.csv', '.log', '.ini', '.cfg', '.conf', '.py', '.c', '.cpp', 
            '.h', '.java', '.sh', '.bat', '.ps1'
          ].includes(extension);
          
          if (isTextFile) {
            return {
              contents: [{
                uri: uri.href,
                text: content.toString('utf-8'),
                mimeType: getMimeType(extension)
              }]
            };
          } else {
            return {
              contents: [{
                uri: uri.href,
                blob: content.toString('base64'),
                mimeType: getMimeType(extension)
              }]
            };
          }
        }
      } catch (error) {
        log.error('Error reading file resource', error);
        throw new Error(`Failed to read file: ${error instanceof Error ? error.message : String(error)}`);
      }
    }
  );
}

/**
 * Register screenshot resources
 */
function registerScreenshotResources(server: McpServer): void {
  server.resource(
    'screenshot',
    new ResourceTemplate('screenshot://{window?}', { 
      list: async () => {
        return { resources: [] }; // Empty list by default
      }
    }),
    async (uri, params) => {
      try {
        await autoIt.init();
        // Ensure window is a string if provided
        const windowName = params.window ? String(params.window) : undefined;
        log.verbose('Taking screenshot', JSON.stringify({ uri: uri.href, window: windowName }));
        
        // If window parameter is provided, activate that window first
        if (windowName) {
          const windowExists = await autoIt.winExists(windowName);
          if (windowExists) {
            await autoIt.winActivate(windowName);
            // Wait a moment for the window to activate
            await new Promise(resolve => setTimeout(resolve, 500));
          } else {
            throw new Error(`Window "${windowName}" not found`);
          }
        }
        
        // TODO: Implement actual screenshot capture
        // This is a placeholder - in a real implementation, you would use
        // a library like 'screenshot-desktop' or other Windows API bindings
        // to capture the screen or specific window
        
        // For now, we'll return a placeholder message
        return {
          contents: [{
            uri: uri.href,
            text: `Screenshot of ${windowName || 'full screen'} would be captured here`,
            mimeType: 'text/plain'
          }]
        };
        
        // In a real implementation, you would return something like:
        /*
        return {
          contents: [{
            uri: uri.href,
            blob: screenshotBase64Data,
            mimeType: 'image/png'
          }]
        };
        */
      } catch (error) {
        log.error('Error taking screenshot', error);
        throw new Error(`Failed to take screenshot: ${error instanceof Error ? error.message : String(error)}`);
      }
    }
  );
}

/**
 * Get MIME type based on file extension
 */
function getMimeType(extension: string): string {
  const mimeTypes: Record<string, string> = {
    '.txt': 'text/plain',
    '.html': 'text/html',
    '.css': 'text/css',
    '.js': 'application/javascript',
    '.ts': 'application/typescript',
    '.json': 'application/json',
    '.xml': 'application/xml',
    '.md': 'text/markdown',
    '.csv': 'text/csv',
    '.png': 'image/png',
    '.jpg': 'image/jpeg',
    '.jpeg': 'image/jpeg',
    '.gif': 'image/gif',
    '.svg': 'image/svg+xml',
    '.pdf': 'application/pdf',
    '.doc': 'application/msword',
    '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    '.xls': 'application/vnd.ms-excel',
    '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    '.ppt': 'application/vnd.ms-powerpoint',
    '.pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
    '.zip': 'application/zip',
    '.rar': 'application/x-rar-compressed',
    '.7z': 'application/x-7z-compressed',
    '.tar': 'application/x-tar',
    '.gz': 'application/gzip'
  };
  
  return mimeTypes[extension] || 'application/octet-stream';
}

```

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

```typescript
/**
 * Prompts module for MCP Windows Desktop Automation
 */

import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod';
import { log } from '../utils/logger/logger';

/**
 * Register all prompts with the MCP server
 */
export function registerAllPrompts(server: McpServer): void {
  // Register window interaction prompts
  registerWindowPrompts(server);
  
  // Register form filling prompts
  registerFormPrompts(server);
  
  // Register automation task prompts
  registerAutomationPrompts(server);
}

/**
 * Register window interaction prompts
 */
function registerWindowPrompts(server: McpServer): void {
  // Prompt for finding and interacting with a window
  server.prompt(
    'findWindow',
    {
      windowTitle: z.string().describe('Title or partial title of the window to find'),
      action: z.enum(['activate', 'close', 'minimize', 'maximize']).describe('Action to perform on the window')
    },
    ({ windowTitle, action }) => {
      log.verbose('findWindow prompt called', { windowTitle, action });
      
      let actionDescription: string;
      switch (action) {
        case 'activate':
          actionDescription = 'activate (bring to front)';
          break;
        case 'close':
          actionDescription = 'close';
          break;
        case 'minimize':
          actionDescription = 'minimize';
          break;
        case 'maximize':
          actionDescription = 'maximize';
          break;
      }
      
      return {
        description: `Find a window with title "${windowTitle}" and ${actionDescription} it`,
        messages: [
          {
            role: 'user',
            content: {
              type: 'text',
              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?`
            }
          }
        ]
      };
    }
  );
  
  // Prompt for getting information about a window
  server.prompt(
    'windowInfo',
    {
      windowTitle: z.string().describe('Title or partial title of the window')
    },
    ({ windowTitle }) => {
      log.verbose('windowInfo prompt called', { windowTitle });
      
      return {
        description: `Get information about a window with title "${windowTitle}"`,
        messages: [
          {
            role: 'user',
            content: {
              type: 'text',
              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?`
            }
          }
        ]
      };
    }
  );
}

/**
 * Register form filling prompts
 */
function registerFormPrompts(server: McpServer): void {
  // Prompt for filling out a form
  server.prompt(
    'fillForm',
    {
      windowTitle: z.string().describe('Title of the window containing the form'),
      formFields: z.string().describe('Description of form fields and values to fill in')
    },
    ({ windowTitle, formFields }) => {
      log.verbose('fillForm prompt called', { windowTitle, formFields });
      
      return {
        description: `Fill out a form in window "${windowTitle}"`,
        messages: [
          {
            role: 'user',
            content: {
              type: 'text',
              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?`
            }
          }
        ]
      };
    }
  );
  
  // Prompt for submitting a form
  server.prompt(
    'submitForm',
    {
      windowTitle: z.string().describe('Title of the window containing the form'),
      submitButtonText: z.string().describe('Text on the submit button')
    },
    ({ windowTitle, submitButtonText }) => {
      log.verbose('submitForm prompt called', { windowTitle, submitButtonText });
      
      return {
        description: `Submit a form in window "${windowTitle}"`,
        messages: [
          {
            role: 'user',
            content: {
              type: 'text',
              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?`
            }
          }
        ]
      };
    }
  );
}

/**
 * Register automation task prompts
 */
function registerAutomationPrompts(server: McpServer): void {
  // Prompt for automating a repetitive task
  server.prompt(
    'automateTask',
    {
      taskDescription: z.string().describe('Description of the repetitive task to automate'),
      repetitions: z.string().describe('Number of times to repeat the task')
    },
    ({ taskDescription, repetitions }) => {
      log.verbose('automateTask prompt called', { taskDescription, repetitions });
      
      return {
        description: `Automate a repetitive task: ${taskDescription}`,
        messages: [
          {
            role: 'user',
            content: {
              type: 'text',
              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?`
            }
          }
        ]
      };
    }
  );
  
  // Prompt for monitoring a window or process
  server.prompt(
    'monitorWindow',
    {
      windowTitle: z.string().describe('Title of the window to monitor'),
      condition: z.string().describe('Condition to monitor for (e.g., "appears", "disappears", "contains text X")')
    },
    ({ windowTitle, condition }) => {
      log.verbose('monitorWindow prompt called', { windowTitle, condition });
      
      return {
        description: `Monitor window "${windowTitle}" for condition: ${condition}`,
        messages: [
          {
            role: 'user',
            content: {
              type: 'text',
              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?`
            }
          }
        ]
      };
    }
  );
  
  // Prompt for taking a screenshot
  server.prompt(
    'takeScreenshot',
    {
      target: z.enum(['fullscreen', 'window', 'region']).describe('What to capture in the screenshot'),
      windowTitle: z.string().optional().describe('Title of the window to capture (if target is "window")')
    },
    ({ target, windowTitle }) => {
      log.verbose('takeScreenshot prompt called', { target, windowTitle });
      
      let promptText: string;
      if (target === 'fullscreen') {
        promptText = 'I need to take a screenshot of the entire screen.';
      } else if (target === 'window' && windowTitle) {
        promptText = `I need to take a screenshot of a window with the title "${windowTitle}".`;
      } else if (target === 'region') {
        promptText = 'I need to take a screenshot of a specific region of the screen.';
      } else {
        promptText = 'I need to take a screenshot.';
      }
      
      return {
        description: `Take a screenshot of ${target === 'window' ? `window "${windowTitle}"` : target}`,
        messages: [
          {
            role: 'user',
            content: {
              type: 'text',
              text: `${promptText} Can you help me do this using AutoIt functions?`
            }
          }
        ]
      };
    }
  );
}

```

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

```typescript
/**
 * Process-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 process-related tools with the MCP server
 */
export function registerProcessTools(server: McpServer): void {
  // run - Run a program
  server.tool(
    'run',
    {
      program: z.string().describe('Program path or command'),
      workingDir: z.string().optional().describe('Working directory'),
      showFlag: z.number().optional().describe('Window show flag')
    },
    async ({ program, workingDir, showFlag }) => {
      try {
        log.verbose('run called', { program, workingDir, showFlag });
        await autoIt.init();
        const result = await autoIt.run(program, workingDir, showFlag);
        return createToolResponse(`Program "${program}" started with process ID: ${result}`);
      } catch (error) {
        log.error('run failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // runWait - Run a program and wait for it to complete
  server.tool(
    'runWait',
    {
      program: z.string().describe('Program path or command'),
      workingDir: z.string().optional().describe('Working directory'),
      showFlag: z.number().optional().describe('Window show flag')
    },
    async ({ program, workingDir, showFlag }) => {
      try {
        log.verbose('runWait called', { program, workingDir, showFlag });
        await autoIt.init();
        const result = await autoIt.runWait(program, workingDir, showFlag);
        return createToolResponse(`Program "${program}" completed with exit code: ${result}`);
      } catch (error) {
        log.error('runWait failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // runAs - Run a program as a different user
  server.tool(
    'runAs',
    {
      user: z.string().describe('Username'),
      domain: z.string().describe('Domain'),
      password: z.string().describe('Password'),
      logonFlag: z.number().describe('Logon flag'),
      program: z.string().describe('Program path or command'),
      workingDir: z.string().optional().describe('Working directory'),
      showFlag: z.number().optional().describe('Window show flag')
    },
    async ({ user, domain, password, logonFlag, program, workingDir, showFlag }) => {
      try {
        log.verbose('runAs called', { user, domain, logonFlag, program, workingDir, showFlag });
        await autoIt.init();
        const result = await autoIt.runAs(user, domain, password, logonFlag, program, workingDir, showFlag);
        return createToolResponse(`Program "${program}" started as user "${user}" with process ID: ${result}`);
      } catch (error) {
        log.error('runAs failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // runAsWait - Run a program as a different user and wait for it to complete
  server.tool(
    'runAsWait',
    {
      user: z.string().describe('Username'),
      domain: z.string().describe('Domain'),
      password: z.string().describe('Password'),
      logonFlag: z.number().describe('Logon flag'),
      program: z.string().describe('Program path or command'),
      workingDir: z.string().optional().describe('Working directory'),
      showFlag: z.number().optional().describe('Window show flag')
    },
    async ({ user, domain, password, logonFlag, program, workingDir, showFlag }) => {
      try {
        log.verbose('runAsWait called', { user, domain, logonFlag, program, workingDir, showFlag });
        await autoIt.init();
        const result = await autoIt.runAsWait(user, domain, password, logonFlag, program, workingDir, showFlag);
        return createToolResponse(`Program "${program}" completed as user "${user}" with exit code: ${result}`);
      } catch (error) {
        log.error('runAsWait failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // processExists - Check if a process exists
  server.tool(
    'processExists',
    {
      process: schemas.processName
    },
    async ({ process }) => {
      try {
        log.verbose('processExists called', { process });
        await autoIt.init();
        const result = await autoIt.processExists(process);
        const exists = result !== 0;
        return createToolResponse(
          exists
            ? `Process "${process}" exists with PID: ${result}`
            : `Process "${process}" does not exist`
        );
      } catch (error) {
        log.error('processExists failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // processClose - Close a process
  server.tool(
    'processClose',
    {
      process: schemas.processName
    },
    async ({ process }) => {
      try {
        log.verbose('processClose called', { process });
        await autoIt.init();
        const result = await autoIt.processClose(process);
        const success = result === 1;
        return createToolResponse(
          success
            ? `Process "${process}" closed successfully`
            : `Failed to close process "${process}"`
        );
      } catch (error) {
        log.error('processClose failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // processSetPriority - Set process priority
  server.tool(
    'processSetPriority',
    {
      process: schemas.processName,
      priority: z.number().describe('Priority level (0-4)')
    },
    async ({ process, priority }) => {
      try {
        log.verbose('processSetPriority called', { process, priority });
        await autoIt.init();
        const result = await autoIt.processSetPriority(process, priority);
        const success = result === 1;
        return createToolResponse(
          success
            ? `Priority for process "${process}" set to ${priority}`
            : `Failed to set priority for process "${process}"`
        );
      } catch (error) {
        log.error('processSetPriority failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // processWait - Wait for a process to exist
  server.tool(
    'processWait',
    {
      process: schemas.processName,
      timeout: schemas.processTimeout
    },
    async ({ process, timeout }) => {
      try {
        log.verbose('processWait called', { process, timeout });
        await autoIt.init();
        const result = await autoIt.processWait(process, timeout);
        const success = result !== 0;
        return createToolResponse(
          success
            ? `Process "${process}" exists with PID: ${result}`
            : `Timed out waiting for process "${process}"`
        );
      } catch (error) {
        log.error('processWait failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // processWaitClose - Wait for a process to close
  server.tool(
    'processWaitClose',
    {
      process: schemas.processName,
      timeout: schemas.processTimeout
    },
    async ({ process, timeout }) => {
      try {
        log.verbose('processWaitClose called', { process, timeout });
        await autoIt.init();
        const result = await autoIt.processWaitClose(process, timeout);
        const success = result === 1;
        return createToolResponse(
          success
            ? `Process "${process}" closed within the timeout`
            : `Timed out waiting for process "${process}" to close`
        );
      } catch (error) {
        log.error('processWaitClose failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // shutdown - Shut down the system
  server.tool(
    'shutdown',
    {
      flags: z.number().describe('Shutdown flags')
    },
    async ({ flags }) => {
      try {
        log.verbose('shutdown called', { flags });
        await autoIt.init();
        const result = await autoIt.shutdown(flags);
        const success = result === 1;
        return createToolResponse(
          success
            ? `System shutdown initiated with flags: ${flags}`
            : `Failed to initiate system shutdown`
        );
      } catch (error) {
        log.error('shutdown failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );
}

```

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

```typescript
/**
 * Window-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 window-related tools with the MCP server
 */
export function registerWindowTools(server: McpServer): void {
  // winActivate - Activate a window
  server.tool(
    'winActivate',
    {
      title: schemas.windowTitle,
      text: schemas.windowText
    },
    async ({ title, text }) => {
      try {
        log.verbose('winActivate called', { title, text });
        await autoIt.init();
        const result = await autoIt.winActivate(title, text);
        return createToolResponse(`Window "${title}" activated with result: ${result}`);
      } catch (error) {
        log.error('winActivate failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // winActivateByHandle - Activate a window by handle
  server.tool(
    'winActivateByHandle',
    {
      handle: schemas.handle
    },
    async ({ handle }) => {
      try {
        log.verbose('winActivateByHandle called', { handle });
        await autoIt.init();
        const result = await autoIt.winActivateByHandle(handle);
        return createToolResponse(`Window with handle ${handle} activated with result: ${result}`);
      } catch (error) {
        log.error('winActivateByHandle failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // winActive - Check if a window is active
  server.tool(
    'winActive',
    {
      title: schemas.windowTitle,
      text: z.string().describe('Window text')
    },
    async ({ title, text }) => {
      try {
        log.verbose('winActive called', { title, text });
        await autoIt.init();
        const result = await autoIt.winActive(title, text);
        const isActive = result === 1;
        return createToolResponse(`Window "${title}" is ${isActive ? 'active' : 'not active'}`);
      } catch (error) {
        log.error('winActive failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // winClose - Close a window
  server.tool(
    'winClose',
    {
      title: schemas.windowTitle,
      text: schemas.windowText
    },
    async ({ title, text }) => {
      try {
        log.verbose('winClose called', { title, text });
        await autoIt.init();
        const result = await autoIt.winClose(title, text);
        return createToolResponse(`Window "${title}" closed with result: ${result}`);
      } catch (error) {
        log.error('winClose failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // winExists - Check if a window exists
  server.tool(
    'winExists',
    {
      title: schemas.windowTitle,
      text: schemas.windowText
    },
    async ({ title, text }) => {
      try {
        log.verbose('winExists called', { title, text });
        await autoIt.init();
        const result = await autoIt.winExists(title, text);
        const exists = result === 1;
        return createToolResponse(`Window "${title}" ${exists ? 'exists' : 'does not exist'}`);
      } catch (error) {
        log.error('winExists failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // winGetHandle - Get a window handle
  server.tool(
    'winGetHandle',
    {
      title: schemas.windowTitle,
      text: schemas.windowText
    },
    async ({ title, text }) => {
      try {
        log.verbose('winGetHandle called', { title, text });
        await autoIt.init();
        const handle = await autoIt.winGetHandle(title, text);
        log.verbose('winGetHandle result', JSON.stringify({ handle }));
        return createToolResponse(`Window "${title}" handle: ${handle}`);
      } catch (error) {
        log.error('winGetHandle failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // winGetPos - Get window position and size
  server.tool(
    'winGetPos',
    {
      title: schemas.windowTitle,
      text: schemas.windowText
    },
    async ({ title, text }) => {
      try {
        log.verbose('winGetPos called', { title, text });
        await autoIt.init();
        const rect = await autoIt.winGetPos(title, text);
        log.verbose('winGetPos result', JSON.stringify(rect));
        const width = rect.right - rect.left;
        const height = rect.bottom - rect.top;
        return createToolResponse(
          `Window "${title}" position: Left=${rect.left}, Top=${rect.top}, Width=${width}, Height=${height}`
        );
      } catch (error) {
        log.error('winGetPos failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // winGetText - Get window text
  server.tool(
    'winGetText',
    {
      title: schemas.windowTitle,
      text: schemas.windowText,
      bufSize: schemas.bufferSize
    },
    async ({ title, text, bufSize }) => {
      try {
        log.verbose('winGetText called', { title, text, bufSize });
        await autoIt.init();
        const windowText = await autoIt.winGetText(title, text, bufSize);
        log.verbose('winGetText result', JSON.stringify({ windowText }));
        return createToolResponse(`Window "${title}" text: "${windowText}"`);
      } catch (error) {
        log.error('winGetText failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // winGetTitle - Get window title
  server.tool(
    'winGetTitle',
    {
      title: schemas.windowTitle,
      text: schemas.windowText,
      bufSize: schemas.bufferSize
    },
    async ({ title, text, bufSize }) => {
      try {
        log.verbose('winGetTitle called', { title, text, bufSize });
        await autoIt.init();
        const windowTitle = await autoIt.winGetTitle(title, text, bufSize);
        log.verbose('winGetTitle result', JSON.stringify({ windowTitle }));
        return createToolResponse(`Window "${title}" title: "${windowTitle}"`);
      } catch (error) {
        log.error('winGetTitle failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // winMove - Move and resize a window
  server.tool(
    'winMove',
    {
      title: schemas.windowTitle,
      text: schemas.windowText,
      x: z.number().describe('X coordinate'),
      y: z.number().describe('Y coordinate'),
      width: z.number().optional().describe('Window width'),
      height: z.number().optional().describe('Window height')
    },
    async ({ title, text, x, y, width, height }) => {
      try {
        log.verbose('winMove called', { title, text, x, y, width, height });
        await autoIt.init();
        const result = await autoIt.winMove(title, text, x, y, width, height);
        const sizeInfo = width && height ? ` and resized to ${width}x${height}` : '';
        return createToolResponse(`Window "${title}" moved to (${x}, ${y})${sizeInfo} with result: ${result}`);
      } catch (error) {
        log.error('winMove failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // winSetState - Set window state (minimized, maximized, etc.)
  server.tool(
    'winSetState',
    {
      title: schemas.windowTitle,
      text: schemas.windowText,
      flags: z.number().describe('State flags')
    },
    async ({ title, text, flags }) => {
      try {
        log.verbose('winSetState called', { title, text, flags });
        await autoIt.init();
        const result = await autoIt.winSetState(title, text, flags);
        return createToolResponse(`Window "${title}" state set to ${flags} with result: ${result}`);
      } catch (error) {
        log.error('winSetState failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // winWait - Wait for a window to exist
  server.tool(
    'winWait',
    {
      title: schemas.windowTitle,
      text: schemas.windowText,
      timeout: z.number().optional().describe('Timeout in seconds')
    },
    async ({ title, text, timeout }) => {
      try {
        log.verbose('winWait called', { title, text, timeout });
        await autoIt.init();
        const result = await autoIt.winWait(title, text, timeout);
        const success = result === 1;
        return createToolResponse(
          success
            ? `Window "${title}" appeared within the timeout`
            : `Window "${title}" did not appear within the timeout`
        );
      } catch (error) {
        log.error('winWait failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // winWaitActive - Wait for a window to be active
  server.tool(
    'winWaitActive',
    {
      title: schemas.windowTitle,
      text: schemas.windowText,
      timeout: z.number().optional().describe('Timeout in seconds')
    },
    async ({ title, text, timeout }) => {
      try {
        log.verbose('winWaitActive called', { title, text, timeout });
        await autoIt.init();
        const result = await autoIt.winWaitActive(title, text, timeout);
        const success = result === 1;
        return createToolResponse(
          success
            ? `Window "${title}" became active within the timeout`
            : `Window "${title}" did not become active within the timeout`
        );
      } catch (error) {
        log.error('winWaitActive failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );

  // winWaitClose - Wait for a window to close
  server.tool(
    'winWaitClose',
    {
      title: schemas.windowTitle,
      text: schemas.windowText,
      timeout: z.number().optional().describe('Timeout in seconds')
    },
    async ({ title, text, timeout }) => {
      try {
        log.verbose('winWaitClose called', { title, text, timeout });
        await autoIt.init();
        const result = await autoIt.winWaitClose(title, text, timeout);
        const success = result === 1;
        return createToolResponse(
          success
            ? `Window "${title}" closed within the timeout`
            : `Window "${title}" did not close within the timeout`
        );
      } catch (error) {
        log.error('winWaitClose failed', error);
        return createErrorResponse(error instanceof Error ? error : String(error));
      }
    }
  );
}

```

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

```typescript
/**
 * 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));
      }
    }
  );
}

```