← Blog

Claude Code iOS Simulator on Windows, Linux or the web

Claude Code's iOS Simulator pane needs a Mac and works only in local sessions. On Windows, Linux, the web or over SSH, give Claude a cloud iPhone Simulator over MCP, ready in seconds.

· 8 min read

Need an iPhone for this? NoMac Simulator gives your agent a cloud iPhone in seconds for $0.90 an hour, billed per minute. See NoMac Simulator →


Claude Code Desktop on macOS can open your app in an iOS Simulator pane next to the conversation, let you watch Claude tap through it, and let you tap it yourself. MacRumors covered the public beta on July 21, 2026. If you run Claude Code anywhere else, Anthropic's own documentation sets two limits:

“A Mac, since Apple's iOS Simulator runs only on macOS”
Requirements
“The simulator pane is available in local sessions only. In cloud and SSH sessions, Claude runs on a machine that can't reach the simulators on your Mac.”
Test iOS apps in the simulator

Both are from Anthropic's iOS Simulator page. The same page says the CLI reaches the Simulator through computer use, which controls the Simulator on your Mac's screen. So on Windows, on Linux, in Claude Code on the web and in an SSH session, Claude has no Simulator to drive.

What works from anywhere is a Simulator that Claude reaches over the network. This guide connects Claude Code to a NoMac phone: an iPhone Simulator on a cloud Mac with Xcode, which Claude drives with MCP tools while you watch through a link.

What you get: an iPhone 17 Pro Simulator on iOS 27, ready in about 4 seconds, with Xcode 27.1 on the same Mac building your app. $0.90 an hour, billed per minute from prepaid credit, with no subscription. A Simulator build needs no Apple Developer account.

Connect Claude Code

In a terminal: Windows, Linux or WSL

Run these where you use Claude Code. The first signs you in through a browser approval. The second registers NoMac's MCP server, which runs from the NoMac CLI on your machine and needs Node 20 or newer.

npx @nomac/cli login
claude mcp add nomac -- npx @nomac/cli mcp

Run /mcp in Claude Code to check that nomac is connected. It lists the Mac tools and the phone tools: phone, phone_app_run, phone_ui_look, phone_ui_act, phone_app_logs, phone_tests_run and a few more. Because this server runs on your machine, phone_app_run takes local_path: the project folder, sent in the same call, only the files the phone does not have yet.

To install nothing, add the hosted server instead and sign in when /mcp asks, the OAuth flow in Anthropic's MCP documentation:

claude mcp add --transport http nomac https://mcp.nomac.app/mcp

The hosted tools are the same, without local_path. A folder on your machine reaches the phone through phone_upload_link, which answers one shell command that packs the folder and sends it. That command needs a POSIX shell: Linux, WSL, macOS, or Git Bash on Windows, which Claude Code uses for its Bash tool when Git for Windows is installed.

Claude Code on the web, the desktop app and SSH sessions

A server added with claude mcp add is stored on your machine, so a cloud session never sees it. Anthropic's cloud environments page says so and points to a committed .mcp.json instead. The simpler route is a claude.ai connector: add NoMac to your claude.ai account once, in one click from its Claude directory listing, or under Settings, Connectors, Add custom connector, with https://mcp.nomac.app/mcp. On Team and Enterprise plans an admin adds it.

Anthropic's MCP documentation says how connectors reach each kind of session: the cloud host passes them into cloud sessions, the desktop app delivers them to its local and SSH sessions, and the terminal fetches them when you sign in with a claude.ai account. Connector traffic travels through Anthropic's servers, so a cloud environment does not need NoMac on its list of allowed domains.

In an SSH session Claude runs on the remote machine, so the project is sent from there, where its files already are.

Run your app on a phone

You don't call the tools yourself. Ask for the result, and Claude picks them:

Start a NoMac phone and give me its view link. Build and run the
app in this repository on it (the Xcode project is in ios/). Read
the first screen, sign in with the test account in TESTING.md and
tell me what the home screen shows. Stop the phone when you are done.

1. Start a phone

phone with action start answers once the phone is ready, usually in about 4 seconds. When every phone is in use, the start waits in line for up to 5 minutes, and the wait is free. Its answer carries links.view, a page that shows the phone live in any browser with no sign-in, and links.control, which also lets you use it. Both work for 2 hours by default, or until the phone stops.

2. Build and run

phone_app_run builds the Xcode project for the Simulator, installs it, launches it and answers with the first screen as text. The project comes from one of three places:

  • ·git: an https link to the repository, with path for a project in a subfolder and ref for a branch, tag or commit. For a private repository on GitHub, GitLab or Bitbucket, secret names a NoMac secret that holds a token. request_secret gives you a link to enter it, so the token never goes through the chat.
  • ·local_path, with the CLI's server: a folder on the machine where Claude Code runs.
  • ·upload, with the hosted server: what the command from phone_upload_link sent. It leaves out build output, dependencies, version control and key files.

Build errors come back as file:line, so Claude fixes them as it would on a Mac. A build that runs past 40 seconds answers with a job, which phone_job_status waits for. A CocoaPods project gets pod install first when its pods differ from Podfile.lock, and an XcodeGen project is generated from project.yml. The project and its build cache stay in your account's workspace between phones, so later builds are incremental: after a one-line change, a rebuild and run takes about 7 seconds.

In Claude Code on the web, the session works on a clone of your GitHub repository. Push the branch and pass it as ref, or send the session's working tree with the upload command. The upload goes to *.r2.cloudflarestorage.com, which is on the default list of Anthropic's Trusted network level.

3. Watch it

Open the view link while Claude works. You see the phone as it is, not a screenshot Claude chose to show you. The control link lets you take over: one person holds input at a time, and a tap you make changes what Claude reads next. After the phone stops, links.replay shows the session as a video beside every tool call, with typed text left out, for 7 days.

Read the screen as text, tap by label

With screenshots alone, an agent looks at a picture, guesses a coordinate, taps, and takes another picture to see what happened. phone_ui_look reads the screen's accessibility tree instead and answers one line per element:

Demo · Sign In · iPhone 17 Pro (iOS 27.0)
textfield "Email" #email @201,194
securefield "Password" #password @201,246
switch "Remember me" #remember off @341,298
button "Sign In" #signIn @201,350
text "Not signed in" #status @201,402
tabs: Login (selected) @158,822, Items @244,822

Each line has the kind, the label, #id (the app's accessibility identifier), the state and the center in points. A sign-in screen like this one is about 70 tokens. phone_ui_act takes steps in the same words and answers with what changed:

steps: ["fill #email test@example.com", "fill #password secret1", "tap #signIn", "wait \"Welcome\""]

4 steps done in 4.5 s
changed: #email "test@example.com" · #password "•••••••" · #status "Welcome, test@example.com"

A tap that changes nothing is reported, and the first step that fails stops the rest, so Claude does not type a password into the wrong field, and a label still finds a button after the layout moves it. When Claude needs pixels, for a layout or a color, screenshot adds a JPEG sized to points, so a point in the picture is a point to tap, and screenshot_file saves the full-size PNG as a download link. A web view with nothing for accessibility to read comes back as one unreadable line, and there Claude falls back to a screenshot and taps by point.

Give your controls accessibility identifiers: they appear as #id, and Claude taps them by name. To skip tapping altogether, phone_app_control with action open_url opens a deep link, and launch with a value such as -Onboarding 3 passes launch arguments, read as UserDefaults, which open a screen directly if your app reads them. The same tool grants permissions, sets the locale, appearance and location, and sends a push.

Logs and tests

  • ·phone_app_logs: what the app printed and logged since launch. grep filters, wait_for waits up to 25 seconds for a line, and crashes lists crash reports with the crashing thread.
  • ·phone_tests_run: XCTest and XCUITest, read from Xcode's result bundle, with the counts and each failure as file:line. only picks tests, such as AppTests/SignInTests. “0 tests ran” is reported as an error, not a pass.
  • ·phone_screen_record: start, then stop for an MP4 you can watch or attach to a bug report.
Run the unit and UI tests on the phone. For each failure, read the
app's logs around it, fix the cause, and run only the failing tests
again until they pass.

Outside Claude Code, the free, MIT-licensed simulator-use CLI runs the same tools from any terminal. In CI, one line starts a phone, builds, runs and tests the project, saves a screenshot and a recording, and stops the phone. It signs in with NOMAC_API_KEY there.

npx simulator-use cloud run . --tests

What it costs

A phone costs $0.90 an hour, billed per minute from prepaid credit, with a one-minute minimum. The build is included, and waiting in line is free. A 12-minute session costs 18¢. Credit comes in $10 packs, each 11.1 hours of phone time, and never expires. There is no subscription.

A phone stops after 10 minutes without a tool call or input through its control link (watching does not count), and at 2 hours by default. phone with action extend adds time, up to 8 hours in all, and action status shows the cost so far. An account runs up to 2 phones at once.

What it cannot do

  • ·No physical device. A phone is Apple's Simulator, and Apple says simulators “don't replicate the performance or features of a physical device.” For anything that needs hardware, install a TestFlight build on your own iPhone: see testing an iOS app without a Mac.
  • ·No App Store sandbox purchases. They cannot be bought in a Simulator. StoreKit Testing can: phone_app_control with action storekit and your project's .storekit file makes purchases local, with no Apple Account.
  • ·Flutter, React Native, Expo and Capacitor need a .app built elsewhere. phone_app_run builds Xcode projects. For these, build the Simulator .app with the framework's own tools on a Mac, then install it with phone_app_control action install, from local_path or an upload of the zipped .app. A NoMac Mac can do that build: see Flutter and React Native.
  • ·No shell, signing or TestFlight. A phone runs only its own tools. For a shell, a debugger, code signing and TestFlight, use a NoMac Mac: start_mac is on the same server, and set_up_signing and send_to_testflight are on NoMac App Store, https://mcp.nomac.app/appstore, with the same account. Claude Code and an iOS app without a Mac walks through that path.

Tell Claude once, in CLAUDE.md

## iOS Simulator
- This machine has no iOS Simulator. Use the NoMac phone tools.
- Start one phone per task and give me links.view first.
- Read the screen with phone_ui_look before acting; tap by #id or
  label, not by coordinates.
- Run phone_tests_run before saying a change works.
- Stop the phone (phone, action stop) when you are done.

If you would rather run Claude next to the Simulator on a whole Mac, over SSH, see Claude Code on a cloud Mac.

Give your agent an iPhone in seconds.

A cloud iPhone Simulator that builds your Xcode project, reads the screen as text and taps by label, over MCP. You watch it in a browser tab. $0.90 an hour, billed per minute from prepaid credit, with no subscription.

Get started from $10

7-day money-back guarantee on your first purchase. Credit never expires.

Connect your agent →