Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

ios-agent

PYPI · IOS-MCP

Drive a real iPhone or an iOS Simulator with an AI agent, through XCUIAutomation.

Available components

+18 this week 93 Trust /100

Last scanned (18 hours ago)

Scores higher than 96% of PyPI servers

Category Browser Automation

Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →

Supply Chain Security100
  • No malware found by supply-chain analysis.Pass
  • No known CVEs affecting this package version or its production dependencies.Pass
  • Runs hatchling.build at install time, a recognised build step with no custom scripting around it. View diagnostics → Pass
  • 1 of 22 dependencies flagged as unhealthy. View diagnostics → Partial
Provenance & Transparency100
  • Source repository is publicly reachable at the declared URL. View diagnostics → Pass
  • Cryptographically verified build provenance (signed, bound to emazaheri/ios-agent). View diagnostics → Pass
  • Clear OSI-approved license (MIT).Pass
  • Actively maintained (last published 28 days ago).Pass
  • Publishes a security disclosure policy (SECURITY.md).Pass
Schema Quality & AI Usability84
  • 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
  • AI-judged instruction clarity (good).Pass
  • Tool/resource definitions use about 3359 tokens (~93/item across 36 items; 31 tools + 5 resources), lean.Pass
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management70
  • Stability observed for 21 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage100
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 100% of tool parameters carry a description.Pass
  • Structured output schemas are declared (97% of tools); any adoption earns full credit.Pass
Tool Safety100
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • All 1 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.Pass
  • An AI judge read all 33 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a current MCP spec version (2026-07-28).Pass
Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 3 Nov 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 63 to 67. That category is still filling its 30-day observation window: 19 days of observed history at the previous scan, 20 at this one. The score rises as the window fills, whether or not the server changes.

  • 1 Nov 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 57 to 60. That category is still filling its 30-day observation window: 17 days of observed history at the previous scan, 18 at this one. The score rises as the window fills, whether or not the server changes.

  • 31 Oct 26 +15
    • Malware scan: unverified → pass ▲ security
  • 30 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 50 to 53. That category is still filling its 30-day observation window: 15 days of observed history at the previous scan, 16 at this one. The score rises as the window fills, whether or not the server changes.

  • 28 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 43 to 47. That category is still filling its 30-day observation window: 13 days of observed history at the previous scan, 14 at this one. The score rises as the window fills, whether or not the server changes.

  • 26 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 37 to 40. That category is still filling its 30-day observation window: 11 days of observed history at the previous scan, 12 at this one. The score rises as the window fills, whether or not the server changes.

  • 25 Oct 26 −15
    • Malware scan: pass → unverified ▼ security
  • 24 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 30 to 33. That category is still filling its 30-day observation window: 9 days of observed history at the previous scan, 10 at this one. The score rises as the window fills, whether or not the server changes.

Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 4 Nov 2026 · Analysed pypi/ios-mcp@0.6.0

Provenance Verified

A signed build attestation was found and verified, binding this exact artifact to the source repository it claims to come from.

Result Verified
Ecosystem pypi
Reason Verified
Discovered via Registry attestation endpoint
Source repo emazaheri/ios-agent
Certificate issuer https://token.actions.githubusercontent.com
Certificate SAN https://github.com/emazaheri/ios-agent/.github/workflows/release.yml@refs/tags/v0.6.0
Rekor log index 3124145979
Predicate type PyPI publish attestation https://docs.pypi.org/attestations/publish/v1
Subject digest sha256:f0c8ffc90b478ab2fcd977e2e1c4b0b3dadc895e34171cf797ca8116261ccb81

Background: How many MCP packages publish verified provenance →

Install scripts 1 script
Hook Tier Command
build_backend allowlisted hatchling.build

Background: Why install scripts are a supply-chain risk →

Dependencies 22 packages
Packages resolved 22
Stale 1
Tree resolution Complete

Background: SBOMs and build attestations, explained →

MCP tools · 31 exposed · ~2,963 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
ios_clipboard ~67

Read or write the device clipboard. Writing is often faster and more reliable than typing a long string, which the on-screen keyboard can mangle with autocorrect.

NameTypeReqDescription
actionstring–'get' or 'set'.
text––Text to write when action is 'set'.

Structured output declared, but exposes no named fields.

No examples provided.

ios_close_session ~21

Release the device and shut down its WebDriverAgent runner.

Input schema present but exposes no named parameters.

Structured output declared, but exposes no named fields.

No examples provided.

ios_doctor ~67

Check that this machine can drive an iOS device, and say how to fix what it can't. Run this first when a session fails to start, when a device does not appear, or after an Xcode or iOS upgrade. Every failing check comes with a concrete remedy.

Input schema present but exposes no named parameters.

Structured output declared, but exposes no named fields.

No examples provided.

ios_drag ~88

Drag one element onto another, for reordering lists and moving items.

NameTypeReqDescription
duration_snumber–Gesture duration.
from_refstringyesRef of the element to drag.
idem_key––Optional key making a retry a no-op. Pass the same key when repeating an action you are unsure completed.
to_refstringyesRef of the element to drop onto.

Structured output declared, but exposes no named fields.

No examples provided.

ios_export_trace ~38

Return the ordered record of everything this session has done. Useful for explaining what happened, and for turning a successful run into a regression test.

Input schema present but exposes no named parameters.

Structured output declared, but exposes no named fields.

No examples provided.

ios_find ~208

Search the screen's accessibility tree, including what the digest hides. Prefer `ios_observe` with a `query` when you want a usable digest you can tap from: what it returns carries refs. Use this when `ios_observe` shows nothing matching but the text is on the device, or when a tap keeps missing. It reads the tree before compaction, so it reports matches the digest dropped, which `ios_observe` by construction cannot, and each one says whether it is `shown` or `hidden`. A hidden match is the diagnosis: the words are on screen and perception is why you cannot reach them. Name it by the `id` reported here.

NameTypeReqDescription
budget––The budget you observed with. It decides `shown`, so pass it whenever you set one on ios_observe.
limitinteger–Most matches to return.
textstringyesText to look for, matched case-insensitively.

Structured output declared, but exposes no named fields.

No examples provided.

ios_get_logs ~70

Read recent device logs. Useful when an app misbehaves and the UI does not say why.

NameTypeReqDescription
limitinteger–Maximum lines to return.
predicate––Filter: an NSPredicate on a Simulator, else a substring.
since_snumber–How far back to read.

Structured output declared, but exposes no named fields.

No examples provided.

ios_halt ~30

Stop this session from taking further action.

NameTypeReqDescription
reasonstring–Why the session is being stopped.

Structured output declared, but exposes no named fields.

No examples provided.

ios_handle_alert ~67

Answer a system alert. Read the alert text before choosing. Accepting blindly is how an agent grants a permission or confirms a deletion nobody wanted.

NameTypeReqDescription
actionstringyes'accept' or 'dismiss'.
button––Exact button label, when the alert has several.

Structured output declared, but exposes no named fields.

No examples provided.

ios_install_app ~38

Install an app from a local .app or .ipa.

NameTypeReqDescription
pathstringyesPath to a .app bundle or .ipa file.

Structured output declared, but exposes no named fields.

No examples provided.

ios_launch_app ~52

Bring an app to the foreground and return its screen.

NameTypeReqDescription
bundle_idstringyese.g. com.apple.Preferences
freshboolean–Restart the app instead of resuming where it was.

Structured output declared, but exposes no named fields.

No examples provided.

ios_list_apps ~37

List apps installed on the device, with their bundle identifiers.

NameTypeReqDescription
kindstring–'user', 'system', or 'all'.

Structured output declared, but exposes no named fields.

No examples provided.

ios_list_devices ~62

List iOS Simulators and attached physical iPhones available for automation. `ready` is false when something blocks automation; `blockers` says what.

NameTypeReqDescription
kindstring–Filter by device kind: 'simulator', 'device', or 'all'.

Structured output declared, but exposes no named fields.

No examples provided.

ios_observe ~171

Read the screen as a compact list of elements with short refs. Each line is one element: `e7 button "Send" @(340,70)`. Pass those refs to the action tools rather than coordinates. If the result says elements were omitted, narrow with `query` or `region` instead of raising `budget`; a smaller answer is usually the more useful one.

NameTypeReqDescription
budget––Token budget for the digest. Default 1500.
include_elementsboolean–Also return each element as structured JSON. Roughly doubles the cost and duplicates the text form; only useful programmatically.
query––Keep only elements whose text contains this. Use when truncated.
region––Restrict to a screen area as [x, y, width, height].

Structured output declared, but exposes no named fields.

No examples provided.

ios_open_session ~131

Attach to a device and start driving it. Boots the simulator or verifies the phone, starts WebDriverAgent, and opens a tuned session. Omitting `device` prefers an already-booted simulator over a connected iPhone, so acting on a real device is always a deliberate choice.

NameTypeReqDescription
app––Bundle id to open, e.g. com.apple.Preferences.
device––UDID, exact name, or part of a name. Omit to pick the best default.
freshboolean–Relaunch the app from scratch rather than resuming it.

Structured output declared, but exposes no named fields.

No examples provided.

ios_open_url ~85

Open a URL or deep link. Usually the cheapest way to reach a screen: a deep link skips the navigation an agent would otherwise have to tap through.

NameTypeReqDescription
urlstringyesA URL or deep link, e.g. maps://?q=coffee or https://example.com. From iOS 26 a Settings link opens Settings but not the pane it names.

Structured output declared, but exposes no named fields.

No examples provided.

ios_press_button ~76

Press a hardware button or a keyboard key.

NameTypeReqDescription
idem_key––Optional key making a retry a no-op. Pass the same key when repeating an action you are unsure completed.
namestringyesHardware: home, volumeUp, volumeDown, siri. Keyboard: enter, tab, delete, space, dismiss_keyboard.

Structured output declared, but exposes no named fields.

No examples provided.

ios_read_text ~70

Read the text of the screen, or of one element and everything inside it. Use this to extract content, rather than `ios_observe`, which is shaped for deciding what to tap.

NameTypeReqDescription
ref––Read only inside this element.
target––Read inside the element matching this description.

Structured output declared, but exposes no named fields.

No examples provided.

ios_resume ~22

Clear a halt after a human has decided it is safe to continue.

Input schema present but exposes no named parameters.

Structured output declared, but exposes no named fields.

No examples provided.

ios_screenshot ~142

Capture the screen as an image. Use this when an element has no accessibility label, when the layout matters, or when `ios_observe` cannot find something you can plainly see. With `annotate_refs` each element is boxed and labelled with its ref, so you can pick one by eye and pass it to an action tool. Annotating re-reads the screen first, so the refs on the image are the current ones rather than whatever was observed last. That costs a tree fetch, and needs the `vision` extra installed.

NameTypeReqDescription
annotate_refsboolean–Draw labelled boxes over the elements, using fresh refs.

No output schema declared.

No examples provided.

ios_scroll ~165

Scroll, optionally until some text comes into view. With `until`, this stops as soon as the text appears and gives up when the content stops moving, so it will not spin at the end of a list.

NameTypeReqDescription
directionstring–up, down, left, or right.
idem_key––Optional key making a retry a no-op. Pass the same key when repeating an action you are unsure completed.
max_scrollsinteger–Cap on repeats when `until` is set.
ref––A ref from the last observation, such as 'e7'. Preferred.
target––Plain description of the element, e.g. 'the Send button'. Used if no ref.
until––Keep scrolling until this text appears.

Structured output declared, but exposes no named fields.

No examples provided.

ios_session_status ~23

Report the current session: device, foreground app, and safety state.

Input schema present but exposes no named parameters.

Structured output declared, but exposes no named fields.

No examples provided.

ios_set_device_state ~83

Change device-level state. Appearance, location, and status bar are Simulator only.

NameTypeReqDescription
appearance––'light' or 'dark'.
clean_status_barboolean–Freeze the status bar so screenshots are reproducible.
latitude––Simulated latitude.
longitude––Simulated longitude.
orientation––'portrait' or 'landscape'.

Structured output declared, but exposes no named fields.

No examples provided.

ios_set_permission ~98

Set a privacy permission without going through the alert. Simulator only. On a real phone there is no API for this: drive the Settings app, or answer the permission alert with ios_handle_alert.

NameTypeReqDescription
bundle_idstringyesApp to grant or revoke for.
grantboolean–True to grant, False to revoke.
servicestringyeslocation, photos, camera, microphone, contacts, calendar, or all.

Structured output declared, but exposes no named fields.

No examples provided.

ios_set_value ~270

Set a switch, slider, or picker wheel to a value. 'on' or 'off' for a switch, a percentage such as '40%' or a fraction for a slider, and the option spelled the way the wheel spells it for a picker. A wheel is turned a row at a time and read back after each one, so an option it does not contain fails listing what it does. Prefer this over tapping a switch: it checks the current state first, so asking for 'on' when it is already on does nothing rather than turning it off. Steppers and segmented controls are not set this way. iOS reports their parts and the digest shows them, so tap 'Increment', 'Decrement', or the segment by its own label.

NameTypeReqDescription
approve––Signature returned by a previous action_requires_approval error.
idem_key––Optional key making a retry a no-op. Pass the same key when repeating an action you are unsure completed.
ref––A ref from the last observation, such as 'e7'. Preferred.
target––Plain description of the element, e.g. 'the Send button'. Used if no ref.
valuestringyes'on'/'off' for switches, otherwise the value.

Structured output declared, but exposes no named fields.

No examples provided.

ios_swipe ~111

Swipe once, for carousels, page views, and swipe-to-reveal rows.

NameTypeReqDescription
directionstringyesup, down, left, or right.
idem_key––Optional key making a retry a no-op. Pass the same key when repeating an action you are unsure completed.
ref––A ref from the last observation, such as 'e7'. Preferred.
target––Plain description of the element, e.g. 'the Send button'. Used if no ref.

Structured output declared, but exposes no named fields.

No examples provided.

ios_tap ~178

Tap an element and return the resulting screen. Prefer `ref` over `target`; it is exact and cannot be misread. Taps on things like Send, Pay, or Delete need approval first.

NameTypeReqDescription
approve––Signature returned by a previous action_requires_approval error.
doubleboolean–Double tap.
idem_key––Optional key making a retry a no-op. Pass the same key when repeating an action you are unsure completed.
long_press_s––Press and hold for this many seconds.
ref––A ref from the last observation, such as 'e7'. Preferred.
role––Narrow by role, e.g. 'button', 'cell', 'switch'.
target––Plain description of the element, e.g. 'the Send button'. Used if no ref.

Structured output declared, but exposes no named fields.

No examples provided.

ios_terminate_app ~31

Force-quit an app.

NameTypeReqDescription
bundle_idstringyesBundle id of the app to kill.

Structured output declared, but exposes no named fields.

No examples provided.

ios_type ~197

Type into a field, focusing it first when a ref or target is given. The field is read back afterwards. If the text did not land, the call fails with `typed.shown` saying what the field holds; `reformatted` means it landed with the app's own capitalisation or formatting.

NameTypeReqDescription
approve––Signature returned by a previous action_requires_approval error.
clear_firstboolean–Replace the field's contents.
idem_key––Optional key making a retry a no-op. Pass the same key when repeating an action you are unsure completed.
ref––A ref from the last observation, such as 'e7'. Preferred.
submitboolean–Press return afterwards.
target––Plain description of the element, e.g. 'the Send button'. Used if no ref.
textstringyesText to type. Never a password; see ios_type_secret.

Structured output declared, but exposes no named fields.

No examples provided.

ios_type_secret ~167

Type a stored secret without ever seeing its value. The value is read from the host keychain and sent straight to the device. Use this for every password and one-time code; never put a real credential into `ios_type`, where it would enter the transcript.

NameTypeReqDescription
idem_key––Optional key making a retry a no-op. Pass the same key when repeating an action you are unsure completed.
ref––A ref from the last observation, such as 'e7'. Preferred.
secret_refstringyesName of a stored secret, e.g. 'icloud-password'. Not the value.
submitboolean–Press return afterwards.
target––Plain description of the element, e.g. 'the Send button'. Used if no ref.

Structured output declared, but exposes no named fields.

No examples provided.

ios_wait_for ~98

Wait for something to appear or disappear. Prefer this over guessing a sleep. It returns as soon as the condition holds, and reports failure rather than raising, so a timeout is something you can reason about.

NameTypeReqDescription
absentboolean–Wait for the text to disappear instead of appear.
textstringyesText to wait for, matched case-insensitively.
timeout_snumber–How long to wait.

Structured output declared, but exposes no named fields.

No examples provided.

Install

How do I install the ios-agent MCP server?

ios-agent runs locally as a PyPI package, launched with uvx ios-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

pypi · ios-mcp

# add to Claude Code
claude mcp add emazaheri-ios-agent -- uvx ios-mcp
Common questions

What is the ios-agent MCP server?

ios-agent is an MCP server listed in the public MCP registry as io.github.emazaheri/ios-agent. Drive a real iPhone or an iOS Simulator with an AI agent, through XCUIAutomation. This page covers its PyPI package (ios-mcp).

Is the ios-agent MCP server safe to use?

ios-agent scores 93 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 4 November 2026. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

What tools does the ios-agent MCP server expose?

ios-agent exposes 31 tools: ios_doctor, ios_list_devices, ios_open_session, ios_session_status, ios_close_session, and 26 more. Their descriptions and schemas cost roughly 2,963 tokens of context every time the server is loaded.

Is the ios-agent MCP server still maintained?

ios-agent is still listed as active in the MCP registry. We last reached this channel on 4 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

What licence is the ios-agent MCP server under?

ios-agent declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.