Skip to main content
Glama

mcp-ios

CI CodeQL License: MIT npm

A Model Context Protocol 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.

Related MCP server: ios-device-mcp

Setup (Appium route)

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 for all variables and 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. 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)

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:

{
  "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:

{
  "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)

npm install
npm run build
node dist/index.js   # with the environment variables set, and `appium` running

Develop

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 for the official MCP registry and an mcpName for npm ownership validation. See PUBLISHING.md for publishing to npm and listing on the MCP registry, Smithery, Glama, Cursor, and PulseMCP.

License

MIT

Available Tools

6 tools
current_appCurrent appB

The app (bundle ID / process) currently in the foreground.

NameRequiredDescriptionDefault

No parameters

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and only discloses the identity of the returned value. It says nothing about whether accessibility/automation permissions are required, what happens when no app is foregrounded, or whether the result is a string or a structured object.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single short sentence with no filler. It is appropriately sized, though it leads with a noun phrase rather than an action, which slightly weakens front-loading for a first-time reader.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple zero-param read tool this is close, but with no output schema and no annotations, the description should specify the return shape and failure behavior. It only partially does so by noting the bundle ID / process form.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4; there is nothing for the description to compensate for. Schema coverage is 100% on an empty object.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific resource — the foreground app, identified by bundle ID / process — which is distinct from list_apps (all apps) and device_info. It lacks an explicit verb, but the noun phrase is unambiguous about what is returned.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance and no mention of alternatives such as list_apps or device_info. The phrase 'currently in the foreground' hints at the context, but the agent must infer when this tool is preferred over its siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

device_infoDevice infoA

Session capabilities and device info (model, iOS version, screen) reported by WebDriverAgent.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, so the description carries the full burden; it does convey that the data is passively reported by WebDriverAgent, which implies a read with no side effects. It says nothing about whether values are cached/snapshot-at-session-start or live, or what happens if no session exists — gaps that matter for a session-scoped read.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single compact sentence with the core resource front-loaded and the concrete payload fields appended. Nothing redundant and nothing padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a no-parameter, no-annotation, no-output-schema tool, the description is nearly sufficient — it names the returned fields and the reporting agent. It falls short only on session preconditions and whether repeated calls return fresh values.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to disambiguate; baseline 4 applies. The enumerated return fields (model, iOS version, screen) add useful framing without being required.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource — session capabilities plus device info — and enumerates concrete fields (model, iOS version, screen) and the source (WebDriverAgent). It isn't confused with any sibling (screenshot, page_source, current_app), though it never explicitly names what separates it from current_app, which also reports state.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No statement of when to call this versus alternatives, no prerequisites (e.g., that a session must be active), and no exclusion criteria. The agent has to infer usage purely from the tool name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_appsList appsB

List installed apps (best-effort; depends on the WebDriverAgent build).

NameRequiredDescriptionDefault

No parameters

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It usefully discloses that results are 'best-effort' and depend on the WebDriverAgent build, but it does not explain return behavior, permissions, or what happens when the dependency is unsupported.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single front-loaded sentence with a useful parenthetical caveat. Every part earns its place and there is no redundant wording.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, low-complexity listing tool, the description covers the core purpose and a reliability caveat. However, without an output schema or annotations, it leaves open what 'apps' returns and how this differs from current_app or list_targets.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the schema baseline is 4. There are no parameter semantics to clarify in the description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a clear verb and resource: 'List installed apps.' This is more specific than a title restatement, but it does not distinguish the tool from siblings such as list_targets or current_app.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives like list_targets or current_app. The caveat about WebDriverAgent builds describes reliability, not usage conditions or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_targetsList targetsB

Show the configured Appium connection (URL, target UDID, default bundle ID) and, best-effort, the devices/simulators attached to this Mac.

NameRequiredDescriptionDefault

No parameters

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It usefully discloses that device enumeration is 'best-effort' (i.e., may be incomplete or fail), which is real behavioral context, and the read-only 'Show' framing implies no mutation. It stops short of saying whether the call requires a live Appium server, what happens when none is configured, or how failures surface.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single well-formed sentence with the primary payload (the configured connection) front-loaded and the secondary, less reliable part (attached devices) qualified. No filler, though the parenthetical enumeration makes it slightly dense.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description must convey return values — and it does, naming the three connection fields and the device list. Combined with the 'best-effort' caveat, an agent knows enough to call it; only failure/precondition behavior is unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to disambiguate. Baseline 4 applies; the description correctly implies a no-argument call.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ('Show') and enumerates exactly what is returned: the Appium connection URL, target UDID, default bundle ID, plus attached devices/simulators. That makes the output concrete, though it doesn't explicitly contrast with the similar-sounding sibling device_info, so the boundary between the two needs inference.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance and no mention of alternatives. An agent facing both list_targets and device_info has no textual basis for choosing one over the other.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

page_sourceElement treeA

Dump the current screen's XCUITest element tree (XML) with labels, types, and bounds — use it to find exact tap coordinates.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It does disclose the return format (XML) and payload contents (labels, types, bounds) and implies a read-only snapshot of the current screen, but says nothing about output size/verbosity on complex screens, staleness of the snapshot, or failure modes when the screen is mid-transition.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single em-dash-joined sentence that front-loads what is returned and ends with the actionable purpose. No filler, nothing repeated from the title alone.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, no-output-schema dump tool this is close to sufficient: format, contents, and purpose are all covered. The only gap is any hint about output volume or when the tree may not reflect the settled UI, which matters for a UI-automation agent parsing XML.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Zero parameters, so there is nothing to disambiguate; the baseline of 4 applies. The description correctly implies the tool takes no input by scoping itself to "the current screen."

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: dumps the current screen's XCUITest element tree as XML, with labels, types, and bounds. This concretely distinguishes it from the sibling screenshot tool, which returns pixels rather than an inspectable element hierarchy.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"use it to find exact tap coordinates" gives a clear positive trigger, which is exactly the decision an agent needs. It stops short of an explicit exclusion (e.g., use screenshot for visual verification instead), so it lacks the alternative-routing that would earn a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

screenshotScreenshotA

Capture the current screen as a PNG image so you can see what's on the phone before acting.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must carry behavioral disclosure. It does convey that the result is a PNG image and implies a read-only capture, but says nothing about device requirements, latency, image scope (e.g., status bar, resolution), or failure modes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with the output format stated early and a purpose clause that earns its place. No waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, output-less-schema tool, the description covers what it does and what it returns (PNG). Minor gaps: no mention of needed device context or when to prefer ui_dump.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to disambiguate; the baseline for a 0-param tool applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Capture the current screen as a PNG image') plus the concrete output format. It does not explicitly contrast with the closest sibling, ui_dump, but an agent can distinguish an image capture from a UI tree dump.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'...so you can see what's on the phone before acting' implies the timing (prior to interactions) but gives no explicit when-not or named alternatives such as ui_dump for structured element data.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 6 tool updatesv0.1.0
    • First observedcurrent_app
    • First observeddevice_info
    • First observedlist_apps
    • First observedlist_targets
    • First observedpage_source
    • First observedscreenshot

TDQS

B3.4/5.0

Scored across 6 tools

Disambiguation4/5

Most tools are clearly distinct (screenshot vs page_source vs current_app vs list_apps). However, list_targets and device_info overlap somewhat: both report device/connection information, which could cause an agent to pick the wrong one when it just wants device details.

Naming Consistency3/5

All names use snake_case, which is consistent, but the naming convention mixes verb_noun (list_targets, list_apps) with noun phrases (device_info, screenshot, page_source, current_app). It is readable but not a predictable verb-first pattern throughout.

Tool Count4/5

Six tools is a reasonable, well-scoped set for an inspection-oriented iOS/Appium bridge, and each tool earns its place. It is slightly thin for full iOS automation, but the count itself is not excessive or trivial.

Completeness2/5

The surface is inspection-only: there are no interaction tools such as tap, type text, swipe, launch/terminate app, or navigation. Since screenshot and page_source are explicitly framed as preparation 'before acting,' the absence of any acting tools is a significant gap that will block agent workflows.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables agents to control a physical iPhone from macOS through local phone tools, including USB capture, Bluetooth HID, and AssistiveTouch interactions. It also exposes relay tools for remote access over Streamable HTTP with optional OAuth.
    MIT
  • A
    license
    B
    quality
    B
    maintenance
    Enables controlling a real iPhone or iPad over USB for app development testing, including building and installing apps, launching with console logs, inspecting the accessibility tree, tapping, swiping, typing, taking screenshots, managing app files, and recording audio.
    28
    1
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI agents to operate a real iPhone from a Mac by reading the screen over USB and sending taps, swipes, typing, and app launches over Bluetooth, with every action returning a fresh screenshot so the agent can verify its work. Runs as a local MCP server, so agents can test iOS apps on physical devices and automate everyday phone tasks.
    43 npm
    10
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Free, open-source Mac app and MCP server that lets AI agents take screenshots, tap, swipe, type and launch apps on a real iPhone. Includes owner-approved clients, an activity log and pause controls; supports USB and Wi-Fi after pairing.
    12
    Apache 2.0