opencode-gui-bridge
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@opencode-gui-bridge打开记事本,在里面输入你好"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
opencode-gui-bridge
Give opencode (or any MCP client) computer-use capabilities: it can see (understand screen state), act (click/type/scroll), and verify (confirm the action took effect).
Built on PySide6 + Win32 API + Windows UI Automation + local OCR, with zero system-level dependencies. All basic operations run locally with no network requirement (only the vision describe optionally uses a network API).
Quick Start
Extract the project to any directory (e.g.
D:\gui-bridge\), double-clicksetup.bat, and wait for it to showDone.Put an
opencode.jsonin your opencode working directory (see "Integrating with opencode"), and change both paths to the actual paths from step 1Restart opencode
Just say it in the AI chat:
"List the windows on the computer" → get the
list_targetsresult"Open Notepad and type hello in it" → it will automatically run open → bind → snapshot → click → input → verify
Related MCP server: uiautomation-mcp
Installation
.\setup.batThe script does everything in one pass: creates a venv virtual environment (skipped if it already exists) → pip installs dependencies → runs a smoke test. Seeing Done. means installation succeeded; on failure it exits and prints the reason.
Manual installation has the same effect:
python -m venv venv
venv\Scripts\python -m pip install -e .
venv\Scripts\python tests\smoke_test.pyRequirements: Windows 10/11 + Python 3.10+ (check Add python.exe to PATH during installation).
Integrating with opencode
Put opencode.json in the working directory where you run opencode (not inside the project):
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"gui-bridge": {
"type": "local",
"command": [
"D:\\gui-bridge\\venv\\Scripts\\python.exe",
"D:\\gui-bridge\\server.py"
],
"enabled": true,
"environment": {
"SILICONFLOW_API_KEY": "{env:SILICONFLOW_API_KEY}"
}
}
}
}Two changes to make:
Replace both
D:\\gui-bridge\\...paths with your actual paths (\must be written as\\in JSON)The
SILICONFLOW_API_KEYline: local OCR and click/input don't need any key; you only need to configure it if you plan to use vision describe (see next section). Delete the line if you have no key.
Verify the integration: after restarting opencode, tell the AI "list the windows on the computer"; if the AI returns a window list, the python.exe and server.py paths are configured correctly.
Vision Channel Configuration (for describe, optional)
list_targets returns channels.vision with a status of ready (has key) or no-key (doesn't). It uses an OpenAI-compatible API, any vendor:
Environment variable | Purpose | Default |
| API endpoint (OpenAI/DeepSeek/Qwen/Zhipu, etc.) |
|
| Vision key (falls back to | — |
| Vision understanding model |
|
| Vision OCR model (OCR fallback for describe) |
|
Three ways to set it, pick any one:
a) Embedded in opencode.json (travels with the config, recommended)
"environment": {
"VISION_BASE_URL": "https://api.siliconflow.cn/v1",
"VISION_API_KEY": "{env:OPENAI_API_KEY}",
"VISION_MODEL": "Qwen/Qwen3-VL-32B-Instruct"
}{env:XXX} means read an existing environment variable of the same name from your machine.
b) System-level persistence (applies to all terminals):
setx VISION_API_KEY "sk-xxxx"
setx VISION_BASE_URL "https://api.siliconflow.cn/v1"After setting, you must reopen the terminal and restart opencode for it to take effect.
c) Only for the current terminal session:
$env:VISION_API_KEY = "sk-xxxx"CDP Channel Configuration (WebView2 / Tauri / Electron)
For Web-kernel apps like Tauri, WebView2, and Electron, UIA can only see the outer shell and can't read the DOM. Once the CDP debug port is enabled, snapshots automatically go through the CDP channel (element ids prefixed with d:), and full-text reads are millisecond-fast.
Enable the debug port by app type:
App type | Method |
Chrome/Edge browser | Launch with the flag: |
WebView2 (WPF/WinForms/Tauri embedded) | Set the environment variable first, then launch the app: |
Electron app | Launch with the flag: |
$env:WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS = "--remote-debugging-port=9222 --remote-allow-origins=*"
Start-Process 目标应用After launching, confirm with list_targets: the returned channels.cdp will show the port number (e.g. 9222). From then on, snapshot automatically uses CDP and act automatically routes DOM operations:
Read full page text: DOM innerText, <10ms (OCR takes 1~6s)
Click: native DOM click (bypasses physical hit-test overlays)
Input: Input.insertText real input pipeline (compatible with editors like Quill)
Element coordinates: CSS×DPR+window position approximation (operations don't depend on coordinates)
Not enabling it doesn't break anything: such apps automatically fall back to the local OCR channel and can still read the screen and operate.
Toolbox: 7 MCP Tools
Tool | Parameters | Purpose | Typical return |
| none | Enumerate available windows + 4 channel statuses |
|
| handle or title (substring match) | Bind the target window |
|
|
| UI snapshot, returns a batch of elements with stable ids | Multi-line text, e.g. |
| action and target | Click/input/keys/scroll/enter, with verification |
|
| region or text | Wait for UI change / a certain text to appear |
|
| region optional (defaults to target window) | Save screenshot to | Save path |
| screenshot file path, omitted = target window | Vision model describes the screen (requires vision key) | Natural language description |
Rules: snapshot/act must be called after focus_target.
act Action Details
action | Parameters | Description |
|
| Click an element, channel auto-selected by id prefix |
|
| Focus the element and type text, then auto-OCR to verify the text appears |
|
| Key combos, |
| none | Equivalent to |
|
| Scroll; with coordinates, scroll to that point |
Return structure {ok, verify, detail}:
ok: whether the action executedverify: result of automatic verification after executionchanged/matched: the UI actually changed / the input content is confirmed to have appearedno_change/no_match: expected change not detected (the action may not have taken effect; re-snapshot to see the latest state)cdp_insert/skipped: went through CDP input or verification was explicitly disabledfailed: execution failed,detailcarries the reason; click-type failures automatically retry physically and attach a diagnostic screenshot path
detail: human-readable result description, may includeDiagnostic screenshot: <path>
Architecture
┌─ Agent (AI)
│ 7 个 MCP 工具: list_targets / focus_target / snapshot /
│ act / wait_change / screenshot / describe
├─ server.py 会话编排: 目标窗口绑定, 通道选择, 验证闭环
├─ snapshot.py 统一元素抽象: {id, type, text, bbox, enabled, focused}
│ 通道融合 + 稳定 id (u:路径链 / o:OCR索引)
├─ executor.py 动作路由: click/input/press/scroll + 内置验证
├─ uia.py UIA 控件树通道 (L1, 毫秒级, 原生应用)
├─ ocr.py 本地 OCR 通道 (L2, 1~6s, WebView 兜底)
├─ win32io.py Win32 底层: 窗口/鼠标/键盘/截图/PostMessage/PrintWindow
└─ vision.py 视觉模型通道 (L3, 兜底理解, 需 API key)
运行日志写入 `logs/gui-bridge.log`(JSON lines:每次工具调用的耗时/通道/结果)。Core Design
The AI only operates by element id, never coordinates. The snapshot provides ids, and act automatically routes each id to the best channel.
Automatic channel fallback: CDP → UIA → OCR → vision; click: InvokePattern → PostMessage → physical.
Built-in verification loop: act returns verify=changed/no_match/failed + reason.
Occlusion-safe capture: OCR and verification use PrintWindow to grab the target window's real content directly, so even if the target is covered by other windows, content doesn't get mixed up.
Element ID Rules
Prefix | Source | Example | Stability |
| CDP DOM |
| Stable if structure unchanged |
| UIA |
| Stable if structure unchanged |
| OCR |
| Re-snapshot needed after every UI change |
For o: ids and u: ids that go stale after UI changes, re-run snapshot to get fresh ids before clicking.
Testing
venv\Scripts\python tests\smoke_test.py # 7 工具 + UIA 全链路(自建测试窗口)
venv\Scripts\python tests\ocr_test.py # OCR 通道兜底链路
venv\Scripts\python tests\stdio_e2e.py # 端到端:真实 MCP stdio 会话Known Limitations
WebView2/Tauri double-shell DOM isn't exposed to UIA → automatically falls back to the OCR channel (verified to fully read the screen and operate)
Windows may prevent background processes from stealing focus → focus_target will warn; manually click the target window once if needed
OCR channel takes 1~6s per snapshot (sub-second with snapshot cache hits when the screen is static), the main latency source for WebView apps
Currently Windows-only
This server cannot be deployed
Maintenance
Related MCP Connectors
Eyes and hands on real Windows PCs — observe, click, type via Glasswarp API.
Stealth web automation for AI agents. Login, signup, navigate, screenshot.
Stealth web automation for AI agents. Login, signup, navigate, screenshot.
Provides cloud browser automation capabilities using Stagehand and Browserbase, enabling LLMs to i…
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to interact with Windows operating systems through native UI automation, file navigation, application control, and system commands. Provides seamless integration between LLMs and Windows environments for tasks like clicking, typing, launching apps, and capturing desktop state.MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to inspect and automate Windows desktop UI elements by exploring UI trees, checking properties, performing actions like clicking and typing, and generating Python automation scripts.MIT
- AlicenseAqualityAmaintenanceAllows AI clients to see and control Windows 10/11 desktops via MCP, with screenshots, UI Automation, Chrome CDP, keyboard/mouse, and terminal using semantic element targeting.30286MIT
- FlicenseNot gradedqualityCmaintenanceEnables AI agents to control Windows GUI applications like a human using screen capture, OCR, mouse and keyboard input, and window management, with safety levels and memory.-