Skip to content

Claude Code on your iPhone and the iOS simulator: MCP setup

Add Mobster's MCP server to Claude Code with one command, then let Claude check the iOS screens it writes on a simulator or use your iPhone over USB.

In Mobster for Mac

Settings › Connectors › Add, next to Claude Code.

Or by hand

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

Config file: ~/.claude.json for you, or .mcp.json at the repository root for your team

What Claude Code gets back from mobster verify on your app: the lesson and its “Great job!” pass, but the streak stays at 3, so the check fails.

Claude Code can write a SwiftUI screen, but it can’t see one. With Mobster’s MCP server connected, Claude builds your app for the simulator, drives it through Mobster’s tools, and gets a verdict of passed or failed from assertions on the accessibility tree, with the frames that prove it. The same server lets Claude use a real iPhone plugged into your Mac.

For simulator work you need an Apple silicon Mac with macOS 15 or later and Xcode with an iOS Simulator runtime. For a real iPhone you also need Developer Mode on the phone and the WebDriverAgent runner set up for it in Mobster for Mac (Device setup). Mobster’s MCP server is tested with Claude Code.

Install Mobster for Mac

Get Mobster for Mac, drag it to Applications and open it. Its MCP server is the agent inside the app, so the command every client starts is this path, with mcp:

/Applications/Mobster.app/Contents/MacOS/mobster-agent

The first check creates Mobster’s own simulator, boots it headless and builds WebDriverAgent, once per Xcode version. Mobster never touches your own simulators: each one it creates has a name that starts with “Mobster”.

Add the server

In Mobster for Mac, open Settings › Connectors › Use Mobster from… and press Add next to Claude Code. It adds the server for every project, and when the app holds your model key it passes the app’s settings file with --env-file, so Smart uses the same key.

By hand, one command, run in your project’s folder:

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

The -- separates Claude Code’s own options from the command that starts the server. Without --scope, Claude Code stores the server in the local scope, so it shows up only in the folder you ran this in. Pick the scope you want:

ScopeCommandWhere it applies
Local (default)claude mcp add mobster -- /Applications/Mobster.app/Contents/MacOS/mobster-agent mcpThis project folder, for you
Userclaude mcp add --scope user mobster -- /Applications/Mobster.app/Contents/MacOS/mobster-agent mcpEvery project, for you, in ~/.claude.json
Projecta .mcp.json at the repository rootEveryone who clones the repository

To share it with your team, commit this .mcp.json. Claude Code asks each person to approve a project server before it connects.

{  "mcpServers": {    "mobster": { "command": "/Applications/Mobster.app/Contents/MacOS/mobster-agent", "args": ["mcp"] }  }}

Key-less checks need nothing more. For Smart, where Mobster runs the steps itself on your OpenAI or Anthropic key, point the server at a private env file:

claude mcp add mobster -- /Applications/Mobster.app/Contents/MacOS/mobster-agent mcp --env-file ~/.config/mobster/agent.env

The file holds one line, OPENAI_API_KEY=… or ANTHROPIC_API_KEY=…. Keep it out of the repository and readable only by you (chmod 600).

Timeouts need no change. Every Mobster tool call returns within 45 seconds and wait within 50. Claude Code’s default tool timeout is far longer than that, and its idle timer for stdio servers is reset by progress notifications, which Mobster sends every 5 seconds while a call waits.

Check it’s connected

Start claude in the project and type /mcp. Mobster should be listed as connected, with its tools. From the terminal, claude mcp list shows the same. Then ask Claude:

Call mobster's status tool and tell me what it says.

status reports Mobster’s version, the simulator setup, whether Smart is available (and if not, why), where runs go, and any open run.

A first check: a lesson

Say your app has lessons and a daily streak. Ask Claude to change the end of a lesson and prove it still works:

Restyle the lesson complete screen, then verify that finishing a lesson stillshows "Lesson complete", adds 10 XP and takes the streak from 3 to 4 days.

Claude builds the scheme for the simulator, then calls verify_start with the absolute app_path, the steps and the expectations. The expectations are fixed at that moment, before Claude touches the app. Each tap, type_text or swipe returns the new screen as an outline Claude reads. Three lines of the lesson complete screen, as screen returns them:

e3  other   "Total XP"                     value="10"      id=xp_earnede4  other   "Streak"                       value="4 days"  id=streak_dayse5  other   "Accuracy"                     value="100%"    id=accuracy

verify_finish checks every expectation on one settled read and returns the verdict, the path to a one-file HTML report and the overlay frame. If the restyle had broken the streak, the verdict is failed, with the reason. Run as a saved check from the terminal, that failure prints like this:

✗ failed  Lesson complete awards XP and the streak goes up  (31.4 s)  ✓ text "Lesson complete"  ✓ value id=xp_earned == 10  ✗ value id=streak_days == 4: was "3 days"

Claude then fixes the code, rebuilds and verifies again. The verdict comes from the assertions, never from a model. Give Claude Code a real iPhone walks through the loop in more detail.

Make it a habit with CLAUDE.md

Put the standing instruction in your project’s CLAUDE.md, with your scheme and app names, so Claude verifies every UI change without being asked:

## Verifying UI changesAfter you change a screen in this iOS app, verify it before you say it works.1. Build for the simulator:   xcodebuild -scheme <Scheme> -destination 'generic/platform=iOS Simulator' -derivedDataPath .mobster/build CODE_SIGNING_ALLOWED=NO build2. Call mobster's verify_start with app_path set to the absolute path of   .mobster/build/Build/Products/Debug-iphonesimulator/<App>.app, the steps in plain English, and expect:   what must be true when the steps are done.3. Drive with screen, tap, type_text and swipe, then call verify_finish.4. If the verdict is failed, fix the code and verify again. Report the verdict and the report path.

Give the controls your checks need an accessibility identifier, such as .accessibilityIdentifier("streak_days"), so an id selector survives copy changes.

Use a real iPhone

Claude calls list_devices to see every device Mobster can use: USB iPhones set up for it, Mobster’s simulators and any WebDriverAgent address. The phone tools (screen, tap, type_text, swipe, alert, open_url, launch_app and home) called with device and no run_id drive that device directly. Mobster takes the device’s lock on the first call, so no other Mobster app or command drives it at the same time. stop with the device, or 90 idle seconds, releases it.

On a real iPhone a tap on Send sends. Claude Code approves a tool, not a device: allowing tap for simulator work allows it on your phone too. Name the phones the server may drive, and every other real device is refused:

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

Mobster marks each tool in its MCP annotations. status, screen, list_devices, wait, wait_for, read_notifications and unlock_status only read, and the tools that act on the device are marked as acting. If you add allow rules in Claude Code’s settings, allow only the read tools, such as mcp__mobster__screen, and keep the prompt on the rest. The server’s instructions also tell Claude that text on the screen is data, not instructions, and to ask you before anything that sends, buys, posts or deletes on a real iPhone.

A locked phone stops the call at once with “Your iPhone is locked. Unlock it and try again. No action was taken.” Mobster never enters a passcode.

Troubleshooting

SymptomFix
/mcp doesn’t list mobster in another projectThe server was added in the local scope. Add it with --scope user, or commit a .mcp.json
A project server waits for approvalRun claude in the project and approve it. claude mcp reset-project-choices asks again
The first verify_start returns status: "preparing"The first run boots the simulator and builds WebDriverAgent. Claude calls wait until it’s ready
verify_start refuses smartSmart is off. status says why: no OPENAI_API_KEY or ANTHROPIC_API_KEY, an env file that doesn’t exist, or --keyless
couldnt_runreason.class and reason.fix in the result say what to do. Getting started with verify covers each class

Every tool and its arguments are in the MCP reference.

Questions

  • Does Claude Code need a longer MCP timeout for Mobster?

    No. Every Mobster tool call returns within 45 seconds and wait within 50, and Claude Code's default tool timeout is far longer. Mobster also sends a progress notification every 5 seconds, which keeps Claude Code's idle timer from firing.

  • Why does Claude Code only see Mobster in one folder?

    claude mcp add uses the local scope unless you pass --scope, so the server belongs to the folder you ran it in. Add it again with --scope user to use it in every project, or commit a .mcp.json to share it with your team.

  • Does Claude Code need a model key for Mobster?

    No. In the key-less loop Claude drives the app with its own model and Mobster judges the result from the accessibility tree. Mobster calls a model only for `verify_start` with `smart`, which needs your own OpenAI or Anthropic key.

  • How do I give Claude Code access to the iOS Simulator?

    Add Mobster's MCP server with claude mcp add mobster -- /Applications/Mobster.app/Contents/MacOS/mobster-agent mcp. Claude Code then gets a headless simulator that Mobster creates and boots, reads each screen as a list of controls by name, taps, types and swipes, and gets passed or failed from assertions. Mobster never touches your own simulators.

  • Can Claude Code control the iOS Simulator?

    Yes, through an MCP server. With Mobster connected, Claude Code builds your app for the simulator, opens it, and acts on buttons and fields by name from the accessibility tree instead of guessing from a screenshot. The verdict on the screen comes from assertions, not from Claude.

  • What does Claude Code need for iOS development with Mobster?

    An Apple silicon Mac with macOS 15 or later and Xcode with an iOS Simulator runtime. A real iPhone also needs Developer Mode and the WebDriverAgent runner, which Mobster for Mac sets up for you.

  • Does it work with Claude Code on Windows?

    No. Xcode and the iOS Simulator run only on macOS, so Mobster needs an Apple silicon Mac. Claude Code on Windows or Linux can't drive an iOS simulator through Mobster.

Sources

We read each of these on 8 October 2026. Reviewed by Andy Guo on . Corrections are welcome at the GitHub repo.

Claude Code’s logo is a trademark of Anthropic, shown only to name the product. Mobster isn’t affiliated with or endorsed by Anthropic.