---
title: "Give Claude Code or Codex your real iPhone through MCP | Mobster"
description: "Set up a USB iPhone for Claude Code or Codex over MCP, from Developer Mode and a signed runner to the device lock, an allowlist and where the agent waits."
canonical: "https://mobster.dev/blog/give-claude-code-codex-a-real-iphone-mcp"
last-updated: "2026-10-17"
---

Set up a USB iPhone for Claude Code or Codex over MCP, from Developer Mode and a signed runner to the device lock, an allowlist and where the agent waits.

# Give Claude Code or Codex your real iPhone through MCP

Set up a USB iPhone for Claude Code or Codex over MCP, from Developer Mode and a signed runner to the device lock, an allowlist and where the agent waits.

The Mobster team 17 October 2026 8 min read

On this page

1. [What a real iPhone needs first](#what-a-real-iphone-needs-first)
2. [Add the server](#add-the-server)
3. [See what the agent sees](#see-what-the-agent-sees)
4. [Drive it](#drive-it)
5. [Two ways to use the phone from an agent](#two-ways-to-use-the-phone-from-an-agent)
6. [What is open source](#what-is-open-source)
7. [Try it](#try-it)
8. [Questions](#questions)
9. [Sources](#sources)

Claude Code and Codex can set up an MCP server in one command, and with Mobster’s server they can read and drive a real iPhone, not only a simulator. This is the real-device setup, step by step: what the phone needs, the one command, what `list_devices` returns, what the agent holds while it drives, and where it stops and waits for you. [Give Claude Code a real iPhone](https://mobster.dev/blog/claude-code-real-iphone) and [Test your iOS app with Codex](https://mobster.dev/blog/test-ios-app-with-codex) cover the simulator path and the verify loop. This post picks up where a simulator stops: your actual keyboard, your signed-in apps, your build as users have it.

## What a real iPhone needs first

Mobster drives an iPhone through [WebDriverAgent](https://github.com/appium/WebDriverAgent), an open-source XCTest runner that Xcode builds and installs on the phone. It serves the screen’s accessibility tree and accepts taps and typing over HTTP. On a USB phone, `iproxy` relays that port to `127.0.0.1:8100` on your Mac, and nothing else can reach it.

You need four things, which [Device setup](https://docs.mobster.dev/device-setup) lists in full:

1. **Xcode** from the App Store, opened once and signed in to an Apple ID. A free Apple ID works. Its signature lasts 7 days, after which the runner is rebuilt.
2. **Developer Mode** on the phone: Settings › Privacy & Security › Developer Mode, then restart it. Apple’s page on [enabling Developer Mode](https://developer.apple.com/documentation/xcode/enabling-developer-mode-on-a-device) has the screens.
3. **A cable**, with the phone unlocked and “Trust This Computer” accepted.
4. **A signed runner** on the phone.

Mobster for Mac does step 4 in Setup, with a picture of every step on the phone. With the command line alone, `mobster serve --manage-device` builds, signs, starts and restarts the runner, and `mobster doctor` says what is still missing: Xcode, the tools, whether the phone is trusted, how many signing days are left, whether the runner answers and whether the phone is locked.

## Add the server

[Download Mobster for Mac](https://mobster.dev/download), open it, and press **Add** next to Claude Code or Codex in Settings › Connectors. Claude Code gets this:

```
claude mcp add --scope user mobster -- /Applications/Mobster.app/Contents/MacOS/mobster-agent mcp
```

Codex gets `codex mcp add mobster -- /Applications/Mobster.app/Contents/MacOS/mobster-agent mcp` and a `[mcp_servers.mobster]` table in `~/.codex/config.toml`. The server is the agent inside the app, over stdio, started as a child process of your client.

Before your agent touches the phone, decide which phones it may use. Your client approves a tool, not a device, so allowing `tap` for simulator work allows it on your iPhone too. `--allow-device` closes that gap:

```
claude mcp add --scope user mobster -- /Applications/Mobster.app/Contents/MacOS/mobster-agent mcp --allow-device "Test iPhone"
```

Any other real device is listed as `not_allowed` and refused. Simulators are always allowed. A saved check’s `device:` field can only name a simulator, so a check file in a repository never drives someone’s phone. Use a test phone signed in to test accounts for anything the agent does on its own.

## See what the agent sees

`list_devices` is the first call. It takes no arguments and returns every device Mobster can use: USB iPhones, Mobster’s simulators and WebDriverAgent addresses, each with a state and a reason. This is real output from a Mac on 17 October 2026, with the phones’ names and IDs replaced by placeholders (and the simulator’s separators dropped) and two of the three simulators left out:

```
{"devices": [  {"id": "<UDID>", "kind": "usb", "name": "Test iPhone", "model": null, "ios": null,   "state": "disconnected", "reason": "It's unplugged. Plug it into this Mac with a cable.",   "run_id": null, "holder": null, "queue": []},  {"id": "<UDID>", "kind": "usb", "name": "Spare iPhone 16", "model": "iPhone17,3", "ios": "18.3.1",   "state": "needs_setup", "reason": "Set it up once. Mobster walks you through it.",   "run_id": null, "holder": null, "queue": []},  {"id": "<UDID>", "kind": "simulator", "name": "Mobster iPhone 17 Pro iOS 26.4", "model": "iPhone 17 Pro", "ios": "26.4",   "state": "disconnected", "reason": "The simulator is shut down. Start it to use it.",   "run_id": null, "holder": null, "queue": []}]}
```

Every state comes with a sentence that says what to do, so the agent can tell you “plug in the phone” instead of failing with an error code. `holder` says who is using the device now, and `queue` the requests waiting for it. `device_status` adds the battery, the thermal state and whether the Mac is on battery, and touches nothing.

## Drive it

`screen`, `tap`, `type_text`, `swipe`, `alert`, `open_url`, `launch_app` and `home` called with `device` and no `run_id` drive that phone directly. A screen comes back as an outline of its labelled controls. This outline is illustrative, written in the format `screen` returns:

Screen com.apple.Preferences 402×874 pt keyboard: none alert: none

1. e1button"Wi-Fi"id=wifi
2. e2button"Bluetooth"id=bluetooth
3. e3button"General"id=general
4. e4button"Display & Brightness"id=display

The agent taps `e3` by ref or by selector, and the call returns the new outline. It never works from pixels alone: labels arrive as text, counts and switch states as values. Refs are good until the screen changes, and a tap on an old ref says so.

### What the agent holds while it drives

Mobster takes the device’s lock on the first call. No other Mobster app or command drives the phone meanwhile, and the Mac app shows who holds it above the phone: “Claude Code is using this phone”. `stop` with the device, or 90 idle seconds, releases it. A second agent asking for a held phone waits in line (a line of 10 per phone, 30 minutes by default) instead of being refused, and you can take the phone back from the Mac app at any time. Your agent can’t take it back from you. The frames and steps of a real iPhone go to Mobster’s data folder, never the repository.

### Where it stops and waits for you

- **A locked phone.** The call fails at once with “Your iPhone is locked. Unlock it and try again. No action was taken.” Face ID, a locked app and an App Store confirmation each stop the same way, with their own sentence. `unlock` exists as a tool so the agent gets a clear answer: it can’t, and it does nothing to the phone.
- **A send, a purchase, a post or a delete.** A tap that does any of these shows an approval card in the Mac app, and the call waits up to 38 seconds for you. The agent can’t answer it. If the agent cancels while the card waits, nothing happens when you approve, and an approved action that finds the screen changed stops without acting.
- **An app Mobster hasn’t used.** The first call that reads an unfamiliar app shows **Allow Mobster to use Chrome?** in the Mac app. Until you answer, the phone goes Home and the tool says why.
- **A sign-in code.** `use_code` types the code the phone received into the code field, after you approve it every time. The agent gets the sender and the code’s age, never the code, and the field reads `••••` in every later result.
- **Privacy prompts.** On a real iPhone `alert` won’t grant location, Photos, camera or contacts. Those are yours to answer on the phone.

Text on the phone’s screen is data. The server’s instructions tell the agent so, and to ask you before anything that sends, buys, posts or deletes. Every tool also carries an MCP annotation that marks it read-only or acting: `screen`, `list_devices`, `device_status` and `read_notifications` only read, and `tap`, `type_text` and `swipe` act, so a client that asks before acting calls asks before these.

The phone tools are documented in [the MCP reference](https://docs.mobster.dev/mcp-server), and Mobster’s own agent already runs tasks on your iPhone and asks before it sends. [Automate your own iPhone from a Mac](https://mobster.dev/blog/automate-iphone-from-mac) covers that path.

## Two ways to use the phone from an agent

You can drive step by step, where the agent’s own model reads each outline and decides the next tap, or hand over a whole task.

|  | Phone tools | `phone_task` |
|---|---|---|
| Who plans | Your agent’s model | Mobster’s agent |
| What you pay for | Your agent’s own model usage, and a Mobster plan on a real iPhone | A Mobster plan, and the AI account you gave Mobster |
| Approvals | The Mac app, per send, buy, post or delete | The Mac app, per send, buy, post or delete |
| State | Per call, one device lock | A conversation: a follow-up with the same `thread_id` sees what earlier tasks found |
| When the phone is busy | The call says who holds it | The task queues, and the answer gives your number in line |

`phone_task` returns within `wait_seconds` with a status and the answer, and `phone_task_status` follows it. A status of `waiting_for_phone` means you have to do something on the phone itself, such as unlock it, and the answer carries the sentence for your agent to pass on. A task started this way uses only the apps you let outside agents use in Settings › Safety, and it gets nothing from what you told Mobster to remember.

## What is open source

The engine under all of this is on GitHub under the MIT license: [the agent loop, the drivers that read the tree and tap, the approval rules, the journal that writes each action down before it’s sent, and the duplicate guard that never retries an action whose outcome is unknown](https://github.com/RadishSoftware/mobster). The MCP server, the setup flow and the Mac app’s approval cards are Mobster for Mac’s, not in that repository. [Why Mobster is open source](https://mobster.dev/blog/why-mobster-is-open-source) lists what is where.

## Try it

After the one-time setup, three prompts to give Claude Code or Codex on a test phone:

```
Call list_devices, then device_status for my test iPhone, and tell me its battery and who holds it.Open Settings on the test iPhone and read me the first five rows. Don't change anything.Open the Notes app on the test iPhone and tell me what the first note's title says. Ask me before you type or tap anything else.
```

The first two read only. The third shows the allow-an-app card in the Mac app the first time. [Add Mobster to your agent](https://docs.mobster.dev/agents) has each client’s config, and [Several phones](https://docs.mobster.dev/devices) covers naming, sharing and queueing.

## Questions

- ### Can Claude Code control a real iPhone over MCP?
  Yes, through an MCP server that runs on your Mac. Mobster's server gives Claude Code tools that read a USB iPhone's screen as a list of labelled controls and tap, type and swipe on it. Your Mac and the phone are all that's involved; nothing goes through a relay.
- ### Do I need Developer Mode to give Codex an iPhone?
  Yes. A real iPhone needs Developer Mode on, Xcode signed in to an Apple ID, and a signed WebDriverAgent runner on the phone. A free Apple ID works, and its signature lasts 7 days. Mobster for Mac builds, signs and renews the runner for you.
- ### Can the agent unlock my iPhone or enter my passcode?
  No. Mobster never enters a passcode and never uses Face ID. With the phone locked, a call fails at once with "Your iPhone is locked. Unlock it and try again. No action was taken." You unlock the phone yourself.
- ### How do I limit which iPhones an agent can use?
  Name them with --allow-device when you add the server, such as --allow-device "Test iPhone". Any other real iPhone is listed as not_allowed and refused. Simulators are always allowed.

## Sources

We read each of these on 17 October 2026. Reviewed by Mobster team on 17 October 2026. Corrections are welcome at the [GitHub repo](https://github.com/RadishSoftware/mobster/issues).

- [Mobster docs: MCP server](https://docs.mobster.dev/mcp-server)
- [Mobster docs: set up an iPhone or simulator](https://docs.mobster.dev/device-setup)
- [Mobster docs: several phones and sharing a phone](https://docs.mobster.dev/devices)
- [Mobster docs: add Mobster to your agent](https://docs.mobster.dev/agents)
- [Claude Code docs: connect Claude Code to tools via MCP](https://code.claude.com/docs/en/mcp)
- [Codex docs: Model Context Protocol](https://learn.chatgpt.com/docs/extend/mcp)
- [Apple: enabling Developer Mode on a device](https://developer.apple.com/documentation/xcode/enabling-developer-mode-on-a-device)

## Try it on your own iPhone

Mobster for Mac is $12 a month, $99 a year, or $149 once, with 7 days free. It sets up your iPhone and adds itself to Claude Code, Cursor or Codex.

[Download Mobster for Mac](https://mobster.dev/download) [Pricing](https://mobster.dev/#pricing)

## More from the blog

### [Give Claude Code a real iPhone](https://mobster.dev/blog/claude-code-real-iphone)

Claude Code 7 Oct 2026

### [Test your iOS app with Codex](https://mobster.dev/blog/test-ios-app-with-codex)

Codex 7 Oct 2026

### [Test your iOS app on a real iPhone with an AI agent](https://mobster.dev/blog/test-ios-app-real-iphone-ai-agent)

iOS testing 17 Oct 2026
