ios-sim-mcp
Drives iOS Simulators on macOS, enabling AI agents to list booted simulators, launch and terminate apps, tap, type, swipe, read the on-screen UI element tree, take screenshots, and control orientation via xcrun simctl and WebDriverAgent.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ios-sim-mcplaunch Safari on the booted iOS simulator and take a screenshot"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ios-sim-mcp
A Model Context Protocol (MCP) server that lets AI agents (Claude, Windsurf, Cursor, etc.) drive iOS Simulators on macOS — listing devices, launching apps, tapping, typing, swiping, reading the on-screen UI tree and taking screenshots.
The package is published as ios-sim-mcp and exposes the ios-sim-mcp binary. It talks to the simulator through two channels:
xcrun simctl— app launch/terminate, installed-app listing, screenshotsWebDriverAgent (on
localhost:8100) — taps, swipes, key input, hardware buttons, orientation, UI element tree, opening URLs
Table of contents
Related MCP server: Simulator MCP
Architecture
┌──────────────┐ stdio (MCP) ┌──────────────────────┐
│ MCP client │──────────────▶│ src/index.js │
│ (Claude etc.)│◀──────────────│ src/server.js │ tool registry
└──────────────┘ └─────────┬────────────┘
│ Robot interface (src/robot.js)
▼
┌──────────────────────┐
│ src/iphone-simulator │ Simctl / SimctlManager
└───┬──────────────┬───┘
xcrun simctl │ │ HTTP (W3C WebDriver)
▼ ▼
┌──────────────┐ ┌───────────────────────┐
│ iOS Simulator│◀─│ WebDriverAgent :8100 │
└──────────────┘ └───────────────────────┘src/index.jsstarts the MCP server over a stdio transport.src/server.jsregisters every tool and holds the currently selected device ("robot").src/robot.jsdocuments the Robot interface every device controller implements, plus shared constants (ORIENTATIONS,BUTTONS,SWIPE_DIRECTIONS) andActionableError.src/iphone-simulator.jsimplements the Robot interface for iOS Simulators (Simctl) and discovers simulators (SimctlManager).src/webdriver-agent.jsis a small WebDriverAgent HTTP client. Each call opens a WDA session, runs the request and deletes the session.src/png.js/src/image-utils.jsvalidate PNG screenshots and optionally downscale/convert them via ImageMagick.
For detailed diagrams, API contracts (MCP, WebDriverAgent HTTP, simctl), connection types and request flows, see ARCHITECTURE.md.
Requirements
Requirement | Notes |
macOS | Simulator discovery returns nothing on other platforms. |
Xcode + Command Line Tools | Provides |
Node.js ≥ 18 | Uses the built-in |
WebDriverAgent | Must be running on the simulator, reachable at |
ImageMagick 7 (optional) | If |
Installation
git clone https://code.devsnc.com/harish-dewangan/ios-sim-mcp.git
cd ios-sim-mcp
npm installBoot a simulator (via Xcode → Open Developer Tool → Simulator, or):
xcrun simctl list devices # find a device UDID
xcrun simctl boot <UDID>
open -a SimulatorRunning WebDriverAgent
Most tools (everything except app listing/launch/terminate and screenshots) need WebDriverAgent. One way to run it on a booted simulator:
git clone https://github.com/appium/WebDriverAgent.git
cd WebDriverAgent
xcodebuild -project WebDriverAgent.xcodeproj \
-scheme WebDriverAgentRunner \
-destination "platform=iOS Simulator,id=<UDID>" \
testVerify it is up:
curl http://localhost:8100/statusThe host and port (localhost:8100) are hard-coded in src/iphone-simulator.js (WDA_PORT).
Configuring an MCP client
The server speaks MCP over stdio. Point your client at src/index.js:
{
"mcpServers": {
"ios-sim-mcp": {
"command": "node",
"args": ["/absolute/path/to/ios-sim-mcp/src/index.js"]
}
}
}Claude Desktop:
~/Library/Application Support/Claude/claude_desktop_config.jsonClaude Code:
claude mcp add ios-sim-mcp -- node /absolute/path/to/ios-sim-mcp/src/index.jsWindsurf / Cursor: add the same block to the editor's MCP config.
To run it standalone (e.g. for debugging with the MCP Inspector):
npm start
# or
npx @modelcontextprotocol/inspector node src/index.jsAvailable tools
Tool | Parameters | Description |
|
| Lists booted iOS simulators by name. |
|
| Selects the simulator for all later calls. Pass the simulator UDID (see limitations). |
| — | Lists installed apps as |
|
| Launches an app by bundle id ( |
|
| Terminates an app by bundle id. |
| — | Returns screen size in points via WDA. |
|
| Taps at the given coordinates. |
| — | Returns visible UI elements (TextField, Button, Switch, Icon, SearchField, StaticText, Image, WebView…) with rect, label/name and WDA attributes. |
|
|
|
|
| Opens a URL on the device via WDA. |
|
| Vertical swipe between y=200 and y=600 at x=200. |
|
| Types into the focused element; presses Enter if |
| — | Returns the screenshot as an image and saves a copy to disk (see |
|
| Rotates the device. |
| — | Returns the current orientation. |
All tools except mobile_list_available_devices and mobile_use_device require a device to be selected first.
Typical agent workflow
mobile_list_available_devices— see what's booted.mobile_use_device— select a simulator (by UDID).mobile_launch_app— e.g.com.apple.mobilesafari.mobile_list_elements_on_screenand/ormobile_take_screenshot— understand the UI.mobile_click_on_screen_at_coordinates/mobile_type_keys/swipe_on_screen— interact.Repeat 4–5, then
mobile_terminate_app.
Example prompt to an agent:
Open Safari on the booted iPhone simulator, go to example.com and take a screenshot.
Project structure
.
├── src/
│ ├── index.js # Entry point: MCP server over stdio
│ ├── server.js # Tool definitions and device selection
│ ├── robot.js # Robot interface docs, constants, ActionableError
│ ├── iphone-simulator.js # Simctl (Robot impl) + SimctlManager (discovery)
│ ├── webdriver-agent.js # WebDriverAgent HTTP client
│ ├── png.js # PNG signature / dimension parsing
│ └── image-utils.js # ImageMagick-based resize / JPEG conversion
├── examples/ # (currently empty)
├── package.json
├── LICENSE
├── ARCHITECTURE.md
└── README.mdnpm scripts
Script | Command | Notes |
|
| Runs the MCP server on stdio. |
|
| No ESLint config file is present in the repo yet. |
|
| No |
|
| |
|
| Runs on |
Error handling
Tools are wrapped so that:
An
ActionableError(e.g. "No device selected", "WebDriverAgent is not running on simulator", unsupported button) is returned as plain text ending in "Please fix the issue and try again." so the agent can self-correct.Any other exception is returned with
isError: trueand the messageError: <message>.
Known limitations
These reflect the current code and are worth knowing before relying on the server:
iOS Simulator only. No Android or physical iOS device support;
deviceTypeonly accepts"simulator".Device name vs. UDID.
mobile_list_available_devicesreturns simulator names, butmobile_use_devicepasses its argument straight toxcrun simctlas the device identifier. Supply the UDID (fromxcrun simctl list devices);bootedmay also work when a single simulator is running.Hard-coded screenshot directory.
OUTPUT_DIRinsrc/server.jsis set to/Users/harish.dewangan/Documents/ios-demo/. Change it for your machine. Files are always saved with a.pngextension, even when ImageMagick has converted them to JPEG.stdout logging. Several tools use
console.log, which writes to stdout — the same stream the stdio MCP transport uses. Some clients may report protocol/parse errors because of this; switching those calls toconsole.erroravoids it.mobile_list_appsparsing. The regexes inSimctl.parseIOSAppDatause\\sinside regex literals, which matches a literal backslash rather than whitespace, so app listing may return an empty list.Swipe supports only
up/downwith fixed coordinates, regardless of screen size.WebDriverAgent location is fixed at
localhost:8100, and a new WDA session is created per call (slower, but stateless).zodis imported bysrc/server.jsbut not declared inpackage.json; it currently resolves as a transitive dependency of@modelcontextprotocol/sdk.
License
MIT © 2026 harishdk522
This server cannot be deployed
Maintenance
Related MCP Connectors
Control real Android and iOS devices with LLM agents — tap, swipe, type, automate flows.
Cloud Macs with Xcode for AI agents: run commands, build and test iOS apps, see and use the screen.
Build, run, and inspect iOS apps in disposable hosted Simulators from cloud coding agents.
Drive real devices from your AI Coding tool. Embed a client SDK (Unity, Godot, Flutter, iOS/macOS, Android, React Native, Web) in your app, then capture screenshots, traverse the UI tree, inject taps and key events, and run automated test tasks on the physical device over a secure relay.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to automate iOS Simulator interactions including device management, UI element interaction (tap, swipe, type), screenshot capture, and execution of YAML-defined navigation workflows.26 npmMIT
- FlicenseNot gradedqualityDmaintenanceEnables AI to control iOS simulators through the MCP protocol. Supports device management, UI automation, and network interception including screenshot capture, text input, and HTTP request mocking.-
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to control real iPhones and simulators on macOS, allowing for UI interaction, testing, and automation.33 npm92MIT
- FlicenseNot gradedqualityCmaintenanceEnables AI agents to control iOS Simulators for UI/UX debugging, app management, and accessibility auditing via simctl, IDB, and ClaudeDebugKit.-