# Ios Mcp Server

> MCP server for iOS Simulator control with native touch injection (IndigoHID) and native UI tree reading (AXPTranslation). No mouse hijacking, no Accessibility permissions needed.

- **Type:** MCP server
- **Install:** `agentstack add mcp-martingeidobler-ios-mcp-server`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [martingeidobler](https://agentstack.voostack.com/s/martingeidobler)
- **Installs:** 0
- **Category:** [Integrations](https://agentstack.voostack.com/c/integrations)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [martingeidobler](https://github.com/martingeidobler)
- **Source:** https://github.com/martingeidobler/ios-mcp-server

## Install

```sh
agentstack add mcp-martingeidobler-ios-mcp-server
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# iOS MCP Server

[](https://www.npmjs.com/package/ios-mcp-server)
[](https://www.npmjs.com/package/ios-mcp-server)
[](https://opensource.org/licenses/MIT)

MCP server for controlling iOS Simulators. Gives AI assistants the ability to see, interact with, and debug iOS apps — taking screenshots, tapping elements, reading the UI tree, and automating testing workflows.

Built with native touch injection and native UI tree reading for accurate, reliable automation that doesn't interfere with your machine.

[npm Package](https://www.npmjs.com/package/ios-mcp-server) | [GitHub](https://github.com/martingeidobler/ios-mcp-server) | [Issues](https://github.com/martingeidobler/ios-mcp-server/issues)

## Why This Server

Most iOS Simulator MCP servers work by sending mouse clicks to the Simulator window through macOS, then reading the Simulator's window frame through the macOS Accessibility API. This means:

- **Your mouse gets hijacked** every time the AI taps something
- **The Simulator window must stay in the foreground** — you can't use your Mac while tests run
- **The UI tree returns Simulator chrome** (window buttons, toolbar) mixed with actual app elements
- **macOS Accessibility permissions are required** for your terminal
- **Touch coordinates are fragile** — they depend on window position and scale

This server takes a different approach:

- **Native touch injection** via IndigoHID — sends touch events directly to the Simulator's HID system. Sub-pixel accuracy, no mouse movement, works with the Simulator in the background.
- **Native UI tree** via AXPTranslation — reads the actual iOS accessibility tree through CoreSimulator, not the macOS window. Returns only app elements with correct device-point coordinates.
- **No macOS Accessibility permissions needed** — everything goes through Apple's Simulator frameworks.
- **No window focus required** — the Simulator can be minimized or behind other windows.

## Features

- **31 tools** for complete iOS Simulator control
- **Native touch injection** — tap, swipe, long press, double tap, multi-tap via IndigoHID (compiled from source on first use)
- **Native UI tree** — real iOS accessibility tree via AXPTranslation (no Simulator chrome, no macOS AX permissions)
- **Screenshot capture** with intelligent compression (Sharp-based, max 1280px)
- **Element targeting** — find and tap elements by identifier, label, or value
- **App lifecycle** — install apps, launch, terminate, uninstall
- **Log integration** — filter by bundle ID, log level, or timestamp
- **Device management** — list simulators, boot/shutdown, get device info
- **Compound actions** — `tap_and_wait` combines tap + settle + UI tree in one round trip
- **iOS-specific tools** — push notifications, permissions, URL schemes, status bar overrides
- **Multi-device support** — target specific simulators by UDID
- **Zero app modifications** — works with any iOS app, no SDK integration needed

## Prerequisites

- macOS (required for iOS Simulator)
- Xcode with command line tools (`xcode-select --install`)
- Node.js 18+
- A booted iOS Simulator

That's it. No Accessibility permissions, no special configuration.

## Setup

Claude Code

```bash
claude mcp add --scope user ios -- npx -y ios-mcp-server
```

This registers the server globally so it's available in all projects. Use `--scope project` instead to limit it to the current project.

Claude Desktop

Add to your Claude Desktop config file (`~/Library/Application Support/Claude/claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "ios": {
      "command": "npx",
      "args": ["-y", "ios-mcp-server"]
    }
  }
}
```

VS Code

Add to your VS Code settings (`.vscode/settings.json`):

```json
{
  "mcp": {
    "servers": {
      "ios": {
        "command": "npx",
        "args": ["-y", "ios-mcp-server"]
      }
    }
  }
}
```

Cursor

Add to your Cursor MCP config (`~/.cursor/mcp.json`):

```json
{
  "mcpServers": {
    "ios": {
      "command": "npx",
      "args": ["-y", "ios-mcp-server"]
    }
  }
}
```

Windsurf

Add to your Windsurf MCP config (`~/.codeium/windsurf/mcp_config.json`):

```json
{
  "mcpServers": {
    "ios": {
      "command": "npx",
      "args": ["-y", "ios-mcp-server"]
    }
  }
}
```

Project config (.mcp.json)

Add to your project's `.mcp.json` (checked into version control so your team gets it too):

```json
{
  "mcpServers": {
    "ios": {
      "command": "npx",
      "args": ["-y", "ios-mcp-server"]
    }
  }
}
```

Build from source

```bash
git clone https://github.com/martingeidobler/ios-mcp-server.git
cd ios-mcp-server
npm install
npm run build
claude mcp add --scope user ios -- node /path/to/ios-mcp-server/dist/index.js
```

## Available Tools

### Device Management
| Tool | Description |
|------|-------------|
| `list_devices` | List available iOS Simulators and their state |
| `list_simulators` | List available simulator device types (iPhone, iPad models) |
| `boot_simulator` | Boot a simulator by name or UDID (waits up to 60s) |

### Screenshot & UI Analysis
| Tool | Description |
|------|-------------|
| `screenshot` | Take screenshot for visual analysis. Optional `save_path` to save to disk |
| `get_ui_tree` | Get UI element hierarchy with bounds, labels, identifiers, and state |

### Interaction
| Tool | Description |
|------|-------------|
| `tap` | Tap at screen coordinates (device points) |
| `tap_element` | Tap element by identifier, label, or value |
| `tap_and_wait` | Tap element, wait for UI to settle, return new UI tree — single round trip |
| `long_press` | Long press at coordinates (context menus, drag handles) |
| `double_tap` | Double tap at coordinates (zoom in, double-tap interactions) |
| `multi_tap` | Tap N times at coordinates with configurable interval |
| `tap_sequence` | Execute a sequence of steps: tap, long press, swipe, type, key press, and pause |
| `type_text` | Type text into focused input |
| `press_key` | Press key (home, lock, enter, tab, delete, arrows, volume, shake, rotate) |
| `swipe` | Swipe gesture between coordinates |
| `scroll_to_element` | Scroll until element is visible |
| `wait_for_element` | Wait for element to appear (with timeout) |

### App Management
| Tool | Description |
|------|-------------|
| `launch_app` | Launch app by bundle ID |
| `terminate_app` | Terminate a running app |
| `install_app` | Install .app bundle |
| `uninstall_app` | Uninstall app by bundle ID |
| `get_current_app` | Get foreground app info |
| `simctl_run` | Run a command inside the Simulator |

### Diagnostics
| Tool | Description |
|------|-------------|
| `get_logs` | Get log output, filterable by bundle ID, log level, and time |
| `clear_logs` | Set log baseline (call before reproducing a bug for clean output) |
| `get_device_info` | Get name, model, iOS version, screen size |
| `pull_file` | Pull a file from an app's container |

### iOS-Specific Utilities
| Tool | Description |
|------|-------------|
| `open_url` | Open a URL or deep link in the Simulator |
| `send_push` | Send a push notification to an app |
| `set_permission` | Grant, revoke, or reset app permissions |
| `set_status_bar` | Override status bar display (time, battery, signal) |

## Example Workflows

### Bug documentation

> "Clear the logs, launch com.example.app, navigate to the settings screen, tap Save, then show me the logs and a screenshot"

Claude will: `clear_logs` → `launch_app` → `tap_element` → `get_logs(bundle_id="com.example.app", level="error")` → `screenshot(save_path="./bugs/settings-crash.png")`

### UI testing

> "Navigate through the login flow and verify each screen matches the designs"

Claude will use `screenshot` + `get_ui_tree` to see and understand each screen, `tap_element`/`type_text` to interact, and its vision capabilities to compare against mockups or descriptions.

### Smoke testing

> "Install the app, launch it, and tap through the main screens to check nothing crashes"

Claude will: `install_app` → `launch_app` → navigate with `tap_element` → `get_logs(level="error")` to check for errors after each screen.

### Deep linking

> "Open the deep link myapp://profile/123 and verify the profile screen loads"

Claude will: `open_url(url="myapp://profile/123")` → `get_ui_tree` to verify the profile screen elements → `screenshot` for visual confirmation.

### Push notification testing

> "Send a push notification to the app and verify the notification appears"

Claude will: `send_push(bundle_id="com.example.app", title="Hello", body="Test notification")` → `screenshot` to see the notification.

## Demos & Prompting Guide

- **[PROMPTING.md](PROMPTING.md)** — best practices, performance tips, and common pitfalls

## How It Works

The server communicates over stdio using the [Model Context Protocol](https://modelcontextprotocol.io). Under the hood it uses three mechanisms:

1. **`xcrun simctl`** — device management, app lifecycle, screenshots, logs, and simulator commands
2. **Native `simtouch` binary** — compiled from Objective-C on first use, sends touch events directly to the Simulator's HID system via IndigoHID/CoreSimulator private frameworks. No mouse involvement.
3. **Native `simtree` binary** — compiled from Objective-C on first use, reads the iOS app's accessibility tree via AXPTranslation/CoreSimulator. Returns real iOS element data, not macOS Simulator window chrome.

Both native binaries are compiled automatically on first use and cached. The source files (`native/simtouch.m`, `native/simtree.m`) ship with the package; only Xcode command line tools are needed.

### Architecture

```
MCP Client (Claude Code, Desktop, VS Code, etc.)
    ↕ stdio (MCP protocol)
iOS MCP Server (Node.js)
    ↕               ↕                  ↕
xcrun simctl     simtouch            simtree
    ↕               ↕                  ↕
iOS Simulator    IndigoHID          AXPTranslation
                 (CoreSimulator)    (CoreSimulator)
```

## Contributing

Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

## License

MIT - see [LICENSE](LICENSE).

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [martingeidobler](https://github.com/martingeidobler)
- **Source:** [martingeidobler/ios-mcp-server](https://github.com/martingeidobler/ios-mcp-server)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-martingeidobler-ios-mcp-server
- Seller: https://agentstack.voostack.com/s/martingeidobler
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
