Desktop Pilot MCP
Native macOS automation for Claude. 30-100x faster than screenshots.
______________________________________________________________________
Desktop Pilot是一款MCP服务器,通过Accessibility API、AppleScript和CGEvent,Claude可以直接访问任何macOS应用程序——无屏幕截图、无像素坐标、无视觉模型开销。它读取实际的UI树并对语义元素引用进行操作,就像Playwright在浏览器中的工作方式一样。
Telegram的一个快照需要20毫秒,并返回结构化数据。使用基于屏幕截图的计算机进行相同的操作需要大约3秒,并返回像素。
pilot_snapshot { "app": "Telegram" }
[e1] Window "Saved Messages"
[e2] MenuButton "Main menu"
[e3] Button "All chats (111 unread chats)"
[e7] Button "Code (4 unread chats)"
[e18] TextField "Write a message..."
[e20] Button "Record Voice Message"
pilot_click { "ref": "e18" } // focus the text field
pilot_type { "ref": "e18", "text": "Hello from Claude" }
pilot_click { "ref": "e20" } // send没有坐标。没有截图。没有猜测。只是参考。
______________________________________________________________________
快速入门(2分钟)
npx desktop-pilot-mcp步骤1。 添加到您的Claude配置并重新启动Claude:
对于 克劳德代码,添加到 ~/.claude.json 在您的项目下 mcpServers:
{
"desktop-pilot": {
"command": "npx",
"args": ["-y", "desktop-pilot-mcp"]
}
}对于 克劳德桌面,添加到 ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"desktop-pilot": {
"command": "npx",
"args": ["-y", "desktop-pilot-mcp"]
}
}
}步骤2。 macOS提示时授予辅助功能权限(一次性)。
如果未出现提示: 系统设置>隐私和安全>辅助功能 --添加您的终端应用程序或Claude Desktop。
步骤3。 让Claude与任何应用程序进行交互:
“拍摄Telegram的快照,并向我展示屏幕上的内容”
就是这样,没有API密钥,没有帐户,没有配置文件。
Alternative: build from source
需要Swift 6.0+(Xcode 16+附带)。
git clone https://github.com/VersoXBT/desktop-pilot-mcp.git
cd desktop-pilot-mcp
swift build -c release然后直接在Claude配置中使用二进制路径:
{
"desktop-pilot": {
"command": "/absolute/path/to/desktop-pilot-mcp/.build/release/desktop-pilot-mcp",
"args": []
}
}______________________________________________________________________
基准测试
对Telegram、Finder和其他macOS应用程序进行测试的真实测量结果:
| 操作 | 电脑使用(截图) | 桌面试点 | 加速 |
|---|---|---|---|
| 快照(读取完整UI树) | ~3000ms | 20ms | 150倍 |
| 快照(查找器,45个元素) | ~3000ms | 78ms | 38x |
| 点击元素 | ~3000ms | ~50ms | 60倍 |
| 读取元素值 | ~3000ms | \ Save As...", "app": "TextEdit" } |
|参数|类型|必填|说明|
|-----------|------|----------|-------------|
| `path` |string |是|菜单路径 `>` 分离器。 |
| `app` |string |否|应用程序名称或捆绑包ID。最前面省略。 |
______________________________________________________________________
### `pilot_script`
运行针对特定应用程序的AppleScript或JXA(JavaScript for Automation)代码。
{ "app": "Finder", "code": "tell application \"Finder\" to get name of every window", "language": "applescript" }
|参数|类型|必填|说明|
|-----------|------|----------|-------------|
| `app` |string |是|目标应用程序名称。 |
| `code` |string |是|要执行的AppleScript或JXA代码。 |
| `language` |string |否| `applescript` (默认)或 `jxa`. |
______________________________________________________________________
### `pilot_screenshot`
捕获特定元素或全屏的屏幕截图。返回base64 PNG。谨慎使用-- `pilot_snapshot` 通常更便于理解UI状态。
{ "ref": "e1" }
|参数|类型|必填|说明|
|-----------|------|----------|-------------|
| `ref` |string |否|元素引用到屏幕截图。省略全屏显示。 |
______________________________________________________________________
### `pilot_batch`
在单个MCP往返中按顺序执行多个工具调用。用于减少执行多步骤操作时的延迟。
{ "actions": [ { "tool": "pilot_click", "params": { "ref": "e18" } }, { "tool": "pilot_type", "params": { "ref": "e18", "text": "Hello" } }, { "tool": "pilot_click", "params": { "ref": "e20" } } ] }
|参数|类型|必填|说明|
|-----------|------|----------|-------------|
| `actions` |array |是|数组 `{ tool, params }` 对象按顺序执行。 |
______________________________________________________________________
### `pilot_list_apps`
列出所有正在运行的macOS应用程序及其名称、捆绑包ID、PID和窗口计数。用于在拍摄快照之前发现可用的应用程序。
{}
无需参数。
______________________________________________________________________
## 建筑
Sources/ DesktopPilot/ Core/ AppRegistry.swift # App discovery via NSWorkspace ElementStore.swift # Actor-based ref-to-element mapping Router.swift # Smart per-app, per-action routing Snapshot.swift # Batch AX tree traversal Layers/ LayerProtocol.swift # InteractionLayer protocol AccessibilityLayer.swift # AXUIElement tree reading + actions AppleScriptLayer.swift # System Events + sdef scripting CGEventLayer.swift # Raw keyboard/mouse injection ScreenshotLayer.swift # Screen capture fallback MCP/ Server.swift # JSON-RPC 2.0 with Content-Length framing Tools.swift # 10 tool definitions + dispatch Types.swift # PilotElement, AppSnapshot, AppInfo Platform/ PlatformProtocol.swift # Cross-platform bridge interface macOS/ AXBridge.swift # Low-level AXUIElement C API wrapper Permissions.swift # Accessibility permission management SystemEvents.swift # AppleScript/JXA execution helper DesktopPilotCLI/ main.swift # Entry point: permission check + server start Tests/ DesktopPilotTests/ DesktopPilotTests.swift # 22 tests: types, router, registry, MCP, tools
**关键设计决策:**
- **零依赖。** 整个服务器仅基于苹果框架(ApplicationServices、AppKit、CoreGraphics)构建。没有SwiftNIO,没有Vapor,没有第三方JSON库。这使二进制文件保持在427KB。
- **基于角色的元素存储。** 引用是短暂的——它们会在每个快照上重置。这 `ElementStore` actor保证跨并发工具调用对AXUIElement到ref映射的线程安全访问。
- **内容长度框架。** MCP服务器使用标准JSON-RPC 2.0协议 `Content-Length` 通过stdin/stdout构建头帧,与MCP规范完全匹配。
- **批量属性读取。** 快照生成器使用 `AXUIElementCopyMultipleAttributeValues` 在一次调用中读取6个属性。这就是为什么快照很快。
______________________________________________________________________
## 支持的应用程序
Desktop Pilot适用于任何公开可访问性树的macOS应用程序(实际上是所有这些应用程序):
|类别|示例|主层|
|----------|----------|---------------|
|Apple原生|查找器、Safari浏览器、邮件、笔记、日历、音乐|AppleScript+辅助功能|
|生产力|微软Office、谷歌Chrome、火狐|辅助功能|
|电子| VS代码、Discord、Slack、Spotify、信号|可访问性|
|创意| Final Cut Pro、Logic Pro、Xcode | AppleScript+辅助功能|
|通信|电报、iMessage、WhatsApp |可访问性|
|系统|系统设置、活动监视器、终端|可访问性|
______________________________________________________________________
## 用例
- **自动化任何macOS工作流程** --文件管理、应用程序配置、跨应用程序的数据输入
- **构建AI代理** 运行Claude无法通过web API访问的本地桌面应用程序
- **测试macOS应用程序** 通过结构化元素引用而不是脆弱的像素坐标来驱动UI
- **跨应用编排** --从一个应用程序复制数据,处理数据,粘贴到另一个应用中,所有这些都在一个Claude会话中完成
- **可访问性审计** --检查任何应用程序的完整UI树,以验证可访问性合规性
______________________________________________________________________
## 故障排除
**“未授予访问权限”**
打开“系统设置”>“隐私和安全”>“辅助功能”,然后添加二进制文件或您的终端应用程序。授予后重新启动MCP服务器。
**“未能捕获屏幕截图”**
在“系统设置”>“隐私和安全”>“屏幕录制”中授予屏幕录制权限。仅适用于 `pilot_screenshot`.
**陈旧参考文献(`Unknown ref 'e5'`)**
每次重置参考值 `pilot_snapshot` 电话。在与元素交互之前,始终拍摄一张新的快照。如果应用程序的UI自上次快照以来发生了变化,则旧的引用无效。
**Electron应用程序没有响应 `pilot_type`**
一些Electron应用程序(VS Code、Discord)会吞下原始密钥事件。路由器通过使用辅助功能(AXSetValue)而不是用于Electron应用程序的CGEvent来处理此问题。如果键入仍然失败,请尝试 `pilot_script` 通过系统事件按键。
**空快照**
该应用程序可能没有任何打开的窗口,或者可能使用非标准UI框架(游戏、OpenGL/Metal渲染器)。使用 `pilot_screenshot` 作为自定义渲染内容的后备方案。
______________________________________________________________________
## 发展
Build debug
swift build
Build release
swift build -c release
Run tests
swift test
Run the server directly
swift run desktop-pilot-mcp
项目被拆分为一个库目标(`DesktopPilot`)以及可执行目标(`DesktopPilotCLI`)为了可测试性。所有核心逻辑都存在于图书馆中;CLI是一个精简的入口点。
______________________________________________________________________
## 许可证
麻省理工学院
## 贡献者
VersoXBT
💻 📖
Claude
🤖 💡