opencode-gui-bridge
Enables AI assistants to control Windows GUI by listing and focusing windows, capturing element snapshots via UIA/OCR/CDP, performing clicks/inputs/scrolls, verifying changes, waiting for screen updates, taking screenshots, and obtaining visual descriptions.
README
opencode-gui-bridge
让 opencode(或任何 MCP 客户端)获得电脑使用能力:能看(理解屏幕状态)、能操作(点击/输入/滚动)、能验证(确认操作生效)。
基于 PySide6 + Win32 API + Windows UI Automation + 本地 OCR 实现,零系统级依赖。基础操作全部本地运行,无网络需求(仅视觉 describe 可选配网络 API)。
快速开始
- 解压项目到任意目录(示例
D:\gui-bridge\),双击setup.bat,等它显示Done. - 在你的 opencode 工作目录放一个
opencode.json(内容见「接入 opencode」),把两处路径改成第 1 步的实际路径 - 重启 opencode
- 用 AI 对话框直接说:
- 「列出电脑上的窗口」→ 得到
list_targets结果 - 「打开记事本,在里面输入你好」→ 会自动执行 打开→绑定→快照→点击→输入→验证
- 「列出电脑上的窗口」→ 得到
安装
.\setup.bat
脚本一次性完成:创建 venv 虚拟环境(已存在则跳过)→ pip 安装依赖 → 跑冒烟测试。看到 Done. 即安装成功;失败时它会退出并打印原因。
手动装也是一样的效果:
python -m venv venv
venv\Scripts\python -m pip install -e .
venv\Scripts\python tests\smoke_test.py
要求:Windows 10/11 + Python 3.10+(安装时勾选 Add python.exe to PATH)。
接入 opencode
opencode.json 放在你运行 opencode 的工作目录下(不放在项目里):
{
"$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}"
}
}
}
}
两步改动:
- 把两个
D:\\gui-bridge\\...换成你的实际路径(\在 JSON 里要写成\\) SILICONFLOW_API_KEY那行:本地 OCR 与点击输入不需要任何 key,只有你打算用视觉 describe 才需要配置(见下一节)。没 key 就删掉这行。
验证接入成功:重启 opencode 后,跟 AI 说一句「列出电脑上的窗口」;若 AI 能返回窗口列表,说明 python.exe 与 server.py 路径配置正确。
视觉通道配置(describe 用,可选)
list_targets 返回的 channels.vision 会标明状态:ready(有 key)或 no-key(没有)。走 OpenAI 兼容 API,任意厂商:
| 环境变量 | 作用 | 默认 |
|---|---|---|
VISION_BASE_URL |
API 地址(OpenAI/DeepSeek/通义/智谱 等任一家) | https://api.siliconflow.cn/v1 |
VISION_API_KEY |
视觉 key(留空则回退 SILICONFLOW_API_KEY) |
— |
VISION_MODEL |
视觉理解模型 | Qwen/Qwen3-VL-32B-Instruct |
VISION_OCR_MODEL |
视觉 OCR 模型(describe 的 OCR 兜底) | deepseek-ai/DeepSeek-OCR |
三种设置方式,任选其一:
a) opencode.json 内嵌(跟随配置,最推荐)
"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} 表示读取你本机已有的同名环境变量。
b) 系统级持久化(对所有终端生效):
setx VISION_API_KEY "sk-xxxx"
setx VISION_BASE_URL "https://api.siliconflow.cn/v1"
设完要重开终端 和重开 opencode 才生效。
c) 只在该次终端会话生效:
$env:VISION_API_KEY = "sk-xxxx"
CDP 通道配置(WebView2 / Tauri / Electron)
Tauri、WebView2、Electron 等 Web 内核应用,UIA 只能看到外层壳,读不到 DOM。开启 CDP 调试端口后,快照会自动走 CDP 通道(元素 id 前缀 d:),读取全文是毫秒级。
按应用类型开启调试端口:
| 应用类型 | 方法 |
|---|---|
| Chrome/Edge 浏览器 | 启动加参数:chrome --remote-debugging-port=9222 --remote-allow-origins=* |
| WebView2(WPF/WinForms/Tauri 内嵌) | 先设环境变量再启动应用:$env:WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS = "--remote-debugging-port=9222 --remote-allow-origins=*",然后启动应用 |
| Electron 应用 | 启动加参数:your-app.exe --remote-debugging-port=9222 |
$env:WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS = "--remote-debugging-port=9222 --remote-allow-origins=*"
Start-Process 目标应用
启动后用 list_targets 确认:返回的 channels.cdp 会显示端口号(如 9222)。之后 snapshot 自动走 CDP,act 自动路由 DOM 操作:
- 读页面全文:DOM innerText,<10ms(OCR 要 1~6s)
- 点击:原生 DOM click(绕过物理 hit-test 覆盖层)
- 输入:Input.insertText 真实输入管线(兼容 Quill 等编辑器)
- 元素坐标:CSS×DPR+窗口位置近似(操作不依赖坐标)
没开启也不影响使用:这类应用会自动降级走本地 OCR 通道,照样能读屏和操作。
工具箱:7 个 MCP 工具
| 工具 | 参数 | 作用 | 典型返回 |
|---|---|---|---|
list_targets() |
无 | 枚举可用窗口 + 4 个通道状态 | {windows:[{handle,title,x,y,width,height,uia}], channels:{uia,ocr,cdp,vision}} |
focus_target(handle=?, title=?) |
句柄或标题(子串匹配) | 绑定目标窗口 | {handle, title, cdp_port, focused, note} |
snapshot(max_items=80, prefer="auto") |
prefer 可选 auto/cdp/uia/ocr |
界面快照,给出一批带稳定 id 的元素 | 多行文本,如 [ocr] 元素 15 个 + o:3 text (y坐标...) 文本 |
act(action, target_id=?, text=?, keys=?, x=?, y=?, delta=?, verify=true) |
动作与目标 | 点击/输入/按键/滚动/回车,含验证 | {ok, verify, detail} |
wait_change(x=?,y=?,w=?,h=?, text="", timeout=15) |
区域或文字 | 等待界面变化 / 某文字出现 | {changed, detail} |
screenshot(name="shot", x=?,y=?,w=?,h=?) |
区域可省略(默认目标窗口) | 保存截图到 screenshots/ |
保存路径 |
describe(region="") |
截图文件路径,省略=目标窗口 | 视觉模型描述画面(需视觉 key) | 自然语言描述 |
规则:snapshot/act 需要在 focus_target 之后调用。
act 动作详解
| action | 参数 | 说明 |
|---|---|---|
click |
target_id |
点击元素,自动按 id 前缀选择通道 |
input |
target_id, text |
聚焦该元素并输入文本,之后自动 OCR 验证文本是否出现 |
press |
keys |
组合键,["ctrl","a"]、["enter"]、["esc"] |
enter |
无 | 等效 press(["enter"]) |
scroll |
delta(±) (可选 x,y) |
滚动;给坐标则滚到该点 |
返回结构 {ok, verify, detail}:
ok: 动作是否执行verify: 执行后自动验证的结果changed/matched:界面确实变了 / 输入内容已确认出现no_change/no_match:没检测到预期变化(可能动作没生效,建议重新 snapshot 看最新状态)cdp_insert/skipped:走了 CDP 输入或指定关闭验证failed:执行失败,detail会带原因,点击类失败会自动物理重试并附诊断截图路径
detail: 人类可读的结果说明,可能附诊断截图: <路径>
架构
┌─ 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:每次工具调用的耗时/通道/结果)。
核心设计
- AI 只按元素 id 操作,不用坐标。快照给 id,act 自动把 id 路由到最优通道。
- 通道自动降级:CDP → UIA → OCR → 视觉;点击: InvokePattern → PostMessage → 物理。
- 验证闭环内置:act 返回 verify=changed/no_match/failed + 原因。
- 遮挡安全捕获:OCR 与验证用 PrintWindow 直取目标窗口真实内容,目标被其他窗口盖住也不串内容。
元素 id 规则
| 前缀 | 来源 | 示例 | 稳定性 |
|---|---|---|---|
d: |
CDP DOM | d:0/3/7 |
结构不变则稳定 |
u: |
UIA | u:0/1/3 (从窗口根的子索引链) |
结构不变则稳定 |
o: |
OCR | o:0 (按 y 排序索引) |
每次界面变化后需重取快照 |
o: 和界面变化后失效的 u:,点击前请先重新 snapshot 拿新 id。
测试
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 会话
已知限制
- WebView2/Tauri 双层壳 DOM 不暴露给 UIA → 自动走 OCR 通道(实测可完整读屏与操作)
- Windows 可能禁止后台进程抢焦点 → focus_target 会提示,必要时手动点一次目标窗口
- OCR 通道每快照 1~6s(画面静止时快照缓存命中可到亚秒级),是 WebView 应用的主要延迟来源
- 当前仅支持 Windows
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。