mcp server
computer-use-fallback-mac
Independently developed app/window-targeted macOS Computer Use MCP with background capture and physical-pointer isolation.
Set up
Runs on your computer. Pick your agent and operating system.
This project does not publish an install method we can turn into a config. Follow the README instead.
README
synced Oct 21, 2026computer-use-fallback-mac
由本仓库独立设计并实现的 macOS Computer Use MCP 组件。它以“应用 + 窗口”为操作边界,通过 Accessibility 语义控制后台窗口,不依赖当前桌面最前端命中,也不移动或抢占实体鼠标。
项目专有源代码、测试、文档和虚拟光标资产均由本仓库贡献者独立开发和维护。完整所有权及依赖边界见 PROVENANCE.md。
核心能力
get_app_state:以 ScreenCaptureKit 为首选、CoreGraphics 为后备,抓取指定应用窗口;遮挡该窗口的其他应用不会进入截图。click、drag、scroll:优先使用AXPress、滚动按钮和控件值语义;坐标始终是目标窗口截图的局部坐标。set_value、type_text、select_text、press_key:只作用于显式目标的 Accessibility 元素;无法验证的后台投递会报错。list_apps、list_windows:发现可寻址应用、窗口 ID 和窗口边界。- 每个 MCP 进程拥有独立的持久 Python worker、状态快照、虚拟光标和 overlay;同一窗口用跨进程锁串行化,不同窗口可并行。
- 成功的点击、滚动、拖动和 down/up 会把真实动作点写入当前 session;点击穿透 live overlay 与下一次
get_app_statePNG 使用同一坐标和反馈阶段。 - 虚拟光标样式
aqua-glass-arrow-v2使用 13×18 逻辑像素的半透明冷白箭头、柔和光晕和低透明浅青尾部内缘;无圆点、无硬环,全部几何与配色均由本仓库维护。 - 兼容旧工具名,但旧鼠标动作必须提供
app/windowId,或先调用get_app_state绑定目标。 - 显示截图、权限、剪贴板、坐标映射和只读 OCR 由独立的最小兼容 worker 提供;它没有输入投递、应用激活、窗口抬升或弹窗点击能力。
安全模型
生产动作路径禁止全局 CGEventPost、CGEventPostToPid、pyautogui 鼠标动作、AppleScript 激活、AXRaise 和焦点抢占。内置 runtime 不会“先投递事件、再报告无法验证”;应用若没有可验证的 AX 后台机制,组件直接返回 unsupported_background_action。
这不是对所有 macOS 应用的无条件承诺。准确边界是:目标控件必须暴露可用的 Accessibility 语义,或目标应用必须能够确认进程定向事件。非 AX 画布等无法验证的控件会明确失败。
使用顺序
- 调用
list_apps,必要时用list_windows取得窗口 ID。 - 调用
get_app_state({app, windowId}),读取窗口截图、元素索引和局部边界。 - 优先按
element_index操作;坐标操作使用该次窗口截图的坐标。 - 窗口内容变化后重新调用
get_app_state。过期索引会返回stale_state。
动作后的文本块包含 cursorFeedback:drawn 表示本次窗口截图是否合成光标,imagePoint 是截图像素坐标,phase 描述按下/释放/稳定阶段。分步 mouse_down 会明确返回 delivery: pending,只有匹配的同 session mouse_up 才完成该手势;首次状态或目标进程/窗口不匹配时不会绘制。
安装与启动
完整安装方法见 MCP_INSTALL.md。本地启动:
npm install
npm start
首次运行会在项目内创建 .venv,并使用 runtime/requirements.txt 的精确版本和 SHA-256 锁执行 --require-hashes 安装。直接依赖源位于 runtime/requirements.in。
验证
npm run test:unit
npm run test:integration
npm run test:live
npm run test:all
默认 npm test 只运行非侵入式 CI 门禁;真实 GUI matrix 必须显式运行 npm run test:live。
已验证的 live matrix:
- Calculator:以
open -n创建并验证独立进程,窗口被覆盖时执行后台按钮点击;已有 Calculator 进程不变。 - TextEdit:独立临时实例被覆盖时设置文本值;不接触用户文档。
- Safari:以
open -n -F创建不恢复历史会话的独立实例,验证并只清理该实例,访问本机临时页面,被覆盖时执行网页按钮操作。 - Microsoft Edge:仅在 Edge 已运行时,live gate 对一个现有后台窗口新增并关闭右侧新标签,核对原标签标题与数量完全恢复;不会启动/激活 Edge、创建窗口、导航地址或结束用户进程。Edge 未运行时该项跳过。
- 双 worker:同时控制两个被覆盖的 AppKit 目标,点击、文本、拖动、滚动、光标状态均无串扰。
- 光标反馈:Calculator 的初始态、点击态、稳态、均匀背景和移位状态均已验证;透明箭头、柔和光晕、浅青尾部内缘和非对称切角在 live overlay 与截图合成路径保持一致。
- Overlay 激活隔离:独立 session overlay 使用 nonactivating
NSPanel和NSApplicationActivationPolicyProhibited;测试按精确 PID 验证它不会成为前台应用。 - 完整焦点生命周期:live/integration gate 在启动任何目标或遮挡层之前开始监听
NSWorkspaceDidActivateApplicationNotification。受保护目标、遮挡层或 overlay 只要曾短暂成为前台即失败;普通键盘输入不能把焦点变化解释为用户操作,只有实体鼠标按下或 Command-Tab 可归因第三方应用切换。 - 测试遮挡层:
CU Blocker Harness是用于证明后台动作不会落到前台桌面的测试窗口,并发用例会创建两个。它不是虚拟鼠标或产品 UI;默认仅 2% 不透明度,使用不可激活面板并由测试自动清理。设置CU_BLOCKER_VISIBLE=1才显示红色诊断外观。
npm run test:live 会创建并清理一次性应用窗口,需本机已授予 Accessibility 和 Screen Recording 权限。权限说明见 PERMISSIONS.md。
主要入口
start-mcp.mjs:stdio MCP 入口。src/mcp-server.mjs:MCP server。src/runtime-worker.mjs:Node 侧持久 worker 客户端。src/compat-worker.mjs:Node 侧最小兼容 worker 客户端。runtime/worker.py:Python JSONL worker。runtime/compat_worker.py、runtime/compat_services/:截图、权限、剪贴板、坐标和只读 OCR。runtime/cu_runtime/:目标解析、窗口截图、AX 状态、动作路由、会话隔离。docs/COMPUTER_USE_OPERATION_GUIDE.md:调用和错误恢复指南。
仓库结构
src/ Node.js MCP 服务与协议映射
runtime/ Python/macOS 原生运行时
tests/ 单元、集成、live 与安装验证
scripts/ 可重复的维护和可视化脚本
docs/ 用户操作文档
knowledge/ 已核验的稳定架构、功能与质量证据
.github/ CI 与依赖更新配置
本地 agent 会话、交接记录、运行时状态、依赖目录、凭据和个人绝对路径不属于仓库发布资产,并由测试与 .gitignore 双重阻止。
贡献与安全
- 贡献流程和必跑门禁见 CONTRIBUTING.md。
- 安全问题请按 SECURITY.md 私下报告,不要在普通 issue 中披露。
- 版本变化见 CHANGELOG.md。
- 行为规范见 CODE_OF_CONDUCT.md。
Hosted CI 只运行确定性测试、干净安装和依赖审计。需要真实 Accessibility/Screen Recording 权限以及实体鼠标与前台应用观测的 live matrix 必须在受控 Mac 上执行。
源代码所有权
本仓库的项目专有源代码、测试、文档和虚拟光标资产均为独立设计与实现。运行时通过 PyObjC 集成公开 macOS API;npm 与 Python 依赖继续遵循各自许可证。详细分类见 PROVENANCE.md。