Mobile MCP
Drives iOS and Android simulators, emulators and real devices from an assistant
Drives and inspects iOS simulators on a Mac: taps, typing, screenshots, video and app installs
By Joshua Yoes (individual) TypeScript Local · stdio TestingDeveloper tools
79 popularity score ★ 2.2k ↓ 11k/wk
Opens the app, which asks before it adds the server.
claude mcp add ios-simulator -- npx -y ios-simulator-mcp{
"mcpServers": {
"ios-simulator": {
"command": "npx",
"args": [
"-y",
"ios-simulator-mcp"
]
}
}
}{
"mcpServers": {
"ios-simulator": {
"command": "npx",
"args": [
"-y",
"ios-simulator-mcp"
]
}
}
}{
"servers": {
"ios-simulator": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"ios-simulator-mcp"
]
}
}
}[mcp_servers.ios-simulator]
command = "npx"
args = ["-y", "ios-simulator-mcp"]gemini mcp add --scope user ios-simulator npx -- -y ios-simulator-mcpOpens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.
git clone https://github.com/joshuayoes/ios-simulator-mcp
cd ios-simulator-mcp
npm install
npm run buildclaude mcp add ios-simulator -- node '<ABSOLUTE_PATH_TO_CLONE>/build/index.js'{
"mcpServers": {
"ios-simulator": {
"command": "node",
"args": [
"<ABSOLUTE_PATH_TO_CLONE>/build/index.js"
]
}
}
}{
"mcpServers": {
"ios-simulator": {
"command": "node",
"args": [
"<ABSOLUTE_PATH_TO_CLONE>/build/index.js"
]
}
}
}{
"servers": {
"ios-simulator": {
"type": "stdio",
"command": "node",
"args": [
"<ABSOLUTE_PATH_TO_CLONE>/build/index.js"
]
}
}
}[mcp_servers.ios-simulator]
command = "node"
args = ["<ABSOLUTE_PATH_TO_CLONE>/build/index.js"]gemini mcp add --scope user ios-simulator node -- '<ABSOLUTE_PATH_TO_CLONE>/build/index.js'IOS_SIMULATOR_MCP_FILTERED_TOOLS |
Optional: Comma-separated tool names to leave unregistered. |
|---|---|
IOS_SIMULATOR_MCP_DEFAULT_OUTPUT_DIR |
Optional: Folder for screenshots and videos given a relative or no path. |
IOS_SIMULATOR_MCP_IDB_PATH |
Optional: Path to the idb executable when it is not on PATH. The server errors if the path does not exist. |
iOS Simulator MCP Server gives an assistant hands and eyes on an iOS simulator running on the developer's own Mac. It can find the booted simulator, open the Simulator app, read the accessibility tree of the whole screen or of one point, search that tree for elements by label or id, and act on the screen with taps, swipes and typed text. Text can also be pasted through the simulator clipboard, which is the mode to pick for non-US keyboard layouts or non-ASCII text.
It also captures what is on screen: a compressed image returned straight to the assistant, a screenshot saved to disk in several formats, or a video recording that can be started and stopped. App-level tools install a .app or .ipa bundle, list installed apps with their bundle ids, launch or terminate an app (optionally passing environment variables to it), and open web URLs, custom schemes or universal links.
The typical use is a quick QA pass after building a feature: the assistant opens the screen under test, checks labels and layout, interacts with it and records the result. Under the hood it calls Apple's simctl and Facebook's IDB command-line tools. Note that stop_recording takes no arguments and sends SIGINT to every process matching simctl recordVideo, so it also ends recordings started outside the server.
| Runtime | Node.js 20+ |
|---|---|
| Runs on | macOS |
| Also |
|
Install IDB as the repository's TROUBLESHOOTING.md describes: idb_companion through Homebrew and the fb-idb client (for example `uv tool install --python 3.12 fb-idb@latest`). If idb is not on PATH, give its location in IOS_SIMULATOR_MCP_IDB_PATH. Paste mode fails on idb_companion 1.1.8, which lacks the axbridge reader. Run `brew upgrade idb-companion` and then `idb kill`. No account or sign-in.
Works only on macOS, since iOS simulators exist only there; it does not reach physical iPhones or Android emulators. Typed text is limited to printable ASCII characters. Taps and swipes take screen coordinates, so the assistant must first read the accessibility tree or a screenshot. Versions before 1.3.3 had command-injection flaws; its makers ask users to run 1.3.3 or later.
Suits iOS and React Native developers on a Mac who want an assistant to check its own UI work in the simulator: reading accessibility labels, tapping through flows, testing deep links and keeping screenshots or videos as evidence. It runs entirely locally and needs no account. Testers on non-US keyboard layouts should use the paste mode of ui_type, which needs an up-to-date IDB. It is not for Windows or Linux users, for real devices, or for Android. Teams that only need code or build help rather than on-screen checks need none of this.
6 only read, 11 change things. A ? marks an optional parameter.
get_booted_sim_idopen_simulator changesui_describe_alludid?: stringui_tap changesx: numbery: numberduration?: stringudid?: stringui_type changestext: stringmethod?: enumreplace?: booleanudid?: stringui_swipe changesx_start: numbery_start: numberx_end: numbery_end: numberduration?: stringdelta?: numberudid?: stringui_describe_pointx: numbery: numberudid?: stringui_find_elementsearch: arraytype?: stringmatchMode?: enumcaseSensitive?: booleanudid?: stringui_viewudid?: stringscreenshot changesoutput_path: stringtype?: enumdisplay?: enummask?: enumudid?: stringrecord_video changesoutput_path?: stringcodec?: enumdisplay?: enummask?: enumforce?: booleanudid?: stringstop_recording changesinstall_app changesapp_path: stringudid?: stringlaunch_app changesbundle_id: stringterminate_running?: booleanenv?: objectudid?: stringterminate_app changesbundle_id: stringudid?: stringopen_url changesurl: stringudid?: stringlist_appsudid?: string