mcp-windows-debug

mcp-windows-debug

A Windows-only MCP server that gives AI models eyes and hands on a Windows machine, enabling file reading, screenshots, mouse/keyboard injection, and an auto-debug loop with a safety-focused watchdog for protected abort regions.

Category
访问服务器

README

mcp-windows-debug

CI TypeScript License: MIT

A TypeScript/Node.js MCP server that plugs into OpenCode over stdio and gives the model eyes and hands on a Windows machine: it reads project files, captures screenshots, moves the mouse and types keys, and runs an auto-debug loop against a target application.

Safety is the point of the whole design. A separate native C++ watchdog process installs global low-level keyboard and mouse hooks so a human can always click a protected abort button, even while the model is injecting input. The Node MCP server and the watchdog are two independent processes, so a stalled Node event loop cannot freeze your input or silently drop the safety layer. Every action flows through three gates: a governor, a freshness check, and a window-scoping guard. Details are in the Security model section below.

This is a Windows-only v1. macOS and Linux backends plug in later behind the same provider interfaces; they are not implemented yet.

Quick start

git clone https://github.com/wgm66/mcp-windows-debug.git
cd mcp-windows-debug
npm install && npm run build
cd src\watchdog && build.bat   # build the C++ watchdog (MSVC required)
node dist\index.js --validate-config  # verify your OpenCode config

Installation

Prerequisites:

  • Node.js 20 or newer, plus npm
  • Windows 10 or 11
  • Administrator access, needed only to run the watchdog (see below)

Install dependencies and build the TypeScript:

npm install
npm run build

npm run build runs tsc and produces dist/index.js, which is the entry point OpenCode launches.

Next, build the watchdog. It is a C++ Win32 console app compiled with MSVC, no CMake, MSBuild, or MinGW involved:

cd src\watchdog
build.bat

build.bat requires the VS2019 Build Tools (MSVC 14.29) and the Windows SDK. The toolchain paths are hardcoded in the script, so it expects them at their default install locations. The output is src\watchdog\watchdog.exe, which the Node server locates relative to the project root at runtime.

The watchdog must run elevated. Global low-level hooks refuse to install from a non-elevated process. Two ways to satisfy this:

  1. Start OpenCode from an elevated terminal, so the spawned watchdog inherits elevation.
  2. Pre-start the watchdog as admin yourself before starting a debug session.

The server cannot request UAC elevation on its own in this build. A debug session that cannot reach an elevated watchdog fails with ELEVATION_REQUIRED, and a non-elevated watchdog run prints ERROR_ACCESS_DENIED and exits with code 1 rather than silently doing nothing.

OpenCode configuration

Add a windows-debug entry under the mcp key in your OpenCode config (opencode.json). Note the key is mcp, not mcpServers:

{
  "mcp": {
    "windows-debug": {
      "type": "local",
      "command": ["node", "<abs-path>/dist/index.js"],
      "environment": {}
    }
  }
}

Replace <abs-path> with the absolute path to this project, using forward slashes so the JSON needs no escaping. For example, if the project lives at G:\工程开发\AI全场景图形化调试, the command becomes:

"command": ["node", "G:/工程开发/AI全场景图形化调试/dist/index.js"]

The command is an array of argv tokens. The environment map is empty by default; the per-session watchdog token is generated by the server itself and passed to the watchdog over the process environment, so you do not need to set anything here.

Usage

A debug session has a fixed shape: register protected abort buttons, start the session, let the model work through the auto-debug loop, then end the session.

Register abort buttons. A session cannot start with zero protected regions. Pass one or more screen rectangles to start_debug_session as regions ({ x, y, w, h, id }, physical pixels). Injected input aimed inside any registered region is blocked by the watchdog. Human input always passes, so the region is a guaranteed physical abort area the model cannot reach. Regions are append-only for the session lifetime; there is deliberately no way to remove or move one after start.

Start the session. start_debug_session spawns or attaches the watchdog, registers every region, and starts the heartbeat. The orchestrator begins monitoring the current foreground window as the debug target. Pass sandbox: 'desktop' to run injection on a private Win32 desktop (PostMessage-based, user's real mouse/keyboard untouched) instead of SendInput (which moves the real cursor). sandbox: 'rdp' is reserved but not implemented in v1.

The auto-debug loop. While the session is active, the orchestrator polls the target window for changes: title, rectangle, foreground status, and optionally a screenshot-signature diff. When a trigger fires, it captures a fresh screenshot and exposes it as the debug://context resource. The client (OpenCode) polls debug://context, decides what to do, and calls execute_action with that decision. The orchestrator never decides actions on its own; it only executes client decisions, and only after the governor, freshness, and safety gates all pass.

End the session. end_debug_session sends SHUTDOWN, kills the watchdog if it does not respond within one second, releases any held modifier keys, and returns to IDLE. If the MCP process dies without a clean shutdown, the watchdog's dead-man switch removes the hooks on its own (see the Security model section).

Tools

Ten tools are registered.

Tool Purpose
read_file Read a text file from an absolute path; binary files return base64.
list_directory List the immediate entries of a directory.
capture_window Capture a window by exact title as a PNG; empty title means the frontmost window.
mouse_click Click at logical screen coordinates with a given button.
mouse_move Move the cursor to logical screen coordinates.
key_press Press a key, optionally holding modifiers.
type_text Type a text string as keyboard input.
start_debug_session Spawn or attach the watchdog and register protected abort regions. Accepts optional sandbox: 'desktop' for isolated PostMessage injection.
end_debug_session End the active session and shut down the watchdog.
execute_action Execute a client-decided action inside the active session.
inspect_element Enumerate visible UI elements (name, role, rect, enabled) via UIAutomation tree walker.

The four input tools (mouse_click, mouse_move, key_press, type_text) all route through the safety layer's injectGuarded gate. Calling them with no active session returns NO_ACTIVE_SESSION. Calling them while the cursor or keyboard focus is outside the target window returns WINDOW_SCOPE_VIOLATION.

Resources

Three resources are registered.

URI Content
screenshot://full PNG capture of the primary monitor.
screenshot://monitor/{index} PNG capture of a specific monitor by 0-based index.
debug://context JSON snapshot of the auto-debug loop: status, target, trigger, screenshot, governor state.

Governor limits

The orchestrator enforces a fixed throttle on interventions:

  • 5 second cooldown between actions
  • 6 interventions per minute
  • auto-pause after 3 consecutive failures
  • hard 30-minute session cap, after which the session auto-ends

Rejections for cooldown, rate limit, or pause are throttling, not failures. Only a stale-state refusal or an injection error counts toward the 3-failure pause.

Security model

What this design guarantees, and what it does not.

Dual-process isolation. The Node MCP server and the native watchdog are separate processes. A stuck Node event loop cannot block the hooks or drop the safety layer, because the watchdog runs its own message loop.

Dead-man switch. The watchdog listens on a named pipe and treats any byte as a heartbeat. If no heartbeat arrives for more than 2 seconds, it calls UnhookWindowsHookEx on both hooks and exits cleanly. Combined with the removal grace period, hooks come down within 3 seconds of MCP death, so a crashed or killed server never leaves input blocked. This is the fail-safe contract; it is not a sub-second guarantee.

Window scoping. Every injection is refused unless a session is active and the cursor and keyboard focus are inside the session target window.

Secure-desktop handling. If the OS switches to the secure desktop (UAC prompt or lock screen), the orchestrator pauses and refuses injection with zero input attempted.

Append-only audit. Every file read, injected action, screenshot request, and intervention decision is logged to an append-only audit log. Keystroke content and file content are never written to it.

What it does NOT guarantee. Read this part carefully, because these are the honest residual risks.

  • Injected-input filtering is not absolute blocking. The watchdog blocks input carrying the LLKHF_INJECTED / LLMHF_INJECTED flags when the destination falls inside a protected region. That stops machine-injected input, which is what SendInput produces. It does not stop every possible input source. Another process could theoretically synthesize non-flagged input by other means, and that input would pass the filter. This tool does not claim absolute physical blocking. Treat the abort button as a strong, best-effort safety net, not a mathematical guarantee.
  • It is a remote-control primitive in the worst case. The full tool surface is file read plus screenshot capture plus keyboard and mouse injection. If an attacker or a misbehaving model controls it, that is the capability they get. Use it on a machine and against windows you are willing to have that surface pointed at.
  • Antivirus and EDR can flag it. Global low-level hooks and SendInput injection are exactly the techniques remote-access tools and keyloggers use. Expect false positives from AV/EDR products, including the watchdog being quarantined or killed mid-session. The dead-man switch makes that safe (hooks come down), but it will interrupt sessions. See Troubleshooting.
  • Elevation widens the surface. The watchdog needs admin to install global hooks, so a session runs with an elevated process in the picture. Do not run it on a machine where that exposure is unacceptable.

No keystroke or button content is ever read or logged by the watchdog; only the injected flag and the cursor destination are inspected. Transport is the local named pipe only. There is no TCP, no network listener, no remote control.

Troubleshooting

Antivirus or EDR flags the watchdog. Add an exclusion for src\watchdog\watchdog.exe (or the project directory) in your AV/EDR console. The durable fix is code signing: a signed binary is far less likely to be quarantined. If the watchdog gets killed mid-session, the session transitions to IDLE and all input tools are refused until a new start_debug_session.

Windows detaches the hook (LowLevelHooksTimeout). Low-level hook procedures have a hard execution budget, controlled by HKCU\Control Panel\Desktop\LowLevelHooksTimeout (default 300 ms). If the hook proc runs too long, Windows silently removes it. The watchdog keeps its hook proc well under 100 ms, so this should not trigger in normal use. If you see hooks dropping on a heavily loaded machine, the problem is system load or interference from another low-level hook, not this tool.

Clicks land at the wrong place on a multi-monitor or mixed-DPI setup. Coordinates are mapped between logical and physical pixels using per-monitor DPI. On mixed-DPI multi-monitor setups there is a known limitation: the logical to physical conversion passes logical coordinates to a call that expects physical pixels. It is harmless at 96 DPI but can drift on scaled monitors. If a click misses, capture a screenshot first, read the target coordinates from it, and prefer working on the primary monitor.

A UAC prompt appears, or injection silently fails. The watchdog runs elevated, so spawning it can surface a UAC prompt. If you cancel it, the session fails with ELEVATION_REQUIRED. The server cannot re-request elevation on its own in this build, so pre-start the watchdog as admin before starting the session, or launch OpenCode from an elevated terminal.

ERROR_ACCESS_DENIED when running the watchdog manually. This is the expected behavior for a non-elevated shell. The watchdog refuses to run without admin and prints ERROR_ACCESS_DENIED with exit code 1, so there is no silent no-op. Run it from an elevated PowerShell instead.

Session recording

Sessions can be recorded as JSON transcripts for later replay. The recorder hooks into the audit log and captures every tool call (name, args, result, timestamp) without keystroke content (data minimization). Transcripts are saved to .omo/recordings/session-<id>.json.

# A session transcript can be replayed programmatically:
node -e "const { SessionRecorder } = require('./dist/recording'); SessionRecorder.replay('.omo/recordings/session-xxx.json', async (call) => { console.log(call.toolName, call.args); })"

UIAutomation (accessibility API)

The inspect_element tool enumerates visible UI elements via the UIAutomation tree walker (competitor parity with terminator-mcp-agent and Windows MCP Inspector). In v1, this is a stub that returns elements from the injected deps seam; full COM interop requires a native N-API addon (future work). The UIAutomationProvider class implements InputProvider but throws UIAutomationError for injection methods in v1 — use SendInput or PostMessage paths for actual injection.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选