MCP.Market

Ios Sim MCP server

by rmathew1973·io.github.rmathew1973/ios-sim-mcp·v0.4.2

Drive the iOS Simulator via semantic accessibility-tree snapshots. Sub-200ms, no WebDriverAgent.

A88/100grade A
What users say
No reviews yet
Be the first
Safety scan
A88/100

full report

Adoption
New

0 stars32 downloads/wk

Reviews

Write one

Nobody has reviewed Ios Sim yet.

If you have run it, two minutes of your experience saves the next person an afternoon.

Ios Sim tools (40, 5 write)

write = sends, deletes, buys or posts

Read from the package source without running it. The installed server may list more.

  • await_quiescent

    Block until the accessibility tree stops changing (UI settles). Returns when the tree hash is identical for 'stable_ms' (default 250) consecutive ms, or 'timeout_ms' elapses (default 5000). Use after launch_app, navigation, or async loads instead of sleep.

  • button

    Press a hardware button: HOME, LOCK, SIDE_BUTTON, SIRI, APPLE_PAY.

  • dylib_call

    Generic escape hatch: invoke an arbitrary method on the Layer 2 dylib. Use dylib_info first to see available methods. Passes 'params' through verbatim. Future phases (2c view_tree, 2d network_*, 2e eval_js) add methods this can reach.

  • dylib_health

    Lightweight liveness probe for the Layer 2 dylib. Returns {available, ...stats} when reachable, {available: false, reason} when not. Does NOT throw — safe to call as a feature-detection precheck before reaching for dylib-only tools. Stats include: bundle_id, pid, uptime_s, phase, whether network capture is running, record/stub counts, JS context status, method count.

  • dylib_info

    Ask the Layer 2 dylib to describe its host process: pid, bundle id, process name, bundle path, uptime, and the list of RPC methods it exposes.

  • dylib_ping

    Round-trip a ping to the Layer 2 dylib inside an injected app. Returns the response plus measured RTT in ms. Use this first to verify the dylib is loaded and reachable.

  • eval_jswrite action

    Run arbitrary JavaScript inside the injected app via JavaScriptCore. Bridged globals: `app` (UIApplication), `key_window()`, `all_windows()`, `defaults` (NSUserDefaults), `pasteboard` (UIPasteboard), `bundle`, `process`, `notif_center`, `first_responder()`, `find_view_by_ax_id(id)`, `find_view_by_class(name)`, `find_vc_by_class(name)`, `post_notification(name, userInfo?)`, `cls(name)` (NSClassFrom

  • eval_js_resetwrite action

    Drop the persistent JSContext inside the injected app. Variables and helper functions you defined via eval_js are forgotten; bridged globals are reinstalled on the next eval_js call.

  • find

    Search the most recent snapshot for elements. Combine fields with AND. 'id' matches AXUniqueId exactly. 'label' is exact match; 'labelContains' is case-insensitive substring across label/value/title. 'role' accepts 'Button', 'TextField' etc (with or without AX prefix). Auto-snapshots if none cached.

  • key

    Press a single key. Pass either {name} (RETURN, ESCAPE, DELETE, TAB, SPACE, F1-F12, UP/DOWN/LEFT/RIGHT) or {code} (raw HID usage code).

  • launch_app

    Launch an app by bundle id (com.example.App). 'foreground_if_running' terminates first. 'inject' loads the Layer 2 dylib (default path: dylib/build/libios-sim-mcp.dylib relative to the server) via SIMCTL_CHILD_DYLD_INSERT_LIBRARIES — currently just emits a lifecycle log line; future phases add a Unix socket. 'inject_dylib' overrides the dylib path. Inject requires the dylib to be built (run dylib/

  • list_simulators

    List iOS simulators (booted and shutdown). Returns udid, name, state, os_version.

  • log_clear

    Clear the in-memory log buffer.

  • log_start

    Start streaming os_log from the simulator into an in-memory buffer (5000 lines max). Optional bundle_id filters by subsystem substring. Level: default|info|debug.

  • log_stop

    Stop the log stream subprocess. Buffer is preserved until log_clear or log_start.

  • log_tail

    Return the last N lines from the log buffer (default 100). Requires log_start first.

  • network_clearwrite action

    Drop all captured records and their bodies. Does not change running state.

  • network_get_body

    Fetch the full request or response body for a captured record. Bodies up to max_body_bytes (default 256KB) are retained per record; larger bodies were truncated at capture time and the response will mark truncated=true. Returns base64 plus a UTF-8 decode when the body is text.

  • network_self_test

    Fire a real HTTP request from inside the injected app to validate the capture path end-to-end. Useful when the host app makes no network calls of its own during a smoke test. Requires network_start first.

  • network_start

    Start capturing HTTP traffic from the injected app's URLSession-based code. Installs an URLProtocol subclass + swizzles +defaultSessionConfiguration / +ephemeralSessionConfiguration so requests made via Alamofire, URLRequest, SwiftUI AsyncImage, or any URLSession-based client are recorded into an in-process ring buffer. Existing URLSessions constructed before start are NOT retro-fitted. Requires d

  • network_status

    Report whether capture is running, how many records are held, and current config (max_records, max_body_bytes, filter).

  • network_stop

    Stop capturing HTTP traffic. The ring buffer is preserved until network_clear; you can keep calling network_tail on captured records after stopping.

  • network_stub

    Register an HTTP stub. When an outgoing request's URL contains `url_substring` (and matches `method` if given), the dylib synthesizes a canned response (status, headers, body) instead of forwarding. Stubbed requests still appear in network_tail with `stubbed:true` and `stub_id`. First-match-wins by insertion order. `body` is a UTF-8 string; pass `body_base64` for binary. `delay_ms` simulates slow

  • network_stubs

    List currently registered HTTP stubs (id, url_substring, method filter, status, body preview, delay, when added). Raw body bytes are not returned — call network_get_body on a captured record if you need the actual body delivered.

  • network_tail

    Return the most recent N captured records (default 50). Each record shows id, method, status, timing, sizes, URL. Pass full=true to include headers + body previews inline; otherwise call network_get_body({id}) to fetch a specific full body. Use since_id to page forward from a previous tail.

  • network_unstubwrite action

    Remove a single HTTP stub by id (as returned from network_stub / network_stubs).

  • network_unstub_allwrite action

    Remove all HTTP stubs.

  • paste_text

    Byte-perfect text input via UIPasteboard + first-responder paste:. Requires the Layer 2 dylib injected and a text field already focused (call tap first). No iOS autocorrect, no capitalization, no smart-quote replacement — what you pass is exactly what the field receives. Use for emails, passwords, OAuth tokens, anything case-sensitive.

  • screenshot

    Capture a screenshot. If 'path' is provided, saves PNG and returns the path. Otherwise saves to a temp file and returns both the path and the image inline. Use sparingly — the AX tree is faster and richer for control flow.

  • scroll

    Scroll a scrollable view. Direction is reader-perspective: 'down' reveals content below (finger drags up); 'up' reveals content above. Optional 'ref' or 'id' to anchor the gesture on a specific scrollable; otherwise uses screen center. 'distance' px (default 300). Default 0.4s duration ensures iOS treats it as a pan, not a tap.

  • snapshot

    Capture the simulator's accessibility tree and return it with stable refs (e1, e2, ...). Subsequent tap/type/swipe accept refs. Default filter 'interactive' hides decorative containers; use 'all' for everything, 'actionable' for only tappable controls. Always call this before acting on UI.

  • swipe

    Swipe from one point to another. Pass from_ref/from_id or from_x+from_y AND to_ref/to_id or to_x+to_y. Optional duration (seconds) and delta (px step).

  • tap

    Tap an element. Pass one of: {ref} from latest snapshot, {id} for AXUniqueId, or {x,y} for raw coordinates. Optional 'duration' (seconds) makes it a long-press.

  • terminate_app

    Terminate an app by bundle id.

  • type_text

    Type text into the focused field. Pass ref/id to tap a field first. Newlines/tabs aren't interpreted — use the key tool for RETURN/TAB. via='paste' (default 'auto') routes through the Layer 2 dylib's UIPasteboard so input arrives byte-perfect: no iOS autocorrect, no first-letter capitalization, no shifted-symbol translation — critical for emails, passwords, anything case-sensitive. 'auto' uses pas

  • use_simulator

    Select a specific simulator by UDID for subsequent calls. If only one is booted, auto-selection happens on first action — you only need this when multiple are booted.

  • view_get_text

    Look up a view by AXUniqueId or class name and return its text content (UILabel.text / UIButton.currentTitle / UITextField.text / UITextView.text), plus accessibility label/value as fallback context. Faster than view_tree when you just need 'what does this control say right now?'. Requires the dylib injected.

  • view_hit_test

    Ask the running app what view sits topmost at (x,y) in window coords, plus the full responder chain up to UIApplication. The right tool for 'tap at (201,406) isn't doing what I expect' — you see exactly which view receives the hit, whether it's userInteractionEnabled, and what view controllers are in the chain. Requires the dylib injected.

  • view_set_text

    Set the text on a UILabel / UITextField / UITextView / any view that responds to setText:. Bypasses focus + keyboard entirely. Use to seed test data directly into a non-focused field, or to programmatically change a label's text mid-test. Requires the dylib injected.

  • view_tree

    Walk the running app's UIView hierarchy on the main thread and return a compact text rendering. Strictly richer than snapshot: catches custom-drawn views, transient overlays, things SwiftUI synthesizes that AX flattens; reports actual class names (UIButton vs _UIRoundedRectButton), exact frames in window coords, alpha/hidden/userInteractionEnabled, and annotates which views are a UIViewController'

Public scan report

scanner v0.1.9 · 2026-09-27 · same rubric, same numbers if you re-run it

no findings
  • Code scan11 source files scanned25/25
  • –Live reliabilityno gateway calls yet and no remote to proben/a
  • –Tool poisoningtools not inspected (local package is not executed); not countedn/a
  • Auth qualitylocal package, no credentials required12/15
  • Maintenancelast push 56 days ago12/15
  • Maintainer identityregistry namespace matches repository owner; GitHub account older than a year8/10
Overall 88/100. Components that don't apply are left out of the denominator. Any critical finding is an F.RubricAppeal a findingJSON

How Ios Sim compares

Against every graded Productivity MCP server, from our own scans and uptime checks. Updated after each scan run.

Safety score
88/100
higher than 75% of 1,297 Productivity servers
Tools
40
the typical Productivity server has 7
Tools that change things
13%
typical: 0%. Fewer write tools means less an agent can break
Downloads a week
32
more than 17% of 423 Productivity servers with a package

What its tools let an agent do: 35 read · 3 change · 2 run or deploy

Install Ios Sim in Claude Code, Cursor or VS Code

Runs npx -y ios-sim-mcp on your machine. Read the scan report first; the gateway never runs local packages.

claude mcp add ios-sim-mcp -- npx -y ios-sim-mcp
Add to Cursor

What the publisher says

From the Ios Sim repository's README, as published. We do not edit it. Read it on GitHub

ios-sim-mcp

An MCP server that drives the iOS Simulator the way Chrome's DevTools MCP drives a browser: semantic accessibility-tree snapshots with stable element refs, sub-200ms operations, and no screenshot-and-eyeball-coordinates loops.

Built because every existing iOS-simulator automation tool either crawls (Appium, screenshot-based agents) or requires pre-written scripts. This one lets an LLM drive a simulator interactively — find an element by label or ID, tap it by ref, wait for the UI to settle, repeat — at roughly the speed a human would.

Why this exists

Most existing iOS-sim MCPs work by taking a screenshot, asking the model to identify coordinates, then tapping pixels. That's slow (image bytes in context), expensive (vision tokens), and fragile (any layout shift breaks it).

iOS apps already expose a structured accessibility tree — the same one VoiceOver uses. If you query that tree, you get every interactive element with its label, role, AX identifier, frame, and enabled state. You can find what you want semantically, refer to it by a stable ref, and act on it directly. That's what Chrome MCP does for the DOM, and it's what this does for UIView hierarchies in the iOS Simulator.

How it works

Three layers, two shipping today:

idb talks directly to CoreSimulator's private framework — no WebDriverAgent, no HTTP hop into the simulator process — which is why the per-call latency is closer to a local subprocess than to a network round trip.

Requirements

  • macOS with Xcode + iOS Simulator
  • idb (brew tap facebook/fb && brew install idb-companion && pipx install fb-idb)
  • Bun (curl -fsSL https://bun.sh/install | bash)
  • A booted simulator (xcrun simctl boot or open it in Xcode)

Install

Quickest path (npm + npx)

# Register with Claude Code, one line:
claude mcp add -s user ios-sim -- npx -y ios-sim-mcp

npx will fetch the package on first run. Verify:

claude mcp list | grep ios-sim     # ios-sim: ... ✓ Connected

Layer 2 dylib ships prebuilt as a universal binary (arm64 + x86_64) — works on both Apple Silicon and Intel Macs out of the box.

From source

git clone https://github.com/rmathew1973/ios-sim-mcp.git
cd ios-sim-mcp
bun install
./dylib/build.sh         # builds the Layer 2 dylib (only needed if you'll use inject:true)

Then register:

Shortened. The full README is on GitHub.

Nothing above is checked by us. What we check is on the safety report.

Ios Sim: common questions

Is Ios Sim MCP server safe?
Yes, by our scan: it is graded A (88/100). Read the Ios Sim safety report
How do I install Ios Sim?
It runs on your machine. Copy the Claude Code, Cursor, VS Code or Claude Desktop config from the install section.
Does Ios Sim need an API key?
Not as far as the registry entry and our scan can tell: no credentials are declared or required.
Is Ios Sim maintained?
The last commit was 91 days ago (2026-08-03). The latest release is v0.4.2.
What can I use instead of Ios Sim?
Servers from other publishers that do the same job: Argent MCP server, Flutter MCP Toolkit MCP server and Sceneview MCP server.
How does Ios Sim compare with other Productivity MCP servers?
safety score 88/100 (higher than 75% of 1,297 Productivity servers); tools 40 (the typical Productivity server has 7); tools that change things 13% (typical: 0%. Fewer write tools means less an agent can break). Full comparison.

Alternatives to Ios Sim

Same job from other publishers: the closest match first, then the best rated.

  • Argent
    Drive iOS Simulators, Android emulators, TVs and Electron/web apps from your coding agent
    A
  • Flutter MCP Toolkit
    Inspect and drive Flutter debug apps/games: semantic snapshots, search, and custom client tools
    A
  • Sceneview
    3D & AR SDK for Android, iOS, Web — API docs, samples, validation, and code generation.
    A
  • SceneView
    3D & AR SDK for Android, iOS, Web — API docs, samples, validation, and code generation.
    A
  • gflow-cli
    Drive Google Flow from an agent: Veo video and Imagen image generation
    A