iOS模拟器和macOS应用自动化服务器

一个本地MCP服务器,用于iOS模拟器和macOS应用的自动化,包含TypeScript MCP层和Swift本地桥接。

  • by oozoofrog
  • JavaScript
  • 本地部署
  • 26 星标
  • 更新于
在 GitHub 查看 oozoofrog/mcp-baepsae

使用说明

mcp-baepsae

Baepsae (文喉鹦鹉)——一种韩国小鸟。圆圆的,胖乎乎的,不停地蹦蹦跳跳地唧唧喳喳。它以坚韧著称——即使小鸟试图跟上鹳,它也从不放弃。这个项目也很小,但它不知疲倦地蚕食着你的模拟器。

用于iOS模拟器和macOS应用程序自动化的本地MCP服务器,具有TypeScript MCP层和Swift本机桥。

韩语文档 README-KR.md请参考。

目录

先决条件

  • macOS 14+
  • Xcode+iOS模拟器
  • Node.js 18+
  • Swift 6+

平台支持

平台 支持 备注
macOS 是 主要平台。iOS模拟器和辅助功能API需要。
Linux 否 本机二进制依赖于AppKit、CoreGraphics和辅助功能框架。
Windows 否 本机二进制依赖于AppKit、CoreGraphics和辅助功能框架。

为什么只有macOS?

Swift原生桥(baepsae-native)使用macOS特定的框架(AppKit、CoreGraphics、Accessibility)与iOS模拟器和macOS应用程序进行交互。这些框架在Linux或Windows上不可用。TypeScript MCP层也依赖于 xcrun simctl,它是Xcode命令行工具的一部分,仅在macOS上可用。

需求概述:

  • macOS 14或更高版本 --iOS模拟器自动化和辅助功能API访问所需。
  • Xcode或Xcode命令行工具 --Swift 6+编译本机二进制文件和 xcrun simctl 命令。
  • Node.js>=18.0.0 --需要运行TypeScript MCP服务器。

权限

需要访问权限 用于UI检查和输入自动化功能(使用统一的通用工具,如 analyze_ui, tap, right_click).

重要的细节是,通常需要授予 自动化主机/运行时进程,而不是您要自动化的目标应用程序。

哪些流程通常需要获得许可?

  • 直接本机二进制调用
    • 例子: baepsae-native ...
    • 最相关的条目: baepsae-native 二进制文件本身,以及启动它的终端/shell应用程序
  • 节点/npx MCP运行时
    • 例子: node dist/index.js, npx -y mcp-baepsae@latest
    • 最相关的条目:运行时进程(node),再加上启动它的终端或MCP客户端应用程序
  • 桌面/CLI MCP客户端
    • 示例:Claude Code、Codex CLI/桌面、Gemini CLI
    • 相关条目可以包括MCP客户端应用程序、终端主机和运行时进程,具体取决于启动路径

推荐的设置流程

  1. 打开 系统设置 > 隐私和安全 > 无障碍.
  2. 启用您实际使用的终端或MCP客户端应用程序。
  3. 启用运行时进程(如果列出)(node, bun等等)。
  4. 对于直接本机调用,还启用 baepsae-native 二进制条目(如果单独出现)。
  5. 如果缺少条目,请单击 + 并手动添加。

重要提示

授予权限后,在macOS应用更改之前,可能需要重新启动启动过程。
如果错误仍然存在,请退出并重新启动已启动的终端、MCP客户端或运行时进程 mcp-baepsae.

对于模拟器目标,基于选择器的操作(tap / right_click 和 id 或 label)搜索 应用内内容 默认情况下。集 all: true 包括模拟器chrome 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 mcp add --tool claude-code 通过以下方式支持多范围 --claude-scope
克劳德桌面 claude mcp add --scope user --tool claude-desktop 用户级注册
Codex CLI codex mcp add --tool codex-cli 也适用于Codex桌面设置
Codex桌面 Codex CLI MCP配置 --tool codex-desktop 使用与CLI相同的MCP注册表
OpenCode 全局配置(~/.config/opencode/opencode.json) --tool opencode 安装程序自动更新
双子座 gemini mcp add --tool gemini 用户范围设置
谷歌反重力 双子座兼容MCP流 --tool antigravity 使用Gemini MCP命令路径
GitHub副本 copilot 或 gh copilot 会议 --tool copilot 交互式/基于会话的设置

法学硕士

如果您是设置此MCP服务器的LLM代理,以下是您需要的一切:

在尝试UI自动化工具之前,请记住辅助功能权限通常属于 主机/运行时进程 (node、终端、MCP客户端),而不是自动化下的目标应用程序。

快速启动(一个命令)

# Register baepsae as an MCP server for all supported clients
bash scripts/install.sh --tool all

如果你通过npm安装而不是克隆repo,请使用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/ (信息、模拟器、用户界面、输入、媒体、系统)
  • 共享公用设施: 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 对于模拟器, bundleId / appName 适用于macOS。

type_text 政策

type_text 只接受一个输入源: text, stdinText,或 file.

  • method: "auto" 决定:
    • paste 用于模拟器目标
    • keyboard 适用于macOS目标
  • method: "paste" 为模拟器目标使用模拟器粘贴板,为macOS目标使用临时主机剪贴板替换/恢复流。
  • method: "keyboard" 始终逐个字符键入。

当 paste 使用时,模拟器目标会在不接触主机剪贴板的情况下更新模拟器剪贴板,而macOS目标会临时覆盖主机剪贴板并在提交后还原。成功的响应报告了输入源、目标类型、请求的方法、使用的方法、粘贴传输以及应用的任何自动回退。

tap_tab 政策

tap_tab 是 语义优先,几何最后.

  • 首先,它尝试在选项卡栏下显示可操作的后代。
  • 如果SwiftUI/Simulator不公开真正的选项卡按钮子体,则可以使用 语义代理行 (例如,该应用程序提供了顶部导航按钮,可以清晰地映射到相同的选项卡)。
  • 只有当两个语义路径都不存在时,它才会回退到标签栏几何图形。

这很重要,因为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应用程序授予权限。

  • 更改权限后,请重新启动启动过程,然后重试。

  • Invalid environment variable format 在Claude设置上:

    • 使用当前脚本(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子集。
  • 多个模拟器窗口打开,选择器击中了错误的设备:

    • 当前版本将模拟器选择器作用于目标 udid 窗口第一。
    • 如果您有意需要模拟器chrome/system UI,请使用 all: true.
  • OpenCode未显示 baepsae:

    • 重新运行 bash scripts/install.sh --tool opencode --skip-install --skip-build 并检查 ~/.config/opencode/opencode.json.
  • 副驾驶未自动注册:

    • 副驾驶MCP流是基于交互/会话的。使用以下命令重新运行安装程序 --interactive.
  • 跳过真实烟雾测试:

    • 首先启动iOS模拟器,然后运行 npm run test:real.