Cloud Agents
Let a cloud coding agent test on your own iPhone. The phone stays in your pocket, your computer can be off, and there is no cable. Set up once per device.
What this is
Cloud coding agents run on Linux, so they have no Xcode, no Simulator and no USB. An agent can write iOS code but never watch it run. The phone does not need to move for that to be fixed, it only needs to be reachable.
MobAI puts a headless build of itself inside the agent's sandbox. It connects to devices you have onboarded, over your own Tailscale network, and serves the ordinary MobAI API on localhost. From the agent's point of view it is indistinguishable from a desktop MobAI: it can list devices, take screenshots, tap, type, install apps and run whole test flows.
Nothing is hosted by us. The traffic goes from the sandbox to your phone across your tailnet. We store only what is needed to find the device again: its identifier, name, iOS version and an encrypted pairing record.
Requirements
- An iPhone or iPad on iOS 17 or later.
- A mobai account. Free accounts get a short session per day; Pro removes the limit.
- A Tailscale account, free tier is fine.
- The device connected by cable once, for the setup below.
Where to start
Connect the device by cable and hover its row in the device list. Three buttons appear on the right. Press the cloud one.
The buttons are hidden until you hover the row. Cloud on the left, then safety settings, then start.
The five steps
1. Pair for cloud
Creates a separate pairing identity for cloud access and uploads it to your account, encrypted. Your normal MobAI setup keeps its own pairing, so revoking cloud access later cannot break anything local.
Unlock the phone and confirm the Trust prompt if it appears. If the device is already onboarded, the wizard says so and offers to continue or re-pair, and the step numbers along the top become clickable so you can jump straight to any step.
2. Prepare the device
Gets the device ready to be driven and installs what MobAI needs on it. Keep the cable connected and the device unlocked while this runs. It can take a few minutes.
This step needs the cable, which is why it happens now rather than later. If it fails, you can skip it and come back: a session will use whatever is already installed on the phone.
3. Tailscale
The phone and the agent's sandbox meet on your tailnet, so the phone has to be on it.
- Install Tailscale on the device from the App Store.
- Sign in to your Tailscale account.
- Leave it connected.
4. API key
Creates a key named "Cloud agent" that the sandbox uses to ask which devices you onboarded and to fetch the pairing identity. It is separate from your other keys, so you can revoke it on its own from the API Keys screen.
On Claude Code you will not need this key at all, see below.
5. Set up the agent
The wizard generates a setup script for the platform you pick. Paste it where that platform runs a command when it creates a sandbox. The script installs Tailscale, MobAI, the MobAI CLI, and a skill that teaches the agent how to use them.
The three platforms differ in ways that matter, so read the section for yours.
Claude Code
Claude Code's web sandbox has no secrets store. Its environment variables field is labelled as visible to anyone using the environment, and those variables are not available while the setup command runs. So nothing secret goes there, and you connect inside the chat instead.
- In your repo settings, paste the allowed hosts from the wizard into the network settings. The sandbox filters outbound traffic and the setup fails without them.
- Paste the setup script into the environment setup command. It installs tools only.
- Start a session and ask the agent to run something on your device. It already knows how, because the script installs a session hook and a skill.
- The agent prints a Tailscale login link. Open it and approve.
- The agent asks for your MobAI account email, then for the six digit code sent to it.
Nothing long lived passes through the conversation. The one time code expires in minutes and the session token it returns is written to disk in the sandbox. You repeat the two approvals once per session, because each session gets a fresh container.
Cursor
Cursor has a dashboard for this, so most of it is filled in rather than written by hand. Secrets are injected at runtime and can be kept out of transcripts.
- Add the two secrets from the wizard under Settings, then Secrets, on cursor.com. They reach the agent as environment variables, and can be scoped to a single environment.
- Open Cloud Agents, pick the repository, and paste the setup script from the wizard as the install command.
- Let the agent run through the setup, then save the snapshot so later runs start from it.
.cursor/environment.json
to the repo, and that file wins over dashboard settings from then on. Edit it directly
only if you want the configuration committed and shared with the team.
Codex not supported yet
Use Claude Code or Cursor meanwhile. Nothing is wasted: onboarding a phone is not tied to any one platform, so it will work on Codex the day we support it.
Building an app
Agent sandboxes have no Xcode, so an app is built by CI on a macOS runner. Set this up once per project with Builder, on your own computer:
# Install
brew install mobai-app/tap/ios-builder
# or: curl -sSL https://raw.githubusercontent.com/MobAI-App/ios-builder/main/install.sh | bash
# Add the build workflow. init detects the repo, writes the
# workflow, and offers to commit, push and run the first build.
builder auth github
builder init
# Optional: signed builds that install on a physical device
builder signing setup
builder signing setup
puts your certificate and provisioning profile into your repository's encrypted
secrets, so signing happens on the build runner and the sandbox only ever downloads an
app that is already signed. Nothing sensitive reaches the agent.
After that the agent can build with
builder ios build
and install the result with
mobai app install.
builder ios build
on your own machine, or trigger the workflow from the GitHub web interface.
Signing
An unsigned app installs on a simulator but not on a physical device. There are two separate things signing applies to, and they are easy to confuse.
Your app
Handled by Builder, on the build runner, as above.
MobAI on the device
Installed during step 2 while the cable is connected. If you signed with a free Apple ID it expires after seven days, and you reconnect the phone and run that step again to renew it. A paid Apple Developer account lasts a year.
On Codex and Cursor you can avoid that renewal entirely by adding signing secrets to the environment, listed in the wizard under "Let the agent sign apps". A session then renews it on its own, and the agent can also sign apps it builds. This needs a paid Apple Developer account.
Driving the device
The setup script installs the MobAI CLI and a skill, so the agent knows the commands without being told. For exploring, one action at a time:
mobai devices
mobai bridge start
mobai observe
mobai screenshot -o /tmp/s.png
mobai tap "Sign in"
For a known sequence, one call instead of many, with per step results:
mobai dsl '{"version":"0.2","steps":[
{"action":"open_app","bundle_id":"com.example.app"},
{"action":"tap","predicate":{"text":"Sign in"}},
{"action":"assert","predicate":{"text_contains":"Welcome"}}
]}'
The full HTTP API is on http://127.0.0.1:8686/api/v1
as well. See the CLI reference
and the API and DSL docs.
Limits
- Pro required. Cloud device access is a Pro feature, checked server side when a session starts.
- Session length. A session runs for a bounded time and then exits. Pro gets a long window; free accounts get a short one and only one per day.
- iOS 17 or later. Older devices cannot be reached this way.
- The phone has to be awake and on the tailnet. A sleeping phone shows up as no devices rather than an error.
- One session at a time is the sane case. Two sandboxes driving the same phone will fight over it.
Troubleshooting
The agent says there are no devices
Almost always the phone. Wake it, confirm Tailscale is connected on it, and confirm it is signed into the same account the agent joined with. An empty list is the normal way an unreachable phone appears.
Setup script fails saying a variable is not set
On Claude Code this is expected, and you should be using its own script, which needs no variables. On Codex and Cursor, check the values are in the secrets store rather than the plain environment variables field.
Downloads fail partway through
The sandbox filters outbound traffic. Paste every host from the wizard's allowed hosts list, including the content delivery hosts, since a release download redirects to one.
The app will not install on the phone
The build was unsigned, or the provisioning profile does not list that device. Run
builder signing setup
and register the phone's UDID in the Apple developer portal.
It worked yesterday and now it does not
If you signed with a free Apple ID, MobAI's setup on the device expired after seven days. Connect the phone and run step 2 of the wizard again.
What is shared
For each device you onboard we store its name, version and an encrypted record that lets your sessions connect to it.
Device traffic does not pass through us. It goes directly between the sandbox and your device across your own tailnet.
Remove a device any time from the cloud setup wizard. Everything stored for it is deleted.