--- title: "Plugging Windows Desktop Control into Four AI Agents: Hermes, OpenCode, Claw, and Claude" description: "How to configure, verify, and standardize windows-mcp across Hermes Agent, OpenCode CLI, Claw Code, and Claude Code without config drift or tool sprawl." pubDate: 2025-12-23 updatedDate: 2026-10-25 category: ai tags: ["windows", "mcp", "ai-agents", "hermes", "opencode", "claw-code"] ogImage: /og/plugging-windows-desktop-control-into-four-ai-agents.jpg banner: /banners/plugging-windows-desktop-control-into-four-ai-agents.jpg draft: false dynamicCta: true --- In a multi-agent development environment, running different agent frameworks for specialized tasks is standard practice. On the Windows workstation I manage, I orchestrate four distinct AI coding agents: - **Hermes Agent**: Built by Nous Research, powering primary multi-modal orchestration and terminal tooling. - **OpenCode**: A flexible, provider-agnostic autonomous coding agent with a terminal UI. - **Claw Code**: The clean-room Rust CLI implementation of Claude Code. - **Claude Code**: Anthropic's flagship coding agent. While all four agents excel at editing files and running shell commands, none of them come with out-of-the-box support for manipulating legacy Windows desktop GUIs, interacting with system file dialogs, or capturing desktop window state. Enter `windows-mcp`, an open-source Model Context Protocol server exposing Windows UIAutomation, mouse, keyboard, and window management tools. Here is how I unified this server across all four agent platforms without configuration drift. --- ## The Python 3.14+ Baseline `windows-mcp` has one strict prerequisite: it requires **Python 3.14+**. On Windows, managing Python versions manually across different environments can easily turn into path conflicts. The cleanest execution strategy is relying on `uv`'s `uvx` ephemeral launcher. With `uvx`, each agent invokes: ```bash uvx windows-mcp serve ``` `uvx` fetches the isolated environment on demand, installs pre-built binary wheels for PyWin32 and Pydantic, and runs the server over standard input/output (`stdio`) without polluting the global system interpreter. --- ## 1. Hermes Agent Hermes Agent features a native MCP client configured through `~/.hermes/config.yaml`. You can register it directly via the Hermes CLI tool discovery mechanism: ```bash printf 'y\n' | hermes mcp add windows-mcp --command uvx \ --env WINDOWS_MCP_CONTROL=false WINDOWS_MCP_SCREENSHOT_SCALE=0.5 WINDOWS_MCP_DISABLE_FLASH=1 WINDOWS_MCP_EXCLUDE_PROCESSES=Code.exe,Cursor.exe ANONYMIZED_TELEMETRY=false \ --args windows-mcp serve --exclude-tools PowerShell,Registry ``` Under the hood, this writes the following block to `~/.hermes/config.yaml`: ```yaml mcp_servers: windows-mcp: command: uvx args: - windows-mcp - serve - --exclude-tools - PowerShell,Registry env: WINDOWS_MCP_CONTROL: "false" WINDOWS_MCP_SCREENSHOT_SCALE: "0.5" WINDOWS_MCP_DISABLE_FLASH: "1" WINDOWS_MCP_EXCLUDE_PROCESSES: Code.exe,Cursor.exe ANONYMIZED_TELEMETRY: "false" ``` Verify the connection: ```bash $ hermes mcp list MCP Servers: Name Transport Tools Status ──────────────── ────────────────────── ──────── ────────── windows-mcp uvx windows-mcp serve all ✓ enabled ``` --- ## 2. OpenCode OpenCode reads its MCP configuration from `~/.config/opencode/opencode.jsonc`. Add the `windows-mcp` server entry inside the top-level `"mcp"` dictionary: ```jsonc { "$schema": "https://opencode.ai/config.json", "mcp": { "windows-mcp": { "type": "local", "command": ["uvx", "windows-mcp", "serve", "--exclude-tools", "PowerShell,Registry"], "enabled": true, "environment": { "WINDOWS_MCP_CONTROL": "false", "WINDOWS_MCP_SCREENSHOT_SCALE": "0.5", "WINDOWS_MCP_DISABLE_FLASH": "1", "WINDOWS_MCP_EXCLUDE_PROCESSES": "Code.exe,Cursor.exe", "ANONYMIZED_TELEMETRY": "false" } } } } ``` Verify that OpenCode connects cleanly: ```bash $ opencode mcp list ┌ MCP Servers │ ● ✓ windows-mcp connected │ uvx windows-mcp serve --exclude-tools PowerShell,Registry │ └ 1 server(s) ``` --- ## 3. Claw Code (claw.exe) Claw Code (v0.1.7) looks for MCP definitions in `.claw/settings.json` (project-level) or `~/.claw/settings.json` (user-level): ```json { "mcpServers": { "windows-mcp": { "command": "uvx", "args": [ "windows-mcp", "serve", "--exclude-tools", "PowerShell,Registry" ], "env": { "WINDOWS_MCP_CONTROL": "false", "WINDOWS_MCP_SCREENSHOT_SCALE": "0.5", "WINDOWS_MCP_DISABLE_FLASH": "1", "WINDOWS_MCP_EXCLUDE_PROCESSES": "Code.exe,Cursor.exe", "ANONYMIZED_TELEMETRY": "false" } } } } ``` Verify in Claw Code: ```bash $ claw mcp MCP Working directory C:\Users\workstation Configured servers 1 Total entries 1 Invalid entries 0 windows-mcp stdio user uvx windows-mcp serve --exclude-tools PowerShell,Registry ``` --- ## 4. Claude Code Claude Code shares the exact same schema in `~/.claude.json`. Mirror the `windows-mcp` block into `~/.claude.json`: ```json { "mcpServers": { "windows-mcp": { "command": "uvx", "args": ["windows-mcp", "serve", "--exclude-tools", "PowerShell,Registry"], "env": { "WINDOWS_MCP_CONTROL": "false", "WINDOWS_MCP_SCREENSHOT_SCALE": "0.5", "WINDOWS_MCP_DISABLE_FLASH": "1", "WINDOWS_MCP_EXCLUDE_PROCESSES": "Code.exe,Cursor.exe", "ANONYMIZED_TELEMETRY": "false" } } } } ``` --- ## Proving End-to-End Operation Rather than hoping the configurations work, I ran an automated probe script via Python's standard `mcp` SDK to exercise three critical tools end-to-end: 1. `DisplayInventory`: Queried my dual-screen setup (1080p primary + 1440p secondary) and returned correct virtual desktop boundaries (`left: -313, top: -1440, right: 2247, bottom: 1080`). 2. `Screenshot`: Captured the active screen buffer with downscaling enabled, validating that cursor coordinates were correctly logged (`1318, -714`). 3. `Notification`: Dispatched a native Windows 11 toast notification to the notification center. With identical arguments and environment variables mirrored across all four agent configs, any of my coding agents can now seamlessly interact with native Windows software when code or APIs alone cannot bridge the gap.