Open Computer Use — macOS 桌面控制的 MCP Server(代码深度分析)
> 一句话版本:用 Swift 写的 macOS Computer Use 引擎,基于 Accessibility API,暴露为 MCP Server。9 个工具让 AI Agent 截图、点击、输入、滚动、拖拽——完整控制 macOS 桌面。还有个亮点:逆向工程了 OpenAI Codex 的光标运动模型,实现了仿人类鼠标轨迹。
| 项目 | 信息 | ||
|---|---|---|---|
| 来源 | [github.com/iFurySt/open-codex-computer-use](https://github.com/iFurySt/open-codex-computer-use) | ||
| Stars | 36 | Forks 5 | |
| 语言 | Swift | 许可证 | MIT |
| 创建 | 2026-04-17 | 最后推送 | 2026-04-19 |
| 代码量 | ~13,800 行 Swift(核心 Kit ~6,500 行) | ||
| 官网 | [evomap.ai](https://evomap.ai)(同 Evolver 作者 iFurySt) |
架构
┌─────────────────────────────────────┐
│ MCP Client (stdio) │
│ Claude Code / Codex / OpenClaw │
└──────────────┬──────────────────────┘
│ JSON-RPC (stdio)
┌──────────────▼──────────────────────┐
│ StdioMCPServer │
│ JSON-RPC 2.0 解析 + 路由 │
└──────────────┬──────────────────────┘
│
┌──────────────▼──────────────────────┐
│ ComputerUseService │
│ 9 个工具的完整实现 │
│ ├── AccessibilitySnapshot (截图) │
│ ├── InputSimulation (输入模拟) │
│ ├── AppDiscovery (应用发现) │
│ └── CursorMotionModel (光标运动) │
└──────────────┬──────────────────────┘
│
┌──────────────▼──────────────────────┐
│ macOS 系统层 │
│ Accessibility API (AXUIElement) │
│ CGEvent (全局鼠标/键盘模拟) │
│ Screen Recording (截图) │
└─────────────────────────────────────┘
9 个 MCP 工具
工具清单
| 工具 | 功能 | 注解 |
|---|---|---|
| `list_apps` | 列出所有运行中 + 最近 14 天用过的 App | readOnly |
| `get_app_state` | 截图 + Accessibility Tree | readOnly |
| `click` | 点击元素(by index)或坐标 | 按左/右/中键,支持多击 |
| `type_text` | 键盘输入文本 | — |
| `press_key` | 按键/组合键 | xdotool 语法 |
| `scroll` | 滚动(上/下/左/右) | by page |
| `drag` | 拖拽(坐标到坐标) | — |
| `set_value` | 设置 Accessibility 元素值 | AXUIElementSetAttributeValue |
| `perform_secondary_action` | 执行辅助功能动作 | Raise/ShowMenu 等 |
关键设计
1. 双模式点击
click 工具有两种点击方式:
- Element-targeted(优先):通过 Accessibility Tree 的 element_index 点击,先尝试
AXPress→AXConfirm→SetFocus,如果都失败再回退到坐标点击 - Coordinate-based:截图坐标 → 转全局坐标 → CGEvent 点击
2. 点击优先级算法
// ComputerUseService.click() 中的 fallback 链
1. AXUIElementPerformAction(kAXPressAction) // Accessibility 原生点击
2. AXUIElementSetAttributeValue(kAXFocused) // Focus
3. AXUIElementPerformAction(kAXConfirmAction) // 确认
4. InputSimulation.clickGlobally(at: point) // 全局 CGEvent 回退
3. 每次操作后自动刷新快照
每个工具调用后都 refreshSnapshot(),返回新的截图 + Accessibility Tree,让 Agent 看到操作结果。
核心模块深度分析
AccessibilitySnapshot(931 行)
最复杂的模块。负责:
截图:用 CGWindowListCreateImage 截取目标 App 窗口,返回 PNG data。
Accessibility Tree 遍历:递归遍历 AXUIElement 树,为每个元素记录:
- index(序号)
- identifier(持久 ID)
- localFrame(相对于窗口的坐标)
- rawActions(可用的 Accessibility 动作)
- prettyActions(人类可读的动作名)
Snapshot 模式:
.accessibility:真实 macOS Accessibility API.fixture:测试夹具模式(用于自动化测试)
输出格式:
App=com.apple.Safari (pid 1234)
Window: "Google", App: Safari.
[0] AXButton "Search" (0, 0, 100, 30) [Press, Focus]
[1] AXTextField "Search or enter website" (0, 0, 200, 30) [Focus, Set Value]
[2] AXStaticText "Google" (0, 0, 300, 20)
...
InputSimulation(260 行)
全局鼠标/键盘模拟,当 Accessibility API 不够用时回退:
clickGlobally(at:button:clickCount:)— CGEvent 鼠标点击scrollGlobally(at:direction:pages:)— CGEvent 滚轮滚动dragGlobally(from:to:)— CGEvent 鼠标拖拽typeText(_:pid:)— 通过 CGEvent 或 AXUIElement 输入文本pressKey(_:pid:)— CGEvent 键盘事件
prepareAppForGlobalPointerInput:在全局点击前,先通过 Accessibility API 把 App 置前(AXRaise),确保窗口在最前面。
CursorMotionModel(1,497 行)🔥
最大亮点。逆向工程了 OpenAI Codex 的光标运动模型。
做了什么:
- 分析 Codex 的
cursor_motion.py(Python 实现) - 重建了光标运动的 20 候选路径池 + 评分模型 + 弹簧时间线
- 用贝塞尔曲线 + 弧度控制生成仿人类鼠标轨迹
轨迹生成:
起点 → [弧线偏移] → [贝塞尔曲线控制点] → 终点
↕
曲线方向 + 曲线幅度
curveDirection:基于移动方向自动选择左偏/右偏curveScale:控制弯曲程度(距离 × 0.22,上限 110px)- 20 候选路径评分选择最自然的轨迹
为什么重要:直线的鼠标移动看起来不自然。仿人类轨迹对某些 App(如绘图工具)可能影响识别。Codex 花了大量工程在这上面,Open Computer Use 直接复刻了。
SoftwareCursorOverlay(966 行)
视觉光标覆盖层:
- 在目标窗口上叠加一个半透明光标
moveCursor:移动到目标位置(带动画)pulseClick:点击时显示脉冲效果settle:光标落下
环境变量 OPEN_COMPUTER_USE_VISUAL_CURSOR 控制开关(默认开启)。
AppDiscovery(440 行)
应用发现:
- 扫描所有运行中的 App(
NSWorkspace.shared.runningApplications) - 追踪最近 14 天的使用频率
- 按名称或 bundle ID 解析 App
- 输出人类可读的 App 列表
Permissions(323 行)
权限管理:
- macOS Accessibility 权限检测和引导
- Screen Recording 权限检测和引导
- 权限状态缓存
FixtureBridge(139 行)
测试桥接:将 Accessibility 操作转发到 fixture 进程,用于自动化测试。
MCP Server 实现
StdioMCPServer 是一个纯 JSON-RPC 2.0 的 stdio MCP Server:
// 协议版本
protocolVersion: "2025-03-26"
serverInfo: { name: "open-computer-use", version: "..." }
// 支持的方法
"initialize" → 返回工具列表 + instructions
"tools/list" → 9 个工具定义
"tools/call" → 路由到 ComputerUseService
"ping" → pong
系统提示词(嵌入 MCP instructions):
- 每次交互前必须先调
get_app_state - 优先使用 element_index 而非坐标点击
- 不要用 AppleScript,优先 Computer Use 工具
- 破坏性操作前要问用户
- 不要覆盖用户的剪贴板
与 OpenAI Codex Computer Use 的对比
| 维度 | Open Computer Use | OpenAI Codex |
|---|---|---|
| 开源 | ✅ MIT | ❌ 闭源 |
| 平台 | macOS only | macOS only |
| API | MCP (JSON-RPC stdio) | Codex 专有插件 |
| 光标运动 | ✅ 逆向工程 Codex 模型 | 原始实现 |
| 安装 | `npm i -g open-computer-use` | 内置在 Codex |
| 截图 | CGWindowListCreateImage | 类似 |
| 输入模拟 | AXUIElement + CGEvent | 类似 |
| 测试 | ✅ Fixture 模式 + Smoke Suite | ❌ |
| 软件光标 | ✅ 可视化覆盖层 | ✅ 类似 |
分析
代码质量:
- 架构清晰:ComputerUseService → 具体操作,MCPServer → JSON-RPC 路由,职责分离
- 错误处理完善:每个 Accessibility API 调用都有 fallback
- 测试友好:Fixture 模式让测试不依赖真实 UI
- Swift + Swift Package Manager:标准的 macOS 开发方式
最大亮点:
1. 逆向工程光标运动模型(1,497 行)——这是最有技术含量的部分
2. 完整的 MCP 集成——任何 MCP 客户端直接用
3. 双模式点击(Accessibility 优先 → CGEvent 回退)——健壮性
局限性:
- macOS only——没有 Linux/Windows 支持
- 36 stars——早期项目,社区小
- 没有历史会话管理——每次交互是独立的
- 权限要求高——Accessibility + Screen Recording + 输入模拟
与 Jay 的关联:
- Jay 的 Mac M3 Air 24GB 可以直接运行
- 通过 MCP 接入 OpenClaw,理论上能让 Agent 控制桌面
- 安全风险:Agent 能点击任何东西——需要权限控制
- 作者 iFurySt 也是 Evolver 的作者,说明他在构建 Agent 基础设施生态
评分
| 维度 | 评分 (1-10) | 说明 |
|---|---|---|
| 代码质量 | 9 | 架构清晰,错误处理完善,有测试 |
| 创新性 | 8 | 逆向 Codex 光标模型 + MCP 集成 |
| 实用性 | 7 | macOS 直接可用,但平台限制 |
| 成熟度 | 5 | 2 天前创建,36 stars |
| 与 Jay 的关联 | 8 | Mac M3 Air 直接用,MCP 接 OpenClaw |
| **总分** | **7.4** | Codex Computer Use 的最佳开源替代 |