mcp-ios
by dockndevai
README.md
# mcp-ios
[](https://github.com/dockndevai/mcp-ios/actions/workflows/ci.yml)
[](https://github.com/dockndevai/mcp-ios/actions/workflows/codeql.yml)
[](./LICENSE)
[](https://www.npmjs.com/package/@dockndevai/mcp-ios)
A [Model Context Protocol](https://modelcontextprotocol.io) server to drive an **iPhone/iPad** — the iOS counterpart to `mcp-android`. **Read this first: iOS is fundamentally more locked down than Android or macOS**, so this server takes the only legitimate route to real UI control.
## The honest landscape
A stock iPhone does **not** allow a background app to see and control other apps the way Android's Accessibility service (or macOS) does. Apple's sandbox forbids it. So there is **no on-device "iOS-use" agent** like the Mac/Android ones. The viable routes, in order of capability:
| Route | Control level | Needs | Notes |
| --- | --- | --- | --- |
| **Appium + WebDriverAgent (XCUITest)** ✅ *(this server)* | Full UI: tap, type, swipe, read elements, screenshots, launch apps | A **Mac** with Xcode; iPhone connected by **USB** (or same-network); WDA signed to the device | The real "phone-use". Built for automation/QA — perfect for a personal agent on your own device. |
| **Shortcuts** | Run user-defined actions (set alarm, send message, toggles) | Shortcuts app; a URL/x-callback bridge | No arbitrary UI control, but great for safe, specific actions. Exposed here via `run_shortcut`. |
| **MDM** | Policy/config, app install | Enrollment | Device management, not interactive control. |
This server implements the **Appium/WDA** route: it runs on a Mac, talks to a local Appium server driving WebDriverAgent on the tethered iPhone, and exposes the same safe-by-default MCP shape as the rest of the suite. A `set_alarm`-style action can also go through **Shortcuts** (`run_shortcut`) when the device isn't tethered.
> If you want control *from the phone itself with nothing attached*, that isn't possible on iOS — use `mcp-android` on the Fold 7 for that experience, or the Shortcuts subset here.
## Setup (Appium route)
```bash
brew install node
npm i -g appium
appium driver install xcuitest
# Xcode + command line tools installed; sign WebDriverAgent to your device once (Xcode)
# Connect the iPhone by USB, Trust the Mac, enable Developer Mode on the device
appium # starts the Appium server (default http://127.0.0.1:4723)
```
The server creates the XCUITest session **lazily** on the first tool call, so it starts even before Appium or the device are up — the first call that needs the device returns a clear "start `appium` / sign WDA / connect the device" message if it can't connect.
## Security model
| Concern | Flag | Default | Effect |
| --- | --- | --- | --- |
| What can the server do? | `IOS_MODE` | `read-only` | `read-only` exposes inspection only; `read-write` adds UI control; `admin` adds app management. Tools above the mode are **never registered**. |
| Which apps are in scope? | `IOS_APP_ALLOWLIST` | *(all)* | When set, launching/managing any other bundle ID is refused. |
| Which apps are read-only forever? | `IOS_PROTECTED_APPS` | `com.apple.Preferences`, `com.apple.springboard` | Inspectable/launchable but never terminated, reset, or uninstalled. |
| Can it install/terminate/reset apps? | `IOS_ALLOW_MANAGE` | `false` | The admin tools need this **and** admin mode; otherwise they aren't even advertised. |
| Interactive confirmation | *(automatic)* | — | `terminate_app` and `reset_app` prompt the human to approve the exact bundle ID via MCP elicitation before running; clients without elicitation fall back to the `IOS_ALLOW_MANAGE` gate. |
| Preview without touching the device | `IOS_DRY_RUN` | `false` | Write/admin tools validate + log intent, then return. |
| Audit trail | `IOS_AUDIT_LOG` | `true` | Emits a JSON line to stderr per guarded operation. |
Connection: `IOS_APPIUM_URL` (default `http://127.0.0.1:4723`), `IOS_UDID` (target device), `IOS_BUNDLE_ID` (optional default app). See [`.env.example`](.env.example) for all variables and [docs/CLIENTS.md](docs/CLIENTS.md) for the full per-client install guide.
## Tools
**Read** (`read-only`+): `list_targets`, `device_info`, `screenshot`, `page_source` (element tree), `current_app`, `list_apps`
**Write** (`read-write`+): `tap`, `swipe`, `input_text`, `press_button` (home/volume), `launch_app`, `open_url`, `run_shortcut` (via Shortcuts)
**Admin** (`admin` + `IOS_ALLOW_MANAGE`): `install_app`, `terminate_app`, `reset_app` (the last two confirm via elicitation; protected apps refused)
`screenshot` returns an MCP image content block so the agent can see the screen before acting.
## Quickstart — add to your agent
Published on npm as [`@dockndevai/mcp-ios`](https://www.npmjs.com/package/@dockndevai/mcp-ios). No clone or build needed — your MCP client runs it on demand with `npx`. It must run **on the Mac** with a running Appium server. **Start in `read-only` mode.**
**Claude Code** (CLI)
```bash
claude mcp add ios -e IOS_APPIUM_URL="http://127.0.0.1:4723" -e IOS_MODE="read-only" -- npx -y @dockndevai/mcp-ios
```
**Claude Desktop · Cursor · Windsurf** — same block in `claude_desktop_config.json`, `.cursor/mcp.json`, or `~/.codeium/windsurf/mcp_config.json`:
```json
{
"mcpServers": {
"ios": {
"command": "npx",
"args": [
"-y",
"@dockndevai/mcp-ios"
],
"env": {
"IOS_APPIUM_URL": "http://127.0.0.1:4723",
"IOS_MODE": "read-only"
}
}
}
}
```
**VS Code (GitHub Copilot, Agent mode)** — in `.vscode/mcp.json`:
```json
{
"servers": {
"ios": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@dockndevai/mcp-ios"
],
"env": {
"IOS_APPIUM_URL": "http://127.0.0.1:4723",
"IOS_MODE": "read-only"
}
}
}
}
```
## Example prompts
- *"Take a screenshot of my phone and tell me what's on screen."*
- *"Open Safari and go to news.ycombinator.com."* (needs `read-write`)
- *"Run my 'Good morning' Shortcut."* (needs `read-write`)
## Run from source (development)
```bash
npm install
npm run build
node dist/index.js # with the environment variables set, and `appium` running
```
## Develop
```bash
npm run dev
npm test # security policy + elicitation confirmation (pure; no device needed)
npm run typecheck
```
> The policy and elicitation tests are pure and run anywhere. The device-driving path can't be smoke-tested without a Mac + Xcode + signed WDA + a tethered iPhone, so it's built against your real device setup.
## Publishing
This server ships a [`server.json`](server.json) for the official MCP registry and an [`mcpName`](package.json) for npm ownership validation. See **[PUBLISHING.md](PUBLISHING.md)** for publishing to npm and listing on the MCP registry, Smithery, Glama, Cursor, and PulseMCP.
## License
MIT
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues