UNPKG

@codai/glass-mcp

Version:

GlassMCP - Model Context Protocol server for Windows automation integrated with CODAI ecosystem

1 lines 47.2 kB
{"version":3,"sources":["../src/mcp-server-enhanced.ts"],"sourcesContent":["import { Server } from '@modelcontextprotocol/sdk/server/index.js';\r\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\r\nimport type { Tool } from '@modelcontextprotocol/sdk/types.js';\r\nimport {\r\n CallToolRequestSchema,\r\n ListToolsRequestSchema,\r\n} from '@modelcontextprotocol/sdk/types.js';\r\nimport { exec } from 'child_process';\r\nimport { promisify } from 'util';\r\nimport { writeFileSync, unlinkSync } from 'fs';\r\nimport { tmpdir } from 'os';\r\nimport { join } from 'path';\r\n\r\nconst execAsyncPromisified = promisify(exec);\r\n\r\n// Windows API types\r\ninterface WindowInfo {\r\n handle: string;\r\n title: string;\r\n className: string;\r\n isVisible: boolean;\r\n isMinimized: boolean;\r\n isMaximized: boolean;\r\n rect: {\r\n left: number;\r\n top: number;\r\n right: number;\r\n bottom: number;\r\n };\r\n}\r\n\r\ninterface TextElement {\r\n id: string;\r\n text: string;\r\n elementType: string;\r\n bounds: {\r\n x: number;\r\n y: number;\r\n width: number;\r\n height: number;\r\n };\r\n isVisible: boolean;\r\n isEnabled: boolean;\r\n automationId?: string;\r\n className?: string;\r\n}\r\n\r\ninterface WindowTextContent {\r\n windowHandle: number;\r\n windowTitle: string;\r\n textElements: TextElement[];\r\n totalTextLength: number;\r\n extractionTimestamp: string;\r\n}\r\n\r\n// Error classes\r\nclass GlassMCPError extends Error {\r\n constructor(\r\n message: string,\r\n public code?: string\r\n ) {\r\n super(message);\r\n this.name = 'GlassMCPError';\r\n }\r\n}\r\n\r\n// PowerShell-based Windows API wrapper\r\nasync function execPowerShell(script: string): Promise<{ stdout: string; stderr: string }> {\r\n const tempFile = join(tmpdir(), `glass-mcp-${Date.now()}.ps1`);\r\n writeFileSync(tempFile, script, 'utf8');\r\n\r\n try {\r\n const result = await execAsyncPromisified(`powershell -NoProfile -ExecutionPolicy Bypass -File \"${tempFile}\"`);\r\n return result;\r\n } catch (error: any) {\r\n throw new GlassMCPError(`PowerShell execution failed: ${error.message}`);\r\n } finally {\r\n try {\r\n unlinkSync(tempFile);\r\n } catch (cleanupError) {\r\n // Ignore cleanup errors\r\n }\r\n }\r\n}\r\n\r\n// Window management functions\r\nasync function listWindows(): Promise<WindowInfo[]> {\r\n const script = `\r\n Add-Type @\"\r\n using System;\r\n using System.Runtime.InteropServices;\r\n using System.Text;\r\n using System.Collections.Generic;\r\n\r\n public struct RECT {\r\n public int Left, Top, Right, Bottom;\r\n }\r\n\r\n public static class WindowManager {\r\n [DllImport(\"user32.dll\")]\r\n public static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);\r\n\r\n [DllImport(\"user32.dll\")]\r\n public static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount);\r\n\r\n [DllImport(\"user32.dll\")]\r\n public static extern int GetWindowTextLength(IntPtr hWnd);\r\n\r\n [DllImport(\"user32.dll\")]\r\n public static extern bool IsWindowVisible(IntPtr hWnd);\r\n\r\n [DllImport(\"user32.dll\")]\r\n public static extern bool IsIconic(IntPtr hWnd);\r\n\r\n [DllImport(\"user32.dll\")]\r\n public static extern bool IsZoomed(IntPtr hWnd);\r\n\r\n [DllImport(\"user32.dll\")]\r\n public static extern bool GetWindowRect(IntPtr hwnd, ref RECT rectangle);\r\n\r\n [DllImport(\"user32.dll\")]\r\n public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);\r\n\r\n public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);\r\n\r\n public static List<object> GetAllWindows() {\r\n var windows = new List<object>();\r\n EnumWindows(delegate(IntPtr hWnd, IntPtr param) {\r\n var length = GetWindowTextLength(hWnd);\r\n if (length == 0) return true;\r\n\r\n var builder = new StringBuilder(length + 1);\r\n GetWindowText(hWnd, builder, builder.Capacity);\r\n\r\n var classBuilder = new StringBuilder(256);\r\n GetClassName(hWnd, classBuilder, classBuilder.Capacity);\r\n\r\n var rect = new RECT();\r\n GetWindowRect(hWnd, ref rect);\r\n\r\n windows.Add(new {\r\n handle = hWnd.ToInt64().ToString(),\r\n title = builder.ToString(),\r\n className = classBuilder.ToString(),\r\n isVisible = IsWindowVisible(hWnd),\r\n isMinimized = IsIconic(hWnd),\r\n isMaximized = IsZoomed(hWnd),\r\n rect = new {\r\n left = rect.Left,\r\n top = rect.Top,\r\n right = rect.Right,\r\n bottom = rect.Bottom\r\n }\r\n });\r\n return true;\r\n }, IntPtr.Zero);\r\n return windows;\r\n }\r\n }\r\n\"@\r\n\r\n $windows = [WindowManager]::GetAllWindows()\r\n $windows | ConvertTo-Json -Depth 3\r\n `;\r\n\r\n const result = await execPowerShell(script);\r\n return JSON.parse(result.stdout);\r\n}\r\n\r\n// Text extraction function\r\nasync function extractWindowText(windowHandle: number): Promise<WindowTextContent> {\r\n const script = `\r\n try {\r\n Add-Type -AssemblyName UIAutomationClient\r\n $handle = [IntPtr]${windowHandle}\r\n $automation = [System.Windows.Automation.AutomationElement]::FromHandle($handle)\r\n \r\n if ($automation -eq $null) {\r\n Write-Output \"ERROR:Could not get automation element\"\r\n exit\r\n }\r\n \r\n # Get window title\r\n $windowTitle = $automation.Current.Name\r\n if ([string]::IsNullOrEmpty($windowTitle)) {\r\n $windowTitle = \"Unknown Window\"\r\n }\r\n \r\n # Simple text extraction - get all text elements\r\n $textCondition = [System.Windows.Automation.Condition]::TrueCondition\r\n $textElements = $automation.FindAll([System.Windows.Automation.TreeScope]::Descendants, $textCondition)\r\n \r\n $allTexts = @()\r\n $elementCount = 0\r\n \r\n foreach ($element in $textElements) {\r\n try {\r\n $text = \"\"\r\n \r\n # Try to get text from different sources\r\n if ($element.Current.ControlType -eq [System.Windows.Automation.ControlType]::Text -or\r\n $element.Current.ControlType -eq [System.Windows.Automation.ControlType]::Button -or\r\n $element.Current.ControlType -eq [System.Windows.Automation.ControlType]::Edit) {\r\n \r\n # Try name first\r\n $text = $element.Current.Name\r\n }\r\n \r\n # Clean and add text\r\n if (![string]::IsNullOrWhiteSpace($text) -and $text.Length -gt 0) {\r\n $cleanText = $text -replace '[\\\\r\\\\n\\\\t]', ' ' -replace '\\\\s+', ' '\r\n $cleanText = $cleanText.Trim()\r\n if ($cleanText.Length -gt 0 -and $cleanText.Length -lt 100) {\r\n $allTexts += $cleanText\r\n $elementCount++\r\n \r\n if ($elementCount -gt 50) {\r\n break\r\n }\r\n }\r\n }\r\n } catch {\r\n continue\r\n }\r\n }\r\n \r\n # Output simple format\r\n Write-Output \"SUCCESS\"\r\n Write-Output \"TITLE:$windowTitle\"\r\n Write-Output \"COUNT:$elementCount\"\r\n Write-Output \"TEXTS:\"\r\n foreach ($txt in $allTexts) {\r\n Write-Output \"TEXT:$txt\"\r\n }\r\n \r\n } catch {\r\n Write-Output \"ERROR:$($_.Exception.Message)\"\r\n }\r\n `;\r\n\r\n const result = await execPowerShell(script);\r\n\r\n // Parse simple output format\r\n const lines = result.stdout.split('\\n').map(l => l.trim()).filter(l => l.length > 0);\r\n\r\n if (lines[0] === \"ERROR\") {\r\n throw new GlassMCPError(`UI Automation error: ${lines[1] || 'Unknown error'}`);\r\n }\r\n\r\n if (lines[0] !== \"SUCCESS\") {\r\n throw new GlassMCPError(`Unexpected response format`);\r\n }\r\n\r\n let windowTitle = \"Unknown Window\";\r\n let elementCount = 0;\r\n const textElements: any[] = [];\r\n\r\n for (let i = 1; i < lines.length; i++) {\r\n const line = lines[i];\r\n if (line.startsWith(\"TITLE:\")) {\r\n windowTitle = line.substring(6);\r\n } else if (line.startsWith(\"COUNT:\")) {\r\n elementCount = parseInt(line.substring(6));\r\n } else if (line.startsWith(\"TEXT:\")) {\r\n const text = line.substring(5);\r\n textElements.push({\r\n id: `elem-${textElements.length}`,\r\n text: text,\r\n elementType: \"Text\",\r\n bounds: { x: 0, y: 0, width: 0, height: 0 },\r\n isVisible: true,\r\n isEnabled: true,\r\n automationId: \"\",\r\n className: \"\"\r\n });\r\n }\r\n }\r\n\r\n return {\r\n windowHandle: windowHandle,\r\n windowTitle: windowTitle,\r\n textElements: textElements,\r\n totalTextLength: textElements.reduce((sum, el) => sum + el.text.length, 0),\r\n extractionTimestamp: new Date().toISOString()\r\n };\r\n}\r\n\r\n// Send text to window\r\nasync function sendTextToWindow(windowHandle: number, text: string): Promise<boolean> {\r\n const script = `\r\n Add-Type -AssemblyName System.Windows.Forms\r\n \r\n # Focus the window first\r\n $handle = [IntPtr]::new(${windowHandle})\r\n Add-Type -TypeDefinition @\"\r\n using System;\r\n using System.Runtime.InteropServices;\r\n public static class User32 {\r\n [DllImport(\"user32.dll\")]\r\n public static extern bool SetForegroundWindow(IntPtr hWnd);\r\n [DllImport(\"user32.dll\")]\r\n public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);\r\n }\r\n\"@\r\n \r\n [User32]::ShowWindow($handle, 1) # SW_SHOWNORMAL\r\n [User32]::SetForegroundWindow($handle)\r\n Start-Sleep -Milliseconds 100\r\n \r\n # Send the text\r\n $escapedText = \"${text.replace(/\"/g, '\"\"').replace(/\\\\/g, '\\\\\\\\')}\"\r\n [System.Windows.Forms.SendKeys]::SendWait($escapedText)\r\n \r\n $true\r\n `;\r\n\r\n await execPowerShell(script);\r\n return true;\r\n}\r\n\r\n// Get clipboard text\r\nasync function getClipboardText(): Promise<string> {\r\n const script = `\r\n Add-Type -AssemblyName System.Windows.Forms\r\n [System.Windows.Forms.Clipboard]::GetText()\r\n `;\r\n\r\n const result = await execPowerShell(script);\r\n return result.stdout.trim();\r\n}\r\n\r\n// Set clipboard text\r\nasync function setClipboardText(text: string): Promise<boolean> {\r\n const script = `\r\n Add-Type -AssemblyName System.Windows.Forms\r\n $text = \"${text.replace(/\"/g, '\"\"').replace(/\\\\/g, '\\\\\\\\')}\"\r\n [System.Windows.Forms.Clipboard]::SetText($text)\r\n $true\r\n `;\r\n\r\n await execPowerShell(script);\r\n return true;\r\n}\r\n\r\n// Window utility functions\r\nasync function focusWindow(title: string, exact: boolean = false): Promise<boolean> {\r\n const windows = await listWindows();\r\n const window = windows.find(w =>\r\n exact ? w.title === title : w.title.toLowerCase().includes(title.toLowerCase())\r\n );\r\n\r\n if (!window) {\r\n throw new GlassMCPError(`Window not found: ${title}`);\r\n }\r\n\r\n const script = `\r\n Add-Type -TypeDefinition @\"\r\n using System;\r\n using System.Runtime.InteropServices;\r\n public static class User32 {\r\n [DllImport(\"user32.dll\")]\r\n public static extern bool SetForegroundWindow(IntPtr hWnd);\r\n [DllImport(\"user32.dll\")]\r\n public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);\r\n }\r\n\"@\r\n $handle = [IntPtr]::new(${window.handle})\r\n [User32]::ShowWindow($handle, 1)\r\n [User32]::SetForegroundWindow($handle)\r\n `;\r\n\r\n await execPowerShell(script);\r\n return true;\r\n}\r\n\r\n// =================== CAPABILITY DISCOVERY FUNCTIONS ===================\r\nfunction isSystemCapabilityQuery(query: string): boolean {\r\n const lowerQuery = query.toLowerCase();\r\n return lowerQuery.includes('glass') && (\r\n lowerQuery.includes('capabilities') ||\r\n lowerQuery.includes('system') ||\r\n lowerQuery.includes('info') ||\r\n lowerQuery.includes('help') ||\r\n lowerQuery.includes('what') ||\r\n lowerQuery.includes('how')\r\n );\r\n}\r\n\r\nfunction isHelpQuery(query: string): boolean {\r\n const lowerQuery = query.toLowerCase();\r\n return lowerQuery === 'help' ||\r\n lowerQuery === 'capabilities' ||\r\n lowerQuery === 'glass help' ||\r\n lowerQuery === 'glass capabilities' ||\r\n lowerQuery.includes('how to use') ||\r\n lowerQuery.includes('usage');\r\n}\r\n\r\nfunction getSystemInformation(): string {\r\n return `GlassMCP Enhanced v5.1.0 - Windows Automation Server\r\n=====================================================\r\n\r\n🚀 CORE CAPABILITIES:\r\n• Windows application automation and control\r\n• Real-time window management and text extraction\r\n• Clipboard operations with system integration\r\n• UI Automation with PowerShell-based Windows API\r\n• Cross-application text input and interaction\r\n• Window focus, extraction, and content analysis\r\n\r\n🛠️ AVAILABLE TOOLS:\r\n• window_list() - List all open windows with properties\r\n• window_focus(title, exact?) - Focus specific windows by title\r\n• window_extract_text(windowHandle) - Extract text from windows\r\n• window_extract_text_by_title(title, exact?) - Extract text by window title\r\n• window_send_text(windowHandle, text) - Send text input to windows\r\n• window_send_text_by_title(title, text, exact?) - Send text by window title\r\n• clipboard_get_text() - Get clipboard content\r\n• clipboard_set_text(text) - Set clipboard content\r\n\r\n📊 PERFORMANCE FEATURES:\r\n• PowerShell-based Windows API integration\r\n• Real-time UI Automation capabilities\r\n• Error handling with detailed diagnostics\r\n• Safe window detection and manipulation\r\n• Optimized text extraction algorithms\r\n\r\n🔧 PLATFORM SUPPORT:\r\n• Windows-only (win32) automation server\r\n• Supports all Windows applications with UI elements\r\n• Compatible with VS Code, browsers, office apps, and more\r\n• Works with visible and background windows\r\n\r\nFor detailed usage examples, query \"glass usage\" or \"glass examples\".`;\r\n}\r\n\r\nfunction getSmartSuggestions(): string {\r\n return `💡 GLASSMCP SMART SUGGESTIONS:\r\n\r\n🔍 Getting Started:\r\n• Try: window_list() to see all open windows\r\n• Try: window_focus(\"Visual Studio Code\") to focus VS Code\r\n• Try: window_extract_text_by_title(\"Notepad\") to get text content\r\n• Try: clipboard_get_text() to see current clipboard\r\n\r\n⚡ Window Management:\r\n• Use exact=true for precise window title matching\r\n• Extract text before sending input for context awareness\r\n• Focus windows before sending text for reliability\r\n• Use clipboard operations for large text transfers\r\n\r\n🛠️ Advanced Automation:\r\n• Combine text extraction with analysis for intelligent responses\r\n• Chain operations: focus → extract → analyze → respond\r\n• Use window handles for direct window manipulation\r\n• Monitor clipboard for cross-application workflows\r\n\r\n📈 Best Practices:\r\n• Always check window_list first to identify available windows\r\n• Use descriptive window titles for reliable automation\r\n• Handle errors gracefully with fallback strategies\r\n• Test automation sequences before deployment`;\r\n}\r\n\r\nfunction getUsageTips(): string {\r\n return `🎯 GLASSMCP USAGE TIPS:\r\n\r\n🪟 Window Management:\r\n• window_list() - Get all windows: [{\"handle\": \"123\", \"title\": \"App\", \"isVisible\": true}]\r\n• window_focus(\"Chrome\") - Focus browser window\r\n• window_focus(\"Document.docx\", true) - Exact title match\r\n\r\n📝 Text Operations:\r\n• window_extract_text_by_title(\"Notepad\") - Get all text from Notepad\r\n• window_send_text_by_title(\"Terminal\", \"echo Hello\") - Send commands\r\n• window_extract_text(123456) - Extract using window handle\r\n\r\n📋 Clipboard Operations:\r\n• clipboard_get_text() - Read clipboard: {\"text\": \"copied content\"}\r\n• clipboard_set_text(\"Hello World\") - Write to clipboard\r\n\r\n🚀 Pro Tips:\r\n• Use window_list() first to discover available applications\r\n• Focus windows before text operations for best results\r\n• Extract text to understand current context before responding\r\n• Use exact title matching for reliable automation\r\n• Chain operations for complex automation workflows`;\r\n}\r\n// =================== END CAPABILITY DISCOVERY FUNCTIONS ===================\r\n\r\n// Define enhanced tools\r\nconst tools: Tool[] = [\r\n {\r\n name: 'window_list',\r\n description: 'List all open windows with their titles, handles, and properties. Use query parameter for help and system information.',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n query: {\r\n type: 'string',\r\n description: 'Optional query for help or system information (e.g., \"help\", \"capabilities\")',\r\n }\r\n },\r\n required: [],\r\n },\r\n },\r\n {\r\n name: 'window_focus',\r\n description: 'Focus a specific window by title',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n title: {\r\n type: 'string',\r\n description: 'The title of the window to focus',\r\n },\r\n exact: {\r\n type: 'boolean',\r\n description: 'Whether to match the title exactly',\r\n default: false,\r\n },\r\n },\r\n required: ['title'],\r\n },\r\n },\r\n {\r\n name: 'window_extract_text',\r\n description: 'Extract all text content from a window using UI Automation',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n windowHandle: {\r\n type: 'number',\r\n description: 'The handle of the window to extract text from',\r\n },\r\n },\r\n required: ['windowHandle'],\r\n },\r\n },\r\n {\r\n name: 'window_extract_text_by_title',\r\n description: 'Extract text content from a window by finding it by title',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n title: {\r\n type: 'string',\r\n description: 'The title of the window to extract text from',\r\n },\r\n exact: {\r\n type: 'boolean',\r\n description: 'Whether to match the title exactly',\r\n default: false,\r\n },\r\n },\r\n required: ['title'],\r\n },\r\n },\r\n {\r\n name: 'window_send_text',\r\n description: 'Send text input to a specific window',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n windowHandle: {\r\n type: 'number',\r\n description: 'The handle of the window to send text to',\r\n },\r\n text: {\r\n type: 'string',\r\n description: 'The text to send to the window',\r\n },\r\n },\r\n required: ['windowHandle', 'text'],\r\n },\r\n },\r\n {\r\n name: 'window_send_text_by_title',\r\n description: 'Send text input to a window by finding it by title',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n title: {\r\n type: 'string',\r\n description: 'The title of the window to send text to',\r\n },\r\n text: {\r\n type: 'string',\r\n description: 'The text to send to the window',\r\n },\r\n exact: {\r\n type: 'boolean',\r\n description: 'Whether to match the title exactly',\r\n default: false,\r\n },\r\n },\r\n required: ['title', 'text'],\r\n },\r\n },\r\n {\r\n name: 'clipboard_get_text',\r\n description: 'Get text content from the system clipboard',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {},\r\n required: [],\r\n },\r\n },\r\n {\r\n name: 'clipboard_set_text',\r\n description: 'Set text content to the system clipboard',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n text: {\r\n type: 'string',\r\n description: 'The text to set in the clipboard',\r\n },\r\n },\r\n required: ['text'],\r\n },\r\n },\r\n];\r\n\r\n// Create MCP server\r\nconst server = new Server(\r\n {\r\n name: 'GlassMCP Enhanced',\r\n version: '5.1.0',\r\n },\r\n {\r\n capabilities: {\r\n tools: {},\r\n },\r\n }\r\n);\r\n\r\n// Handle tool requests\r\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\r\n const { name, arguments: args } = request.params;\r\n\r\n try {\r\n switch (name) {\r\n case 'window_list': {\r\n const { query } = args as { query?: string };\r\n\r\n // Check for capability/help queries\r\n if (query && (isSystemCapabilityQuery(query) || isHelpQuery(query))) {\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: JSON.stringify({\r\n windows: [],\r\n count: 0,\r\n message: \"GlassMCP system information and capabilities\",\r\n debug: {\r\n requestId: `v5.1-${Date.now()}-${Math.random().toString(36).substr(2, 6)}`,\r\n queryLength: query.length,\r\n isCapabilityQuery: isSystemCapabilityQuery(query),\r\n isHelpQuery: isHelpQuery(query),\r\n timestamp: new Date().toISOString()\r\n },\r\n performance: {\r\n responseTime: \"0ms\",\r\n requestId: `v5.1-${Date.now()}-${Math.random().toString(36).substr(2, 6)}`,\r\n serverType: \"glass-mcp-enhanced-v5.1.0\",\r\n timestamp: new Date().toISOString()\r\n },\r\n systemInfo: {\r\n server: {\r\n name: \"GlassMCP Enhanced\",\r\n version: \"5.1.0\",\r\n platform: \"Windows (win32)\",\r\n status: \"Active and Operational\"\r\n },\r\n capabilities: {\r\n coreTools: [\r\n {\r\n name: \"window_list\",\r\n description: \"List all open windows with properties\",\r\n usage: \"window_list(query?)\",\r\n features: [\"Window discovery\", \"Property inspection\", \"System information\"]\r\n },\r\n {\r\n name: \"window_focus\",\r\n description: \"Focus specific windows by title\",\r\n usage: \"window_focus(title, exact?)\",\r\n features: [\"Window activation\", \"Exact/fuzzy matching\", \"Error handling\"]\r\n },\r\n {\r\n name: \"window_extract_text\",\r\n description: \"Extract text content from windows\",\r\n usage: \"window_extract_text(windowHandle) / window_extract_text_by_title(title, exact?)\",\r\n features: [\"UI Automation\", \"Text extraction\", \"Content analysis\"]\r\n },\r\n {\r\n name: \"window_send_text\",\r\n description: \"Send text input to windows\",\r\n usage: \"window_send_text(windowHandle, text) / window_send_text_by_title(title, text, exact?)\",\r\n features: [\"Text input\", \"Automation\", \"Cross-application communication\"]\r\n },\r\n {\r\n name: \"clipboard_operations\",\r\n description: \"Clipboard get/set operations\",\r\n usage: \"clipboard_get_text() / clipboard_set_text(text)\",\r\n features: [\"System clipboard\", \"Cross-app data transfer\", \"Text operations\"]\r\n }\r\n ],\r\n advancedFeatures: [\r\n \"PowerShell-based Windows API integration\",\r\n \"Real-time UI Automation capabilities\",\r\n \"Error handling with detailed diagnostics\",\r\n \"Safe window detection and manipulation\",\r\n \"Optimized text extraction algorithms\",\r\n \"Cross-application automation workflows\"\r\n ],\r\n platformSupport: [\r\n \"Windows-only (win32) automation server\",\r\n \"All Windows applications with UI elements\",\r\n \"VS Code, browsers, office apps, and more\",\r\n \"Visible and background window support\"\r\n ]\r\n }\r\n },\r\n smartSuggestions: getSmartSuggestions().split('\\n'),\r\n usageTips: getUsageTips().split('\\n'),\r\n systemInformation: getSystemInformation().split('\\n')\r\n }, null, 2)\r\n }\r\n ]\r\n };\r\n }\r\n\r\n const windows = await listWindows();\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: JSON.stringify(windows, null, 2),\r\n },\r\n ],\r\n };\r\n }\r\n\r\n case 'window_focus': {\r\n const { title, exact = false } = args as { title: string; exact?: boolean };\r\n const result = await focusWindow(title, exact);\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: JSON.stringify(result),\r\n },\r\n ],\r\n };\r\n }\r\n\r\n case 'window_extract_text': {\r\n const { windowHandle } = args as { windowHandle: number };\r\n const textContent = await extractWindowText(windowHandle);\r\n\r\n // Clean and sanitize the content for JSON serialization\r\n const cleanContent = {\r\n ...textContent,\r\n windowTitle: textContent.windowTitle.replace(/[\\x00-\\x1F\\x7F-\\x9F]/g, ' ').trim(),\r\n textElements: textContent.textElements.map(el => ({\r\n ...el,\r\n text: el.text.replace(/[\\x00-\\x1F\\x7F-\\x9F]/g, ' ').replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').trim()\r\n }))\r\n };\r\n\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: JSON.stringify(cleanContent, null, 2),\r\n },\r\n ],\r\n };\r\n }\r\n\r\n case 'window_extract_text_by_title': {\r\n const { title, exact = false } = args as { title: string; exact?: boolean };\r\n const windows = await listWindows();\r\n const window = windows.find(w =>\r\n exact ? w.title === title : w.title.toLowerCase().includes(title.toLowerCase())\r\n );\r\n\r\n if (!window) {\r\n throw new GlassMCPError(`Window not found: ${title}`);\r\n }\r\n\r\n const textContent = await extractWindowText(parseInt(window.handle));\r\n\r\n // Create a simple, safe text response instead of JSON\r\n const textList = textContent.textElements.map(el => el.text).join('\\n');\r\n const response = `Window: ${textContent.windowTitle}\\nElements: ${textContent.textElements.length}\\nText Content:\\n${textList}`;\r\n\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: response,\r\n },\r\n ],\r\n };\r\n }\r\n\r\n case 'window_send_text': {\r\n const { windowHandle, text } = args as { windowHandle: number; text: string };\r\n const result = await sendTextToWindow(windowHandle, text);\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: JSON.stringify(result),\r\n },\r\n ],\r\n };\r\n }\r\n\r\n case 'window_send_text_by_title': {\r\n const { title, text, exact = false } = args as { title: string; text: string; exact?: boolean };\r\n const windows = await listWindows();\r\n const window = windows.find(w =>\r\n exact ? w.title === title : w.title.toLowerCase().includes(title.toLowerCase())\r\n );\r\n\r\n if (!window) {\r\n throw new GlassMCPError(`Window not found: ${title}`);\r\n }\r\n\r\n const result = await sendTextToWindow(parseInt(window.handle), text);\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: JSON.stringify(result),\r\n },\r\n ],\r\n };\r\n }\r\n\r\n case 'clipboard_get_text': {\r\n const text = await getClipboardText();\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: JSON.stringify({ text }),\r\n },\r\n ],\r\n };\r\n }\r\n\r\n case 'clipboard_set_text': {\r\n const { text } = args as { text: string };\r\n const result = await setClipboardText(text);\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: JSON.stringify(result),\r\n },\r\n ],\r\n };\r\n }\r\n\r\n default:\r\n throw new GlassMCPError(`Unknown tool: ${name}`);\r\n }\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : String(error);\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: JSON.stringify({ error: errorMessage }),\r\n },\r\n ],\r\n isError: true,\r\n };\r\n }\r\n});\r\n\r\n// Handle tool listing\r\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\r\n return { tools };\r\n});\r\n\r\n// Start the server\r\nasync function main() {\r\n const transport = new StdioServerTransport();\r\n await server.connect(transport);\r\n console.error('Enhanced GlassMCP Server started successfully');\r\n}\r\n\r\nmain().catch((error) => {\r\n console.error('Server failed to start:', error);\r\n process.exit(1);\r\n});\r\n"],"mappings":"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","names":[]}