关于 baepsae
baepsae 是一个本地运行的 MCP 服务,用于自动化 iOS 模拟器和 macOS 应用。它由 TypeScript MCP 层与 Swift 原生桥接二进制组成,面向需要通过 Agent 操作模拟器或桌面应用界面的开发者。
主要功能
- 01UI 检查与查询(analyze_ui、query_ui)
- 02点击、输入、滑动等交互工具
- 03基于语义优先的 tap_tab 标签页切换
- 04模拟器截图与录屏
- 05macOS 应用窗口、菜单与剪贴板操作
- 06通过 run_steps 执行多步工作流
适用场景
- 01让编码 Agent 在模拟器中验证应用界面
- 02自动化 iOS 应用的登录或导航流程
- 03对 macOS 应用执行界面操作与截图
MCP 相关
该项目是 MCP 服务,向 MCP 客户端暴露约 43 个统一的通用工具,包括 UI、输入、系统与模拟器相关工具,目标通过 udid 或 bundleId / appName 指定。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
47收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| subcommand | enum | 否 | 用于查看兼容性参考的旧版子命令名称(可选)describe-ui | search-ui | list-simulators | list-apps | doctor | tap | tap-tab | type | swipe | button | key | key-sequence | key-combo | touch | gesture | stream-video | record-video | screenshot | list-windows | activate-app | screenshot-app | right-click | scroll | drag-drop | menu-action | get-focused-app | clipboard |
详细介绍
mcp-baepsae
Baepsae(棕头鸦雀)—— 一种韩国小鸟。圆滚滚、胖乎乎的,总是蹦来蹦去叽叽喳喳。以坚韧著称 —— 即使一只小鸟试图跟上鹳的步伐,它也从不放弃。这个项目也很小,但它会不知疲倦地啄击你的模拟器。
用于 iOS Simulator 和 macOS 应用自动化的本地 MCP 服务,带有 TypeScript MCP 层和 Swift 原生桥接。
한국어 문서는 README-KR.md를 참고하세요.
目录
前置条件
- macOS 14+
- Xcode + iOS Simulator
- Node.js 18+
- Swift 6+
平台支持
| 平台 | 支持 | 说明 |
|---|---|---|
| macOS | 是 | 主要平台。iOS Simulator 和辅助功能 API 所必需。 |
| Linux | 否 | 原生二进制依赖 AppKit、CoreGraphics 和辅助功能框架。 |
| Windows | 否 | 原生二进制依赖 AppKit、CoreGraphics 和辅助功能框架。 |
为什么仅支持 macOS?
Swift 原生桥接(baepsae-native)使用 macOS 专属框架(AppKit、CoreGraphics、辅助功能)来与 iOS Simulator 和 macOS 应用交互。这些框架在 Linux 或 Windows 上不可用。TypeScript MCP 层还依赖 xcrun simctl,它属于 Xcode Command Line Tools 的一部分,仅在 macOS 上可用。
要求摘要:
- macOS 14 或更高版本 —— iOS Simulator 自动化和辅助功能 API 访问所必需。
- Xcode 或 Xcode Command Line Tools —— 原生二进制的 Swift 6+ 编译和
xcrun simctl命令所必需。 - Node.js >= 18.0.0 —— 运行 TypeScript MCP 服务所必需。
权限
UI 检查和输入自动化功能需要辅助功能权限(使用统一的通用工具,如 analyze_ui、tap、right_click)。
重要的一点是,权限通常需要授予自动化宿主 / 运行时进程,而不是你正在自动化的目标应用。
哪个进程通常需要权限?
- 直接调用原生二进制
- 示例:
baepsae-native ... - 最相关的条目:
baepsae-native二进制本身,以及启动它的终端/Shell 应用
- 示例:
- Node / npx MCP 运行时
- 示例:
node dist/index.js、npx -y mcp-baepsae@latest - 最相关的条目:运行时进程(
node),以及启动它的终端或 MCP 客户端应用
- 示例:
- 桌面 / 命令行 MCP 客户端
- 示例:Claude Code、Codex CLI/Desktop、Gemini CLI
- 相关条目可能包括 MCP 客户端应用、终端宿主和运行时进程,具体取决于启动路径
推荐的设置流程
- 打开 系统设置 > 隐私与安全性 > 辅助功能。
- 启用你实际使用的终端或 MCP 客户端应用。
- 如果列出了运行时进程(
node、bun等),请启用它。 - 对于直接调用原生二进制的情况,如果
baepsae-native二进制条目单独出现,也请启用它。 - 如果缺少某个条目,请点击
+手动添加。
重要说明
授予权限后,可能需要重启启动进程,macOS 才会应用更改。
如果错误仍然存在,请退出并重新启动启动 mcp-baepsae 的终端、MCP 客户端或运行时进程。
对于模拟器目标,基于选择器的操作(使用 id 或 label 的 tap / right_click)默认搜索应用内内容。设置 all: true 可包含 Simulator 外壳 UI。
安装
方案 A)npm(最简单)
# Run directly without installing
npx mcp-baepsae@latest
# Or install globally
npm install -g mcp-baepsae
在 macOS 上,Swift 原生二进制文件会在安装过程中自动构建。如果 Swift 不可用,服务仍可使用基于 simctl 的功能。
如果你打算立即使用 UI 检查或输入自动化,请向你实际用于启动服务的终端 / MCP 客户端 / 运行时进程授予辅助功能权限。
方案 B)从源码构建
git clone https://github.com/oozoofrog/mcp-baepsae.git
cd mcp-baepsae
npm install
npm run build
MCP 配置(推荐)
使用安装脚本,它会直接调用每个客户端的 MCP 安装流程。
bash scripts/install.sh --tool all
客户端对照表
| 客户端 | 安装路径 | 脚本目标 | 说明 |
|---|---|---|---|
| Claude Code | claude mcp add | --tool claude-code | 通过 --claude-scope 支持多作用域 |
| Claude Desktop | claude mcp add --scope user | --tool claude-desktop | 用户级注册 |
| Codex CLI | codex mcp add | --tool codex-cli | 也适用于 Codex Desktop 设置 |
| Codex Desktop | Codex CLI MCP 配置 | --tool codex-desktop | 使用与 CLI 相同的 MCP 注册表 |
| OpenCode | 全局配置(~/.config/opencode/opencode.json) | --tool opencode | 由安装脚本自动更新 |
| Gemini | gemini mcp add | --tool gemini | 用户作用域设置 |
| Google Antigravity | 兼容 Gemini 的 MCP 流程 | --tool antigravity | 使用 Gemini MCP 命令路径 |
| GitHub Copilot | copilot 或 gh copilot 会话 | --tool copilot | 基于交互式会话的设置 |
面向大模型
如果你是一个正在配置此 MCP 服务的 LLM Agent,以下是你需要的一切:
在尝试 UI 自动化工具之前,请记住辅助功能权限通常属于宿主/运行时进程(
node、终端、MCP 客户端),而不是被自动化的目标应用。
快速开始(一条命令)
# Register baepsae as an MCP server for all supported clients
bash scripts/install.sh --tool all
如果你通过 npm 安装而非克隆仓库,请使用 npx:
# Claude Code
claude mcp add baepsae -- npx -y mcp-baepsae@latest
# Codex CLI
codex mcp add baepsae -- npx -y mcp-baepsae@latest
自动化标志
# Preview commands without executing
bash scripts/install.sh --tool all --dry-run
# Verify environment and dependencies
bash scripts/install.sh --tool all --doctor
# Unregister from all clients
bash scripts/install.sh --tool all --uninstall
运行时选项
安装脚本通过 --runtime 支持多种运行时:
| 标志 | 命令 | 适用场景 |
|---|---|---|
--runtime node(默认) | node dist/index.js | 本地源码构建 |
--runtime npx | npx -y mcp-baepsae@latest | npm 注册表,无需全局安装 |
--runtime bunx | bunx mcp-baepsae@latest | Bun 用户 |
--runtime global | mcp-baepsae | 在 npm install -g mcp-baepsae 之后 |
手动配置(备用方案)
当你不想运行 scripts/install.sh 时使用此方式。
使用 npx(推荐 npm 用户使用)
# Claude Code
claude mcp add baepsae -- npx -y mcp-baepsae@latest
# Codex CLI
codex mcp add baepsae -- npx -y mcp-baepsae@latest
# Gemini CLI
gemini mcp add --scope user --transport stdio baepsae npx -y mcp-baepsae@latest
使用 npx 时,相关的辅助功能条目通常是生成的 node 运行时以及启动它的终端 / MCP 客户端。
使用本地构建
# Claude Code (project)
claude mcp add --scope project --env="BAEPSAE_NATIVE_PATH=/ABS/PATH/native/.build/release/baepsae-native" baepsae -- node /ABS/PATH/dist/index.js
# Codex CLI
codex mcp add baepsae --env BAEPSAE_NATIVE_PATH=/ABS/PATH/native/.build/release/baepsae-native -- node /ABS/PATH/dist/index.js
# Gemini CLI
gemini mcp add --scope user --transport stdio -e BAEPSAE_NATIVE_PATH=/ABS/PATH/native/.build/release/baepsae-native baepsae node /ABS/PATH/dist/index.js
使用本地构建时,请同时检查运行时(node)和启动它的应用的权限。
如果你直接调用 baepsae-native 进行调试,也请检查原生二进制文件入口本身的权限。
项目结构
- MCP 服务入口点:
src/index.ts - 工具模块:
src/tools/(info、simulator、ui、input、media、system) - 共享工具:
src/utils.ts、src/types.ts - 原生二进制文件入口点:
native/Sources/main.swift - 原生命令处理器:
native/Sources/Commands/ - 原生二进制文件输出:
native/.build/release/baepsae-native - TS 测试:
tests/mcp.contract.test.mjs、tests/unit.test.mjs、tests/mcp.real.test.mjs - Swift 测试:
native/Tests/BaepsaeNativeTests/
命令
npm run build # Build TypeScript + native Swift binary
npm test # Contract/integration tests
npm run test:real # Real simulator smoke test (requires booted simulator)
npm run test:real:preflight # Environment diagnostics only
npm run test:real:sim # iOS simulator phases only (skips Phase 4)
npm run test:real:mac # macOS Safari phase only
npm run verify # test + test:real
npm run setup:mcp # Alias for scripts/install.sh
MCP 工具状态
已端到端实现 43 个工具。
官方公开 MCP 接口:统一通用工具
公开 API 接口有意采用单一方案:使用带目标参数的统一通用工具,而不是 sim_* / mac_* 名称。
| 类别 | 工具 |
|---|---|
| UI | analyze_ui、query_ui、tap、tap_tab、type_text、swipe、scroll、drag_drop、wait_for_ui、detect_dialog、read_ui_value、set_ui_value、read_ui_param、hit_test、enumerate_ui |
| 输入 | key、key_sequence、key_combo、touch、input_source、list_input_sources |
| 工作流 | run_steps |
| 系统 | list_windows、activate_app、screenshot_app、right_click、focus_window、context_menu_action、watch_notification |
| 仅模拟器 | list_simulators、screenshot、record_video、stream_video、open_url、install_app、launch_app、terminate_app、uninstall_app、button、gesture |
| macOS/系统 | list_apps、menu_action、get_focused_app、clipboard |
| 实用工具 | baepsae_help、baepsae_version、doctor |
目标路由在参数中显式指定:模拟器使用 udid,macOS 使用 bundleId / appName。
type_text 策略
type_text 只接受一种输入源:text、stdinText 或 file。
method: "auto"解析为:- 模拟器目标使用
paste - macOS 目标使用
keyboard
- 模拟器目标使用
method: "paste"对模拟器目标使用模拟器粘贴板,对 macOS 目标使用临时替换/恢复宿主机剪贴板的流程。method: "keyboard"始终逐字符输入。
使用 paste 时,模拟器目标会更新模拟器粘贴板而不触碰宿主机剪贴板,而 macOS 目标会临时覆盖宿主机剪贴板并在提交后恢复。成功的响应会报告输入源、目标类型、请求的方法、实际使用的方法、粘贴传输方式,以及所应用的任何自动回退。
tap_tab 策略
tap_tab 采用语义优先、几何兜底。
- 首先尝试标签栏下暴露的可操作后代元素。
- 如果 SwiftUI/模拟器未暴露真实的标签按钮后代元素,则可以使用语义代理行(例如,应用提供的、能清晰映射到相同标签的顶部导航按钮)。
- 只有当两种语义路径都不存在时,才会回退到标签栏几何。
这一点很重要,因为模拟器中的 SwiftUI TabView 可能将标签栏暴露为通用的 AXGroup text="Tab Bar",而不带可操作的子按钮。
用法示例
按索引切换标签,带语义优先回退:
// Prefer this when your app exposes a real tab bar but individual tab buttons
// are not consistently addressable via query_ui/tap selectors.
tap_tab({ udid: "...", index: 1, tabCount: 3 })
统一模拟器应用无障碍快速入门(应用 UI 内部):
// 1) Launch your app in the target simulator
launch_app({ udid: "...", bundleId: "com.example.app" })
// 2) Inspect or search accessibility tree (in-app content scope by default)
analyze_ui({ udid: "..." })
query_ui({ udid: "...", query: "Login" })
// 3) Interact by accessibility identifier/label
tap({ udid: "...", id: "login-button" })
// Optional: include Simulator chrome/system UI in selector lookup
tap({ udid: "...", label: "Home", all: true })
打开 URL(iOS 模拟器):
// Open Naver Mobile
open_url({ udid: "...", url: "https://m.naver.com" })
管理应用(iOS 模拟器):
// Install an app
install_app({ udid: "...", path: "/path/to/App.app" })
// Launch Safari
launch_app({ udid: "...", bundleId: "com.apple.mobilesafari" })
// Terminate Safari
terminate_app({ udid: "...", bundleId: "com.apple.mobilesafari" })
macOS 应用自动化:
// List running macOS apps
list_apps({})
// Take screenshot of a macOS app
screenshot_app({ bundleId: "com.apple.Safari" })
故障排查
辅助功能权限检查清单
-
权限目标通常是自动化宿主/运行时进程,而不是目标应用。
-
先运行
doctor,在一个地方检查宿主进程、父进程、原生二进制文件、已启动的模拟器可用性以及辅助功能就绪状态。 -
检查错误消息中的:
- 当前宿主进程
- 父进程
- 推断的启动模式
-
如果你通过
npx/node启动,请为运行时以及启动它的终端 / MCP 客户端授予权限。 -
如果你直接启动
baepsae-native,请为原生二进制文件入口以及启动它的终端 / shell 应用授予权限。 -
更改权限后,请先重启启动进程再重试。
-
Claude 设置时出现
Invalid environment variable format:- 使用当前脚本(
scripts/install.sh)或claude mcp add --env="KEY=value" ...格式。
- 使用当前脚本(
-
出现
Missing native binary错误:- 运行
npm run build并确认native/.build/release/baepsae-native存在。
- 运行
-
辅助功能权限错误含义不明确:
- 当前版本会在错误文本中包含宿主/父进程诊断信息以及推断的启动模式,以便你查看哪个可执行文件路径可能需要权限。
-
真实冒烟测试诊断:
- 运行
npm run test:real:preflight可打印环境和能力诊断信息,而无需执行完整测试套件。 - 运行
npm run test:real:sim可专注于模拟器能力覆盖,或运行npm run test:real:mac可针对 macOS Safari 子集。
- 运行
-
打开了多个 Simulator 窗口,选择器命中了错误的设备:
- 当前版本会先将模拟器选择器限定到目标
udid窗口。 - 如果你确实需要 Simulator 界面/系统 UI,请使用
all: true。
- 当前版本会先将模拟器选择器限定到目标
-
OpenCode 不显示
baepsae:- 重新运行
bash scripts/install.sh --tool opencode --skip-install --skip-build并检查~/.config/opencode/opencode.json。
- 重新运行
-
Copilot 未自动注册:
- Copilot MCP 流程是交互式/基于会话的。使用
--interactive重新运行安装程序。
- Copilot MCP 流程是交互式/基于会话的。使用
-
真实冒烟测试被跳过:
- 先启动一个 iOS 模拟器,然后运行
npm run test:real。
- 先启动一个 iOS 模拟器,然后运行
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。