Plugging Windows Desktop Control into Four AI Agents: Hermes, OpenCode, Claw, and Claude
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:
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:
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:
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:
$ 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:
{
"$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:
$ 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):
{
"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:
$ 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:
{
"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:
DisplayInventory: Queried my dual-screen setup (1080p primary + 1440p secondary) and returned correct virtual desktop boundaries (left: -313, top: -1440, right: 2247, bottom: 1080).Screenshot: Captured the active screen buffer with downscaling enabled, validating that cursor coordinates were correctly logged (1318, -714).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.
Want a 24/7 bot or automation pipeline that never drops a lead?
Don't let customer inquiries slip away at midnight or on weekends. I build custom Telegram/WhatsApp AI assistants and deterministic workflows that connect directly to your catalogue, CRM, and order fulfillment.