mcp-baepsae
v3.1.10
Published
Local MCP server for iOS Simulator and macOS app automation with a native Swift bridge
Maintainers
Readme
mcp-baepsae
Baepsae (Vinous-throated Parrotbill) — A tiny Korean bird. Round, chubby, and constantly hopping around chirping. Known for its grit — even when a little bird tries to keep up with a stork, it never gives up. This project is small too, but it pecks away at your simulators tirelessly.
Local MCP server for iOS Simulator and macOS app automation with a TypeScript MCP layer and a Swift native bridge.
한국어 문서는 README-KR.md를 참고하세요.
Table of Contents
- Prerequisites
- Install
- MCP Setup (Recommended)
- Client Matrix
- For LLM
- Manual Setup (Fallback)
- Project Structure
- Commands
- MCP Tool Status
- Troubleshooting
Prerequisites
- macOS 14+
- Xcode + iOS Simulator
- Node.js 18+
- Swift 6+
Permissions
Accessibility permission is required for UI automation features (describe_ui, tap by ID).
- Open System Settings > Privacy & Security > Accessibility.
- Enable your terminal (Terminal, iTerm2, VSCode) or command runner (
node,openclaw). - If the app is missing, click
+and add it manually.
Install
Option A) npm (easiest)
# Run directly without installing
npx mcp-baepsae@latest
# Or install globally
npm install -g mcp-baepsaeOn macOS, the Swift native binary is built automatically during install. If Swift is not available, the server still works with simctl-based features.
Option B) From source
git clone https://github.com/oozoofrog/mcp-baepsae.git
cd mcp-baepsae
npm install
npm run buildMCP Setup (Recommended)
Use the installer script that calls each client's MCP install flow directly.
bash scripts/install.sh --tool allClient Matrix
| Client | Install Path | Script Target | Notes |
|---|---|---|---|
| Claude Code | claude mcp add | --tool claude-code | Supports multi-scope via --claude-scope |
| Claude Desktop | claude mcp add --scope user | --tool claude-desktop | User-level registration |
| Codex CLI | codex mcp add | --tool codex-cli | Also works for Codex Desktop settings |
| Codex Desktop | Codex CLI MCP config | --tool codex-desktop | Uses same MCP registry as CLI |
| OpenCode | Global config (~/.config/opencode/opencode.json) | --tool opencode | Auto-updated by installer |
| Gemini | gemini mcp add | --tool gemini | User scope setup |
| Google Antigravity | Gemini-compatible MCP flow | --tool antigravity | Uses Gemini MCP command path |
| GitHub Copilot | copilot or gh copilot session | --tool copilot | Interactive/session-based setup |
For LLM
If you are an LLM agent setting up this MCP server, here is everything you need:
Quick start (one command)
# Register baepsae as an MCP server for all supported clients
bash scripts/install.sh --tool allIf you installed via npm instead of cloning the repo, use npx:
# Claude Code
claude mcp add baepsae -- npx -y mcp-baepsae@latest
# Codex CLI
codex mcp add baepsae -- npx -y mcp-baepsae@latestAutomation flags
# 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 --uninstallRuntime options
The installer supports multiple runtimes via --runtime:
| Flag | Command | When to use |
|---|---|---|
| --runtime node (default) | node dist/index.js | Local source build |
| --runtime npx | npx -y mcp-baepsae@latest | npm registry, no global install |
| --runtime bunx | bunx mcp-baepsae@latest | Bun users |
| --runtime global | mcp-baepsae | After npm install -g mcp-baepsae |
Manual Setup (Fallback)
Use this when you do not want to run scripts/install.sh.
Using npx (recommended for npm users)
# 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@latestUsing local build
# 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.jsProject Structure
- MCP server:
src/index.ts - Native binary project:
native/ - Native binary output:
native/.build/release/baepsae-native - Tests:
tests/mcp.contract.test.mjs,tests/mcp.real.test.mjs
Commands
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 verify # test + test:real
npm run setup:mcp # Alias for scripts/install.shMCP Tool Status
32 tools implemented end-to-end, organized by platform:
iOS Simulator Only (11)
| Tool | Description |
|---|---|
| list_simulators | List available iOS simulators |
| screenshot | Capture simulator screen |
| record_video | Record simulator screen |
| stream_video | Stream video frames |
| open_url | Open URL in simulator (Safari/Deep Link) |
| install_app | Install .app or .ipa |
| launch_app | Launch app by Bundle ID |
| terminate_app | Terminate running app |
| uninstall_app | Uninstall app |
| button | Hardware buttons (home, lock, side, siri, apple-pay) |
| gesture | Preset gestures (scroll, swipe-edge) |
macOS Only (4)
| Tool | Description |
|---|---|
| list_apps | List running macOS apps |
| scroll | Scroll wheel events |
| menu_action | Execute menu bar actions |
| get_focused_app | Get focused app info |
Cross-Platform — iOS Simulator + macOS (15)
| Tool | Description |
|---|---|
| describe_ui | Accessibility tree (pagination, filter, subtree, summary) |
| search_ui | Search UI elements by text/ID/label |
| tap | Tap by coordinates or element ID/label (supports double-click) |
| type_text | Type text input |
| swipe | Swipe gesture |
| key | HID keycode input |
| key_sequence | Sequential keycode input |
| key_combo | Modifier + key combination |
| touch | Touch down/up events |
| right_click | Right-click by ID/label or coordinates |
| drag_drop | Drag and drop |
| clipboard | Read/write clipboard |
| list_windows | List app windows |
| activate_app | Bring app to foreground |
| screenshot_app | Capture app window screenshot |
Utility (2)
| Tool | Description |
|---|---|
| baepsae_help | Show help info |
| baepsae_version | Show version info |
Usage Examples
Open a URL (iOS Simulator):
// Open Naver Mobile
open_url({ udid: "...", url: "https://m.naver.com" })Manage Apps (iOS Simulator):
// 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 App Automation:
// List running macOS apps
list_apps({})
// Take screenshot of a macOS app
screenshot_app({ bundleId: "com.apple.Safari" })Troubleshooting
Invalid environment variable formaton Claude setup:- Use current script (
scripts/install.sh) orclaude mcp add --env="KEY=value" ...format.
- Use current script (
Missing native binaryerror:- Run
npm run buildand confirmnative/.build/release/baepsae-nativeexists.
- Run
- OpenCode does not show
baepsae:- Re-run
bash scripts/install.sh --tool opencode --skip-install --skip-buildand check~/.config/opencode/opencode.json.
- Re-run
- Copilot not auto-registered:
- Copilot MCP flow is interactive/session-based. Re-run installer with
--interactive.
- Copilot MCP flow is interactive/session-based. Re-run installer with
- Real smoke test skipped:
- Boot an iOS simulator first, then run
npm run test:real.
- Boot an iOS simulator first, then run
