ExecBro
← back to docs

Platform & IDE Setup

Detailed setup instructions for all supported IDEs and platforms.

Requirements

  • Node.js 18+
  • React Native app running with Metro bundler
  • Recommended: execbro-sdk in your app — wires stores and the network layer into the agent for dramatically better debugging (optional; ExecBro works without it)
  • iOS UI automation: Facebook IDB or AXe CLI — required for tap, swipe, text input, accessibility on iOS Simulator
  • Physical iPhone/iPad: pymobiledevice3 , for screenshots of a USB-attached iPhone/iPad (iOS 15+) and coordinate taps on iOS 27+. See the physical device section below

No installation required — every client below uses npx to fetch the latest version on demand. After saving the configuration, fully quit and relaunch the client so it picks up the new server.

Claude Code

Project-specific (recommended)
claude mcp add execbro --scope project -- npx -y execbro@latest
Global (all projects)
claude mcp add execbro --scope user -- npx -y execbro@latest

Project scope writes a .mcp.jsonyou can commit, so the whole team picks ExecBro up in this repo and nowhere else. Global scope starts it in every session you open, including repos with no Metro server to connect to — convenient if you work in React Native all day, wasteful otherwise.

Or edit ~/.claude.json (user) / .mcp.json (project) manually:

{
  "mcpServers": {
    "execbro": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "execbro@latest"
      ]
    }
  }
}

Claude Desktop

Edit the config at ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows). You can also open it from Settings → Developer → Edit Config.

{
  "mcpServers": {
    "execbro": {
      "command": "npx",
      "args": [
        "-y",
        "execbro@latest"
      ]
    }
  }
}

Codex CLI (OpenAI)

codex mcp add execbro -- npx -y execbro@latest

Or edit ~/.codex/config.toml directly:

[mcp_servers.execbro]
command = "npx"
args = ["-y", "execbro@latest"]

Cursor

Via Command Palette: Cmd+Shift+P→ "View: Open MCP Settings". Or edit .cursor/mcp.json (project) / ~/.cursor/mcp.json (global):

{
  "mcpServers": {
    "execbro": {
      "command": "npx",
      "args": [
        "-y",
        "execbro@latest"
      ]
    }
  }
}

VS Code Copilot (1.102+)

Via Command Palette: Cmd+Shift+P→ "MCP: Add Server". Or edit .vscode/mcp.json:

{
  "servers": {
    "execbro": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "execbro@latest"
      ]
    }
  }
}

Windsurf

Edit ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "execbro": {
      "command": "npx",
      "args": [
        "-y",
        "execbro@latest"
      ]
    }
  }
}

Zed

Open the Agent Panel settings and click "Add Custom Server", or add to settings.json:

{
  "context_servers": {
    "execbro": {
      "command": "npx",
      "args": [
        "-y",
        "execbro@latest"
      ],
      "env": {}
    }
  }
}

Gemini CLI

Edit ~/.gemini/settings.json (user) or .gemini/settings.json (project):

{
  "mcpServers": {
    "execbro": {
      "command": "npx",
      "args": [
        "-y",
        "execbro@latest"
      ]
    }
  }
}

Android Setup

Android works out of the box — all device control tools use ADB, which ships with Android Studio. Verify it's available:

adb devices

iOS Simulator — UI Automation Setup

iOS UI automation tools (tap, swipe, text input, accessibility queries) require a UI driver. Install one of the following:

Option A: AXe CLI (experimental)

AXe is a standalone CLI for iOS simulator automation. No daemon required — single binary, simple setup.

brew install cameroncooke/axe/axe

Verify: axe --version

Add env to your MCP server configuration:

{
  "mcpServers": {
    "execbro": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "execbro@latest"
      ],
      "env": {
        "IOS_DRIVER": "axe"
      }
    }
  }
}

Note: AXe text input only supports US keyboard layout characters.

Option B: IDB (default)

IDB (iOS Development Bridge) is a tool built by Meta for automating iOS Simulators. Requires a background daemon.

brew install idb-companion

Verify: idb_companion --list 1

IDB is the default driver — no IOS_DRIVER env var needed.

What works without a UI driver

CapabilityWithout IDB/AXeWith IDB/AXe
ScreenshotsYes (simctl)Yes
App install/launch/terminateYes (simctl)Yes
URL openingYes (simctl)Yes
Boot simulatorYes (simctl)Yes
Tap / swipe / gesturesNoYes
Text inputNoYes
Accessibility tree queriesNoYes
Element finding / waitingNoYes
Hardware buttons (Home, Lock)NoYes

Troubleshooting:If you see errors like "IDB is not installed" or "AXe is not installed" in tap results, install the appropriate driver with the commands above and retry.

Physical iOS Device

A USB-attached iPhone or iPad. screenshot works on iOS 15 and later. On iOS 27 and later,tap works too, by x/y coordinates, including long press, in portrait and landscape. Not on a phone yet:swipe, input_text, and tap by testID, text or component.

1. Install pymobiledevice3

There is no Homebrew formula for it, and plain pip install is refused on current macOS (externally-managed-environment), so install it as an isolated CLI tool:

brew install pipx
pipx install pymobiledevice3

If you already useuv,uv tool install pymobiledevice3 does the same thing. Both land the binary in ~/.local/bin, which ExecBro checks directly, so it works even when your MCP client is launched from the GUI and does not inherit your shell PATH. Taps need version 11.32.0 or later; update an older install with pipx upgrade pymobiledevice3.

2. Mount the developer disk image

On iOS 17 and later, let pymobiledevice3 fetch and mount it:

pymobiledevice3 mounter auto-mount

On iOS 16 and below, auto-mountfails on a stock machine (it tries to write into a root-owned Xcode directory), so mount Xcode's existing image instead, picking the version closest to your device:

X=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/15.5
pymobiledevice3 mounter mount-developer \
  "$X/DeveloperDiskImage.dmg" "$X/DeveloperDiskImage.dmg.signature"

The device then appears in list_devices under "iOS physical", and screenshot accepts its UDID or name. Without pymobiledevice3 installed, no physical devices are listed and nothing else changes.

3. Taps (iOS 27 and later)

On top of the steps above:

1. Developer Mode onthe phone: Settings > Privacy & Security > Developer Mode (the phone restarts).

2. The Xcode 27 disk image mounted. The touch service ships only in Xcode 27's image; Xcode 26's (build 17A400) does not have it. An open Xcode 26 remounts its own image within a second, so quit Xcode first, then run:

pymobiledevice3 mounter umount-personalized
pymobiledevice3 mounter auto-mount
pymobiledevice3 mounter list

auto-mount downloads the image, so Xcode 27 does not need to be installed. In the mounter list output,ProductBuildVersion should start with 27. If it says 17A400, Xcode 26 is still running.

3. The phone unlocked, with the screen on.A tap on a dark screen would wake it and land on the lock screen, so tap refuses instead. Setting Auto-Lock to Never (Settings > Display & Brightness) keeps the phone awake during a session.

Then take a screenshot and tap with coordinates from it:

screenshot({ device: "00008030-001D69C00192802E" })
tap({ x: 697, y: 817, device: "00008030-001D69C00192802E" })
tap({ x: 697, y: 817, device: "00008030-001D69C00192802E", duration: 800 })

Pass the UDID from list_devicesrather than the name: a phone is often just called "iPhone", which also matches simulators.

A tap takes about 6 s, or about 9 s with the default before/after check (verify: false skips it). In landscape, tap asks the phone which way it is turned, which adds a second or two. If the phone stops answering, the tap is stopped after 15 s and never retried, because the touch may already have landed: take a screenshot before trying again.

Install the SDK (recommended)

ExecBro works with zero app changes, but installing the companion execbro-sdk package is the single biggest upgrade to debugging quality. It lets you wire the important parts of your app — your state stores and your network layer — directly into the agent's reach, so the AI inspects real Redux / TanStack Query state and full request/response bodies instead of guessing from the outside.

Under the hood, the MCP server connects over Chrome DevTools Protocol (CDP), which misses events that fire before it attaches and can't read request/response bodies on newer architectures. The SDK patches fetch and console at import time and buffers everything in-app from the very first line — the MCP server auto-detects it, no extra config.

Without SDKWith SDK
State stores (Redux, TanStack Query)Manual via execute_in_appWired up — direct references
Request/response bodiesNot availableFull (including GraphQL)
Startup network requests (auth, config)MissedCaptured from first fetch
Console logs from startupMay miss early logsCaptured from first log
Works on Bridgeless (Expo SDK 52+)PartialFull
Install
npm install execbro-sdk

Initialize in your app's entry file ( index.js, App.tsx, or app/_layout.tsx for Expo Router) as the first import, and pass in the stores and references you want the agent to reach:

import { init } from 'execbro-sdk';
import { store } from './store'; // Redux store
import { queryClient } from './queryClient'; // TanStack Query
import { navigationRef } from './navigation';

if (__DEV__) {
  init({
    stores: { redux: store, queryClient },
    navigation: navigationRef,
  });
}

init() alone already unlocks full log and network capture. Wiring stores, navigation, or custom references is what hands the agent direct control — it can read and act through any object you pass in, not just your state and navigation but AsyncStorage, MMKV, or any other reference you choose to expose. See the SDK guide for every option.