# How to install phonedriver

> Set up phonedriver by pasting one prompt into your agent, or install the binary by hand on macOS, Linux or Windows and check it with phonedriver doctor.

Web page: https://phonedriver.dev/docs/install/

phonedriver is one binary: the CLI, the daemon and the MCP server. The Android agent is packed inside it, so there is nothing else to download.

> The current release is phonedriver 0.1.1, on npm, Homebrew and GitHub Releases. You only need to build from source if you want to change it.

## Easiest: ask your agent

Paste this into Claude Code, Codex, Cursor or any agent that can run commands. It checks your machine, adds the MCP server to itself and tells you what to plug in.

```prompt
Set up phonedriver so you can use my phone. Run `npx -y phonedriver doctor` and help me fix what it flags. Add its MCP server to this client (the server command is `npx -y phonedriver mcp`). Then run `npx -y phonedriver skill`, follow it, and show me what is on my phone's screen.
```

The rest of this page is the same setup by hand.

## By hand: npx

The `phonedriver` npm package is a small launcher. On first run it downloads the binary for your platform from GitHub Releases, checks its SHA-256 against the `.sha256` file published beside it, caches it (`~/Library/Caches/phonedriver/npm` on macOS, `~/.cache/phonedriver/npm` on Linux, `%LOCALAPPDATA%\phonedriver\npm` on Windows) and runs it. Later runs use the cache and make no network request. The launcher contacts GitHub only to download the binary and sends no telemetry. It needs Node 18 or later.

```sh
npx -y phonedriver --version
claude mcp add phonedriver -- npx -y phonedriver mcp
```

## Permanent install

These put `phonedriver` on your `PATH`.

```sh
# macOS and Linux
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/hridaya423/phonedriver/releases/latest/download/phonedriver-installer.sh | sh

# Homebrew (macOS and Linux)
brew install hridaya423/tap/phonedriver
```

```powershell
# Windows
powershell -ExecutionPolicy Bypass -c "irm https://github.com/hridaya423/phonedriver/releases/latest/download/phonedriver-installer.ps1 | iex"
```

The shell and PowerShell installers put `phonedriver` in `$CARGO_HOME/bin` (`~/.cargo/bin`) and add it to your `PATH`. The iOS Simulator runner needs no download: its sources are inside the binary, and the first command that needs it builds it on your Mac with Xcode and XcodeGen.

## Build from source

Use Rust 1.99 or later.

```sh
cargo build --release
```

The build packs the Android agent, so it needs the Android SDK with build-tools **37.0.0** and platform **android-37.0** (`ANDROID_HOME`, falling back to `ANDROID_SDK_ROOT`), `d8` and JDK 17. Override the versions with `ANDROID_BUILD_TOOLS` and `ANDROID_PLATFORM`. If anything is missing, the build says exactly what and how to get it. To skip that step, set `PHONEDRIVER_AGENT_JAR` to a built `phonedriver-agent.jar` (`bash android-agent/build.sh` makes one).

For iOS only, with no Android toolchain:

```sh
cargo build --release -p phonedriver --no-default-features
```

That binary has no Android support, and `phonedriver doctor` skips the Android checks. The binary is `target/release/phonedriver`.

## Check it works

```console
$ phonedriver version
phonedriver 0.1.1
```

`phonedriver doctor` checks adb, each Android device, the agent, UiAutomation, the video stream, Xcode, the simulators and the permissions of the daemon socket. Each line says `ok`, `warn` or `fail`, and a fix follows every line that is not `ok`.

```console
$ phonedriver doctor
ok    adb server       0029 at 127.0.0.1:5037
warn  android devices  none connected
      fix: Connect a phone with USB debugging on, or start an emulator; `adb devices` lists what adb sees.
ok    xcode            Xcode 27.0, Build version 27A266a
ok    daemon socket    /Users/you/.phonedriver/run/daemon.sock mode 600 in a directory of mode 700
```

## Next

Connect it to an agent: [Claude Code](/docs/claude-code/) or [Cursor and other MCP clients](/docs/cursor-and-mcp-clients/). Then pick a device: an [Android emulator](/docs/android-emulator/), a [real Android phone](/docs/android-phone/), the [iOS Simulator](/docs/ios-simulator/) or an [iPhone](/docs/iphone/).

## Environment variables

| Name | Default | Meaning |
|---|---|---|
| `PHONEDRIVER_HOME` | `~/.phonedriver` | Where the daemon keeps its socket, `daemon.log`, `traces/`, `tmp/` and the iOS `runner/` builds. Set it to run a separate daemon. |
| `PHONEDRIVER_SOCKET` | under `PHONEDRIVER_HOME` | The daemon's socket or named pipe. Point it at an `ssh -L` forward to use another machine's devices. |
| `PHONEDRIVER_DEVICE` | none | The device to use when `--device` is not given. Also read by `phonedriver mcp`. |
| `PHONEDRIVER_DISPLAY` | `main` | `hidden` makes the Android agent work on a second screen that the person holding the phone cannot see (Android 13 and later; `--display hidden` does the same). See [the Android phone page](/docs/android-phone/#a-hidden-screen-for-the-agent). |
| `PHONEDRIVER_SESSION` | `default` | The session name, as `--session`. |
| `PHONEDRIVER_TEAM` | none | Apple developer team ID that signs the iOS runner on a physical device. |
| `PHONEDRIVER_GUARD` | on | `off` stops the [approval guard](/docs/approval-guard/). |
| `PHONEDRIVER_ASK` | none | More taps to ask about, besides payments and account deletion: `send`, `delete`, `install`, comma separated. See the [approval guard](/docs/approval-guard/). |
| `PHONEDRIVER_SECRET` | none | The text for `type --secret`, instead of stdin. |
| `PHONEDRIVER_TRACE_FULL`, `PHONEDRIVER_TRACE_SCREENS` | off | Keep observation text, or screenshots, in traces. |
| `ADB_SERVER_SOCKET` | `tcp:127.0.0.1:5037` | The adb server to use, for example a tunnel to another machine. |
