macOS桌面自动化控制工具

一款用于原生macOS桌面自动化的服务,支持屏幕、鼠标、键盘、窗口管理及移动设备模拟器控制,可在后台或前台运行。

  • by d-wwei
  • JavaScript
  • 本地部署
  • 4 星标
  • 更新于
在 GitHub 查看 d-wwei/macos-desktop-control

使用说明

macos桌面控制

中文文档

用于本地macOS桌面自动化的MCP服务器——屏幕、鼠标、键盘、窗口管理和移动模拟器。

没有Docker。无虚拟显示。控制您的实际Mac桌面。人工智能在后台或前台运行——你可以选择。

v3.1中的新增功能

智能截图压缩 -屏幕截图现在默认压缩,以防止高DPI显示器(Retina,4K)上出现API“输入过长”错误。

预设 最大宽度 质量 格式 标准尺寸
none 原始 100 PNG 4-15MB
low 2048像素 85 JPEG 300-500 KB
medium 1280像素 70 JPEG 100-400 KB
high 800像素 50 JPEG 30-150KB

默认值为 medium.Agent根据任务选择级别,或使用 none 像素完美工作。

平铺模式 -当需要全分辨率时,将屏幕截图拆分为网格。代理每次获取一个瓦片,每个瓦片足够小,可以用于API。

新工具: screenshot_tile --从平铺的屏幕截图中获取单个平铺。

压缩也适用于 sim_screenshot 和 emu_screenshot.

v3.0

两种操作模式。30个工具(从13个增加)。可选的iOS/Android模拟器控件。

模式 工作原理 用户体验
前景 cliclick+AppleScript(与v2相同) 您观看AI操作您的屏幕
背景 CGEvent API 通过 CGEventPostToPid AI在目标窗口中工作——你的焦点保持不变

添加 target: { app: "Safari" } 任何支持的工具。坐标变为相对于窗口的坐标。AI永远不会偷走你的前景。

快速开始

# 1. Install cliclick
brew install cliclick

# 2. Clone and install
git clone https://github.com/d-wwei/macos-desktop-control.git
cd macos-desktop-control
npm install

# 3. Add to your MCP client (example: Claude Code)
claude mcp add macos-desktop-control -- node /path/to/macos-desktop-control/src/index.js

授予 无障碍权限 到您的终端:系统设置→ 隐私和安全→ 无障碍。

特性

前景模式(默认)

所有原始v2功能不变。

  • 屏幕捕获 --全屏、区域或特定显示;具有压缩预设和平铺模式
  • 老鼠 --使用修改键单击(左/右/双/三)、移动、拖动、滚动
  • 键盘 --三种打字模式(按键、点击、直接绕过输入法),通过AppleScript键码进行任何组合键
  • 窗口管理 --列出窗口,按应用程序/标题聚焦,打开应用程序
  • 系统 --运行macOS快捷方式工作流
  • 焦点保护 — app 参数在每次操作前自动重新聚焦目标

背景模式(target 参数)

添加 target: { app: "AppName", title?: "WindowTitle" } 在不转移注意力的情况下进行操作。

工具 背景行为
screenshot 通过以下方式捕获目标窗口 screencapture -l<windowId>
click 将CGEvent鼠标事件直接发送到目标PID
type_text 通过CGEvent Cmd+V将文本粘贴到目标PID(保存/恢复剪贴板)
key_press 将CGEvent键盘事件发送到目标PID
scroll 将CGEvent滚轮事件发送到目标PID
drag 闪光技术:短暂激活目标→ 拖拽→ 恢复您的前台应用程序
open_app 通过发布 open -g (背景,无焦点窃取)
list_windows 返回每个窗口的CGWindowID+PID(内部用于定位)

当 target 设置,x/y坐标为 窗口相对 --(0,0)是目标窗口的左上角。服务器在内部转换为屏幕绝对坐标。

iOS模拟器(需要Xcode)

工具在以下情况下自动注册 xcrun simctl 被检测到。

工具 功能
sim_list_devices 列出模拟器及其状态
sim_boot / sim_shutdown 启动或停止模拟器
sim_screenshot 以本机设备分辨率捕获
sim_tap 点击iOS空间坐标(自动映射到模拟器窗口)
sim_swipe 带有持续时间控制的滑动手势
sim_type 在模拟器中键入文本
sim_open_url 在模拟器上打开URL
sim_install_app 安装.app捆绑包

Android模拟器(需要adb)

工具在以下情况下自动注册 adb 被检测到。所有操作都是完全后台的——adb从不窃取焦点。

工具 功能
emu_list_devices 列出连接的设备/模拟器
emu_screenshot 通过捕获 adb exec-out screencap
emu_tap 点击设备坐标
emu_swipe 使用持续时间控制滑动
emu_type 键入文本
emu_key 发送按键事件(主页、后退、回车等)
emu_open_url 通过意图打开URL
emu_install_app 安装APK

用法示例

特定应用程序的背景截图

{ "target": { "app": "Safari" } }

捕获Safari的窗口,即使它位于其他窗口后面。你的前景保持不变。

窗口中的背景单击

{ "x": 100, "y": 200, "target": { "app": "Safari", "title": "GitHub" } }

点击Safari浏览器中标题为“GitHub”的窗口的位置(100200)。没有焦点变化。

背景文本输入

{ "text": "hello world", "target": { "app": "Notes" } }

通过剪贴板粘贴(CGEvent Cmd+V)键入Notes。剪贴板已保存并恢复。

压缩屏幕截图(v3.1中的默认行为)

{ "target": { "app": "Chrome" } }

返回1280px宽的JPEG(~150KB),而不是原始PNG(~5MB)。开箱即用。

无压缩的高分辨率屏幕截图

{ "target": { "app": "Chrome" }, "compression": "none" }

返回原始PNG——与v3.0行为相同。

自定义压缩

{ "target": { "app": "Chrome" }, "compression": "low", "maxWidth": 1920, "quality": 90 }

明确的 maxWidth/quality/format 覆盖预设值。

用于全分辨率检查的平铺模式

{ "target": { "app": "Chrome" }, "tile": { "rows": 2, "cols": 2 } }

返回包含磁贴元数据的清单。然后获取单个图块:

{ "id": "tiles-1711929600000-abc123", "index": 0, "compression": "medium" }

聚焦安全前台操作

{ "text": "hello", "app": "TextEdit", "mode": "direct" }

直接通过AppleScript写入文本——完全绕过输入法。

先决条件

  • macOS(在Sequoia 15.x和Tahoe 26.x上测试)
  • Node.js 18+
  • 点击: brew install cliclick
  • 无障碍权限 适用于您的终端应用程序
  • 可选:Xcode(用于iOS模拟器工具)
  • 可选:带adb的Android SDK(用于Android模拟器工具)

客户端配置

用途 stdio传输所有MCP客户端的配置都是相同的。

Claude Code
# Project scope
claude mcp add macos-desktop-control -- node /path/to/macos-desktop-control/src/index.js

# Global scope
claude mcp add macos-desktop-control -s user -- node /path/to/macos-desktop-control/src/index.js
Claude Desktop

~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "macos-desktop-control": {
      "command": "node",
      "args": ["/path/to/macos-desktop-control/src/index.js"]
    }
  }
}
OpenAI Codex CLI

.codex/mcp.json:

{
  "mcpServers": {
    "macos-desktop-control": {
      "command": "node",
      "args": ["/path/to/macos-desktop-control/src/index.js"]
    }
  }
}
Gemini CLI

~/.gemini/settings.json:

{
  "mcpServers": {
    "macos-desktop-control": {
      "command": "node",
      "args": ["/path/to/macos-desktop-control/src/index.js"]
    }
  }
}
Cursor

.cursor/mcp.json:

{
  "mcpServers": {
    "macos-desktop-control": {
      "command": "node",
      "args": ["/path/to/macos-desktop-control/src/index.js"]
    }
  }
}
VS Code (GitHub Copilot)

.vscode/mcp.json:

{
  "servers": {
    "macos-desktop-control": {
      "command": "node",
      "args": ["/path/to/macos-desktop-control/src/index.js"]
    }
  }
}

建筑

                          ┌─────────────────────────────────┐
                          │   MCP Server (stdio transport)  │
                          └──────────┬──────────────────────┘
                                     │
              ┌──────────────────────┼──────────────────────┐
              │                      │                      │
     Foreground Mode          Background Mode        Simulator Mode
              │                      │                      │
   ┌──────────┴──────────┐  ┌───────┴────────┐   ┌────────┴────────┐
   │ cliclick (mouse)    │  │ CGEvent API    │   │ xcrun simctl    │
   │ osascript (keyboard)│  │ via JXA bridge │   │ (iOS)           │
   │ screencapture       │  │ CGEventPost-   │   │                 │
   │ shortcuts CLI       │  │   ToPid(pid)   │   │ adb             │
   └─────────────────────┘  │ screencapture  │   │ (Android)       │
                             │   -l<windowId> │   └─────────────────┘
                             └────────────────┘

后台模式内部:

  1. CGWindowListCopyWindowInfo 通过JXA枚举具有CGWindowID、PID和边界的窗口
  2. 使用边界将窗口相对坐标转换为屏幕绝对坐标
  3. CGEventPostToPid 将鼠标/键盘/滚动事件直接发送到目标进程
  4. screencapture -l<windowId> 无需聚焦即可捕获特定窗口

与替代方案相比

解决方案 平台 后台模式 模拟器支持 真实桌面
这个项目 macOS 是(CGEvent) iOS+安卓 是
人类计算机使用 Linux 否 否 无(虚拟)
MCPControl Windows 否 否 是
剧作家MCP 跨平台 部分 否 仅限浏览器
PyAutoGUI MCP服务器 跨平台 否 否 是

为什么选择macOS原生

  • 后台操作 -CGEvent API在不接触焦点的情况下将事件发布到目标PID。PyAutoGUI和clicliclick都要求窗口为前台。
  • 重点防窃 — app 参数+ ensureAppFocus() 处理所有MCP客户端共享的审批对话框问题。
  • IME旁路 — direct 模式通过AppleScript写入文本,完全跳过输入法。PyAutoGUI typewrite 仅处理ASCII。
  • 模拟器集成 --iOS和Android模拟器通过相同的MCP接口进行控制。不需要单独的工具。
  • 轻量级 --cliclick(一个brew包)+内置macOS工具。没有Python运行时,没有ONNX,没有严重的依赖关系。

何时选择跨平台解决方案

  • 您需要Windows或Linux支持
  • 您需要基于OCR的元素检测
  • 后台操作不是工作流的要求

更新管理

该项目整合 更新工具包 用于策略控制、验证和回滚的更新编排。

检查更新:

npx update-kit check --cwd /path/to/macos-desktop-control --json

应用更新(git pull+语法验证):

npx update-kit apply --cwd /path/to/macos-desktop-control

出现问题时回滚:

npx update-kit rollback --cwd /path/to/macos-desktop-control

配置存在于 update.config.json。状态和审计日志存储在 .update-kit/ (忽略了)。

许可证

麻省理工学院