@mgcrea/mcp-ios-simulator
Provides tools for driving an iOS Simulator, including screen capture, accessibility tree inspection, touch input (tap, swipe, type), app management, device staging (appearance, permissions, location), and push notification delivery.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@@mgcrea/mcp-ios-simulatortake a screenshot and read the accessibility tree of the current app"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
@mgcrea/mcp-ios-simulator
Model Context Protocol server for driving an iOS Simulator from a model: screenshot the screen, read its accessibility tree, tap, swipe, type, manage the app under test — and stage the device itself, which is the part no physical device can do.
No Apple Developer team. No code signing. No device trust. No tunnel. Nothing to unlock. And screenshots work with nothing installed at all.
Features
See the screen, with zero setup.
simctlcaptures it directly, scaled to exactly the device's point size, so a position read off the image is a tap coordinate with no conversion. No WebDriverAgent needed for this.Read the screen. A flattened, pruned accessibility tree — type, label, identifier and the precomputed tap point per element — instead of the tens of KB of nested JSON WebDriverAgent actually returns.
Drive the screen. Tap by coordinate or by accessibility label, swipe, type, press Home. Every action returns the resulting screen by default, so a mis-aimed tap is visible on the call that made it.
Stage the device. Dark mode, Dynamic Type size, increased contrast, a frozen 9:41 status bar, a simulated location, and app permissions granted or denied without a prompt anyone has to tap. None of this is possible on real hardware.
Push without APNs. Deliver a real remote notification with no certificate and no server.
Manage the app. Install a build, launch it with fixture arguments, terminate it, open a deep link. An app's data container is an ordinary path on this Mac, so its database or logs are read directly — there is nothing to copy off a device.
Related MCP server: Shotter
Security
Writes are on by default, and that is deliberate. The rest of the fleet is
read-only until a flag is set because a mutating tool acts on someone's real
account or someone's real phone. A simulator is neither: it holds no person's
data, and ios_simulator_erase puts it back to factory in seconds.
What that still costs you, stated honestly:
installandlaunchrun code on your Mac. A simulated process is a host process.The app's data container is a plain host path, readable by anything.
eraseis irreversible — it is the only tool behind an explicitconfirm.IOS_SIMULATOR_ALLOW_WRITES=0restores the device server's posture in one variable, and then the fourteen driving tools are absent fromtools/listrather than refused, because a refusal still lets a model try, retry and reason about a way around it.
Your credentials. There are none. The server holds no tokens and talks to no
vendor API. Everything goes through xcrun simctl and a loopback HTTP server.
Supply chain. Three runtime dependencies: @modelcontextprotocol/server,
zod, and @mgcrea/mcp-ios-core — our own, and itself
dependent on only the first two. Scaling images uses sips and reading property
lists uses plutil, both of which ship with macOS, specifically so neither an
image library nor a plist parser has to be installed.
How it reaches the simulator
Lane | Carries | Needs |
| simulators, apps, install, launch, deep links, the screenshot, appearance, status bar, location, permissions, push, boot/shutdown/erase | Xcode. Nothing else. |
WebDriverAgent over HTTP | the accessibility tree, tap, swipe, type, buttons | a runner started once with |
The asymmetry with mcp-ios-device is worth stating plainly: there, every
pixel comes through WebDriverAgent, so nothing about the screen works until a
signed runner is installed and trusted on the phone. Here simctl captures the
screen itself, so fourteen of the nineteen tools work with no runner at all
— only ios_simulator_ui_tree and the five input tools need one, and building it
takes about two minutes with no Apple account.
ios_simulator_diagnostics reports both lanes separately, so "the simulator is
fine but the runner is not up" is a distinguishable answer rather than a generic
failure.
Configure
Variable | Default | What it does |
| the only booted simulator | UDID, name, or |
| on |
|
| none | Launch arguments applied when |
|
| Must match the runner's |
|
| Explicit override; rarely needed. |
|
| Byte cap on a |
|
| Budget for one |
|
| Budget for one WebDriverAgent call. |
|
| Screenshots, launch logs, the runner log. |
| off | Log every |
The same keys in camelCase can go in ~/.config/ios-simulator-mcp/config.json
(IOS_SIMULATOR_CONFIG to move it). The environment wins per field, so a
one-off IOS_SIMULATOR_ALLOW_WRITES=0 beats a file that says true. Unknown keys
in the file are an error rather than silently ignored — a typo that looks like
"that setting had no effect" is the worst way to learn where your configuration
came from.
See .env.example for the annotated version.
Quick start
Requires macOS with Xcode and a booted simulator.
A. Everything except the tree and the taps, with no setup
npx -y @mgcrea/mcp-ios-simulatorlist, list_apps, screenshot, diagnostics, power, install, launch,
open_url, set_environment, push and erase all work immediately.
B. The input lane
ui_tree, tap, tap_element, swipe, type and press_button need a
WebDriverAgent runner. Build and start it — no team id, no signing, no prompt:
scripts/wda.sh setup # ~2 minutes
scripts/wda.sh run # leave this running
scripts/wda.sh status # is it answering?Installed from npm, the same script is the ios-simulator-wda binary:
npx -p @mgcrea/mcp-ios-simulator ios-simulator-wda setup
npx -p @mgcrea/mcp-ios-simulator ios-simulator-wda runC. Wired into a client
See .mcp.json.example.
Tools
Twenty-one. Six are read-only; the other fifteen disappear with
IOS_SIMULATOR_ALLOW_WRITES=0.
Tool | Writes? | What it does |
| Every simulator, with state and whether its runtime is installed | |
| Both lanes, the resolved target, the geometry, and who owns the WDA port | |
| Installed apps, with bundle id and host-path data container | |
| The screen, in point space — no runner needed | |
| Addressable elements with precomputed tap points | |
| Poll until something appears, or goes away | |
| ✓ | Tap a point |
| ✓ | Tap by identifier, label or predicate |
| ✓ | Drag between two points |
| ✓ | Type into the focused field, or a named one |
| ✓ | Home |
| ✓ | Boot or shut down; never implicit |
| ✓ confirm | Wipe to factory — the only irreversible tool |
| ✓ | Install a simulator |
| ✓ | Launch, with fixture arguments and captured output |
| ✓ | Kill a running app |
| ✓ | Deep links and universal links |
| ✓ | Appearance, Dynamic Type, contrast, status bar, location, permissions |
| ✓ | Seed the photo library — the way around the missing camera |
| ✓ | A remote notification, with no APNs certificate |
| ✓ | Start or restart the runner, detached |
Deliberately absent: create, clone, delete, rename, upgrade and pair
(fleet management, not driving, and delete all is a footgun with no upside);
get_app_container (list_apps already returns the path); uninstall
(install overwrites, and erase covers first-run properly); keychain,
pbcopy, spawn, diagnose and recordVideo (real capabilities that an agent
would use approximately never, and every tool costs listing bytes on every
connect).
addmedia was on that list until 0.2.0, and it was the wrong call. A simulator
has no camera, so seeding the photo library is not a nice-to-have — it is the
only way an app whose first step is "choose a photo" can be driven here at all.
Anyone hitting that had to drop out to a shell, which is exactly what these
tools exist to avoid.
Traps worth knowing
All measured on Xcode 26.6 (17F113).
simctl io … screenshot -does not write to stdout. The help text says it does. It creates a file literally named-in the current working directory and printsWrote screenshot to: …to stderr, exit 0. This server always passes a real path.simctl ioon a simulator whose runtime is missing aborts — SIGABRT, exit 134, an uncaughtNSInternalInconsistencyExceptionand a thirty-line stack trace, not an error message. Availability is checked in the resolver, before the call. On a typical machine a large fraction of simulators are in this state.erase,deleteandshutdownall accept the literalall. A target of"all"reachingsimctl erasewipes every simulator on the machine. Refused in the resolver and again in the adapter.bootedis a coin flip. simctl's own help: "If multiple devices are booted … simctl will choose one of them." Resolved to a concrete UDID here first.WebDriverAgent scans ports 8100-8199 when
USE_PORTis unset. With two booted simulators, the second runner comes up healthy on 8101 and a server pointed at 8100 drives the first one while every call reports success.scripts/wda.shalways pinsUSE_PORT, anddiagnosticsreports the port's real owner viaSIMULATOR_UDIDfromps -Eww.listappsreturns an old-style NeXTSTEP plist, not JSON.--jsonis a flag onlistand nothing else.A status bar override survives a reboot. Clear it or it quietly pollutes every later screenshot.
simctl launchenvironment variables need aSIMCTL_CHILD_prefix on the calling process, not a flag.A label belongs to the control and to every container around it. WebDriverAgent answers depth-first, so an unqualified label match lands on the navigation bar as readily as on the button — and a tap on a container does nothing while reporting success.
tap_elementnarrows a label to the interactive types first, and sayspreferredControlwhen it did.isVisibleis not always truthful. APHPickerpresented over Safari reports all nine of its asset cellsisVisible: "0"while they are on screen and tappable — a synthesised tap on one opens the preview. The defaultui_treefilter drops them, which is why the result carries afilteredtally: a short list that has been filtered and a screen that is genuinely bare are otherwise the same answer.simctl installwants a.appbundle directory built for the simulator — an.ipaor a device build fails with "No such file or directory", which reads like a path typo.simctl bootgives you no window. It runs headless, which is what an agent wants and confusing the first time;poweropens Simulator.app by default.Two runtimes can share one identifier, so the key of
list devicesis not a primary key.
Develop
pnpm install
pnpm lint && pnpm format:check && pnpm typecheck && pnpm test && pnpm buildLicense
MIT — see LICENSE.
Available Tools
21 toolsios_simulator_add_mediaiOS Simulator: Add MediaA
Put photos or videos into the simulator's photo library. A simulator has no camera, and this is how you get around that: seed the library first, then drive the app's picker as normal. Without it, every flow that starts with an image is untestable here. Files are copied in, so the originals are untouched and the simulator keeps them until it is erased. Pair it with permission on ios_simulator_set_environment to skip the access prompt entirely.
| Name | Required | Description | Default |
|---|---|---|---|
| paths | Yes | Absolute paths to the images or videos, e.g. ["/Users/me/fixtures/monstera.jpg"]. Formats are the ones Photos itself accepts — JPEG, PNG, HEIC, MOV, MP4. | |
| device | No | Which simulator: its UDID or its name as shown by ios_simulator_list. Omit it when exactly one is booted — that is the normal case, and IOS_SIMULATOR_ID pins it when it is not. Unlike simctl's own `booted`, this never picks arbitrarily between two. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say non-read-only, non-idempotent, non-destructive. The description adds meaningful behavioral detail beyond those flags: 'Files are copied in, so the originals are untouched and the simulator keeps them until it is erased.' This clarifies persistence, non-destructiveness to source files, and the fact that the simulator's library is mutated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is about five sentences long, but every sentence earns its place: purpose, motivation, workflow, side effects, and integration with a sibling tool. It is front-loaded with the core function and avoids filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with two parameters, no output schema, and only generic annotations, the description plus schema gives an agent everything needed to select and invoke it correctly: what it does, why it exists, how to sequence it in a test flow, what side effects to expect, and how to combine it with permission handling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already has 100% description coverage with clear explanations for both `paths` and `device`, so the baseline is 3. The description does not add parameter-level semantics beyond the schema; it provides useful workflow context, but the schema itself carries the parameter documentation burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and noun: 'Put photos or videos into the simulator's photo library.' This clearly distinguishes it from sibling tools like screenshot, install, or launch, none of which address media seeding. It also gives the motivating problem ('A simulator has no camera'), so an agent understands exactly what unique gap this tool fills.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description is explicit about when and how to use the tool: seed the library first, then drive the app's picker as normal. It states the consequence of not using it ('every flow that starts with an image is untestable here') and even gives complementary guidance by pairing it with `permission` on ios_simulator_set_environment to skip the access prompt.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ios_simulator_diagnosticsiOS Simulator: DiagnosticsARead-only
Report both lanes separately and never fail: which simulators exist and which are usable, which one this server would drive, its screen geometry, and whether WebDriverAgent is answering — including which simulator owns its port, which is the one way to catch a second runner quietly taking your taps. Start here when anything else misbehaves.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Which simulator: its UDID or its name as shown by ios_simulator_list. Omit it when exactly one is booted — that is the normal case, and IOS_SIMULATOR_ID pins it when it is not. Unlike simctl's own `booted`, this never picks arbitrarily between two. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description adds meaningful behavioral context: it reports 'both lanes separately', 'never fail[s]', and can detect a second runner by identifying which simulator owns the WDA port. This gives the agent useful expectations about reliability and output structure without contradicting the annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but efficient, front-loading the core behavior ('Report both lanes separately and never fail') before enumerating the diagnostic contents. The later clauses about catching a second runner are slightly wordy but still earn their place by clarifying a key diagnostic use case.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by enumerating the major output categories: existing/usable simulators, the server-selected simulator, screen geometry, and WDA port ownership. This is enough for an agent to know what to expect, though exact output formatting remains unspecified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides full coverage for the optional 'device' parameter, including guidance on omitting it and the distinction from simctl's 'booted'. The tool description itself adds no parameter-specific detail, so the high schema coverage establishes the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific action ('Report') and a concrete diagnostic resource: simulator existence/usability, server-chosen simulator, screen geometry, and WDA status with port ownership. This distinguishes it from sibling tools like ios_simulator_list or ios_simulator_restart_wda by emphasizing an aggregated diagnostic report.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'Start here when anything else misbehaves' provides explicit situational guidance for when to invoke this tool. It does not spell out exclusions or contrast itself against specific sibling tools, but the context is clear enough for an agent to select it as a first-line diagnostic.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ios_simulator_eraseiOS Simulator: EraseADestructive
Wipe a simulator back to a factory state: installed apps, their data, the keychain and every granted permission. The only irreversible tool here, and the reason it is the only one behind confirm. Use it to test a genuine first launch. A booted simulator is shut down first and booted again afterwards, because simctl refuses to erase a running one.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Which simulator: its UDID or its name as shown by ios_simulator_list. Omit it when exactly one is booted — that is the normal case, and IOS_SIMULATOR_ID pins it when it is not. Unlike simctl's own `booted`, this never picks arbitrarily between two. | |
| confirm | Yes | Must be true. Explicit acknowledgement that this changes state on a real simulator. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the destructiveHint annotation, the description discloses what state is destroyed, that the operation is irreversible, and that a booted simulator is automatically shut down and rebooted because simctl refuses to erase a running device. This is valuable behavioral context the annotations alone do not provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences with no filler: what is wiped, why it is gated, when to use it, and how booted state is handled. Information is front-loaded and every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive, confirmed erase operation with no meaningful output schema, the description covers the full behavioral contract: scope of destruction, irreversibility, confirmation requirement, intended use, and side effects on boot state. Nothing essential is missing for an agent to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and the schema itself already documents both parameters thoroughly: device explains UDID/name behavior and IOS_SIMULATOR_ID pinning, while confirm explains the acknowledgement requirement. The tool description adds only the fact that confirm is the reason this tool is gated, so it does not need to compensate for missing parameter documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource ('Wipe a simulator') and lists exactly what gets reset: installed apps, their data, keychain, and granted permissions. It distinguishes itself from siblings by calling itself 'the only irreversible tool here', so an agent can tell it apart from install, terminate, and power-related tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says to use the tool 'to test a genuine first launch', which gives a clear positive use case. It also signals caution by noting irreversibility and the confirm requirement, though it does not explicitly name alternative tools or list when-not-to-use conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ios_simulator_installiOS Simulator: InstallAIdempotent
Install a build. The path must be a .app bundle directory built for the simulator — not an .ipa, and not a device build, both of which fail with a bare "No such file or directory" that reads like a typo. Installing over an existing copy replaces it and keeps its data.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute path to the .app bundle, e.g. ~/Library/Developer/Xcode/DerivedData/…/Build/Products/Debug-iphonesimulator/Foo.app | |
| device | No | Which simulator: its UDID or its name as shown by ios_simulator_list. Omit it when exactly one is booted — that is the normal case, and IOS_SIMULATOR_ID pins it when it is not. Unlike simctl's own `booted`, this never picks arbitrarily between two. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses the important overwrite behavior: installing over an existing copy replaces it and keeps its data. It also explains the misleading 'No such file or directory' failure mode for invalid builds, which is exactly the kind of context an agent needs to interpret errors correctly. This adds real value beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences deliver the core instruction, the key input constraint, the failure mode, and the overwrite behavior with no filler. The most important constraint is front-loaded, and every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter install operation with no output schema, the description covers the required input shape, the common failure cases, and the side effect of reinstalling. Device-selection details are already fully specified in the schema, so nothing necessary for a correct call is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already documents both the .app path format and the device-selection rules, so the baseline is 3. The description adds meaning by explaining that .ipa and device builds fail with a confusing error, which sharpens the agent's understanding of the path parameter beyond the schema alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with the specific action 'Install a build' and precisely identifies the target resource as a simulator-built .app bundle. It also clearly separates this from invalid inputs like .ipa and device builds, making the tool's purpose easy to distinguish from sibling tools such as ios_simulator_launch.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The primary use case is explicit: install a simulator build from a .app bundle. It also gives strong negative guidance by warning that .ipa files and device builds fail. It does not explicitly name an alternative tool for launching or listing apps, but the install operation itself is unambiguous enough that no direct sibling comparison is required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ios_simulator_launchiOS Simulator: LaunchA
Launch an installed app. Pass arguments to put it into a fixture or demo mode — that is what IOS_SIMULATOR_LAUNCH_ARGS sets as the default for every launch that does not override it. Standard output and error are captured to files under the output directory, so an app that dies on launch leaves something readable behind.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Which simulator: its UDID or its name as shown by ios_simulator_list. Omit it when exactly one is booted — that is the normal case, and IOS_SIMULATOR_ID pins it when it is not. Unlike simctl's own `booted`, this never picks arbitrarily between two. | |
| arguments | No | Launch arguments, e.g. ["-DemoMode", "YES"]. Overrides IOS_SIMULATOR_LAUNCH_ARGS rather than adding to it. | |
| bundle_id | Yes | The app's bundle identifier, e.g. "io.mgcrea.Canopy". List them with ios_simulator_list_apps. | |
| terminate_first | No | Replace a running copy rather than attaching to it. On by default so a launch means a fresh process and a predictable first screen. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are all false, so the description carries the behavioral burden. It adds useful detail: stdout and stderr are captured to files under the output directory, and a launch that crashes leaves readable artifacts. It also explains the IOS_SIMULATOR_LAUNCH_ARGS default behavior beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler. The primary purpose is front-loaded, and the second sentence packs meaningful behavioral detail about output capture and crash diagnostics.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-parameter tool with full schema coverage and no output schema, the description provides enough behavioral and parameter context to invoke the tool correctly. It could mention return behavior or explicit sibling alternatives, but those are minor gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds extra meaning by framing `arguments` as a fixture/demo-mode hook and explaining the relationship with IOS_SIMULATOR_LAUNCH_ARGS. This goes beyond simply restating the schema's parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Launch an installed app.' The qualifier 'installed' distinguishes it from install/list workflows, and the title/name are expanded with actual scope. An agent can tell this is the launch tool rather than install, terminate, or open_url.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear context about launching installed apps and using arguments for fixture/demo mode, but it never explicitly says when to prefer this tool over siblings. The guidance is mostly implied rather than stated with alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ios_simulator_listiOS Simulator: ListARead-only
List the simulators on this machine, with the UDID every other tool takes. Shows the usable ones: a typical machine carries thirty-odd simulators and a good fraction of them are orphans whose runtime is no longer installed, which cannot be booted, driven or screenshotted at all. The result still says how many were left out and how to delete them, and include_unavailable brings them back with available: false and the reason, so "why can't I use that one" is still answerable here.
| Name | Required | Description | Default |
|---|---|---|---|
| booted_only | No | Only simulators that are currently running. | |
| name_contains | No | Case-insensitive substring filter on the name, e.g. "iPhone 17". | |
| include_unavailable | No | Also list simulators whose runtime is not installed. Off by default because they are not usable for anything; turn it on to see why a specific one is missing. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses substantial behavior: unavailable simulators are filtered out, the result reports how many were omitted and how to delete them, and include_unavailable reveals them with available: false and the reason. This is rich, non-obvious behavior that an agent needs to know.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose is front-loaded in the first sentence. The subsequent illustrative detail about typical simulators is useful context but slightly extended; it earns its place by justifying the default filtering, yet could be trimmed without losing essential guidance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite lacking an output schema, the description covers the essential return values: UDID, available flag, reason, and count of excluded simulators. It also explains the default filtering and how to opt into seeing unavailable ones, making the tool self-sufficient for an agent to invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds extra meaning for include_unavailable, explaining the returned available: false flag and the reason, which goes beyond the schema. booted_only and name_contains are already well documented in the schema, so no further elaboration is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool 'List the simulators on this machine' and highlights the key output, the UDID, which every other tool consumes. This distinguishes it from sibling tools like ios_simulator_list_apps, which lists apps rather than simulators.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: it shows usable simulators by default, and explains when to use include_unavailable to understand why a simulator is missing. It implies this is the tool to obtain a UDID for other tools, though it does not explicitly name alternatives or state 'use this before X'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ios_simulator_list_appsiOS Simulator: List AppsARead-only
List the apps installed on a simulator, with the bundle id every other tool takes. Defaults to your own apps: a stock simulator carries about thirty, and twenty-five of them are Apple's. Each entry also carries dataContainer — an ordinary path on this Mac, so an app's database or logs can be read directly with no copy step.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Which simulator: its UDID or its name as shown by ios_simulator_list. Omit it when exactly one is booted — that is the normal case, and IOS_SIMULATOR_ID pins it when it is not. Unlike simctl's own `booted`, this never picks arbitrarily between two. | |
| include_all | No | Include Apple's built-in apps as well. Off by default; the list is long. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses meaningful behavior: results are filtered to the user's own apps by default, stock simulators contain about thirty apps, and each entry exposes a real filesystem path in dataContainer that enables direct reads. This is rich, non-obvious context that helps an agent trust and interpret the result.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with no filler: the main purpose is front-loaded, followed by high-value behavioral details and a practical note about dataContainer. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only listing tool with two optional parameters and no output schema, the description plus schema fully cover how to invoke it, what the output will contain, and how to use the returned values. Nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents both parameters fully, including the device ambiguity rule and include_all default, so the description does not need to add parameter-level detail. The description's 'Defaults to your own apps' reinforces include_all but adds little beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action and resource: 'List the apps installed on a simulator', and immediately adds the key value proposition that it returns the bundle id used by other tools. This clearly separates it from sibling tools like ios_simulator_list and ios_simulator_ui_tree.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives practical context for when to use the tool: to obtain bundle ids that other tools consume, and it explains the default filtering behavior. It does not explicitly name an alternative or state a when-not-to-use condition, but the purpose is so distinct that the omission is minor.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ios_simulator_open_urliOS Simulator: Open URLA
Open a URL on the simulator, which is how you exercise a deep link or a universal link without finding a way to tap one. An https:// link opens in Safari unless the app claims it; a custom scheme goes straight to whichever app registered it.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | e.g. "myapp://garden/42" or "https://example.com/garden/42". | |
| device | No | Which simulator: its UDID or its name as shown by ios_simulator_list. Omit it when exactly one is booted — that is the normal case, and IOS_SIMULATOR_ID pins it when it is not. Unlike simctl's own `booted`, this never picks arbitrarily between two. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are neutral (no readOnly/destructive hints), so the description carries the behavioral burden. It discloses non-obvious routing behavior for https vs custom schemes, which is valuable context beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences: the first front-loads the purpose, the second adds a key behavioral detail. No filler or repetition of schema content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter tool with no output schema, the description plus detailed parameter schema covers purpose, usage context, scheme behavior, and device selection. Nothing needed for a correct call is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds extra meaning by explaining how the URL's scheme affects behavior, helping an agent choose an appropriate value beyond the schema's examples.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States the exact action ('Open a URL on the simulator') and the purpose ('exercise a deep link or a universal link'), immediately distinguishing it from tap-based sibling tools. The additional scheme-routing details further clarify what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a clear use case: when you need to exercise a deep/universal link without tapping one. It implies this tool overrides manual tapping but does not explicitly name alternatives or exclusions, so it misses a fully explicit routing statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ios_simulator_poweriOS Simulator: PowerAIdempotent
Boot or shut down a simulator. Booting is the one thing this server will not do for you implicitly — a cold boot takes tens of seconds and puts a window on the user's screen, and it changes which simulator an unqualified call resolves to afterwards. Both directions are idempotent: booting a booted simulator succeeds.
| Name | Required | Description | Default |
|---|---|---|---|
| state | Yes | The state to put it in. `booted` also waits for it to actually get there. | |
| device | No | Which simulator: its UDID or its name as shown by ios_simulator_list. Omit it when exactly one is booted — that is the normal case, and IOS_SIMULATOR_ID pins it when it is not. Unlike simctl's own `booted`, this never picks arbitrarily between two. | |
| wait_ms | No | How long to wait for a boot to complete before reporting what it saw. | |
| open_window | No | Bring up the Simulator app so the screen is visible. A `boot` on its own is headless, which is fine for an agent and confusing for a person watching. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (idempotentHint=true), the description discloses operational details: a cold boot takes tens of seconds, puts a window on the user's screen, and changes which simulator an unqualified call resolves to afterwards. It also states that both boot and shutdown are idempotent, adding behavioral nuance not present in the annotations. This gives the agent a realistic expectation of side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, each with a distinct purpose: stating the action, explaining the critical boot implications, and clarifying idempotency. It is front-loaded with the primary function. Slightly verbose due to the compound second sentence, but every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a four-parameter tool with no output schema, the description covers the key operational aspects: boot/shutdown, idempotency, waiting behavior via `wait_ms`, the headless default, and the unqualified-call resolution shift. It could explicitly describe shutdown side effects, but the idempotency statement covers both directions. The absence of an output schema is mitigated by the description's behavioral clarity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides 100% coverage with descriptions for all four parameters, including the meaning of `booted` waiting and the `booted` selection rule. The description adds context about idempotency and the resolution change, which enriches the `device` parameter's meaning, but this is marginal on top of thorough schema documentation. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Boot or shut down a simulator.' This clearly defines the tool's purpose and distinguishes it from sibling tools like ios_simulator_list, ios_simulator_launch, or ios_simulator_diagnostics, which serve different functions. The additional context about implicit booting further clarifies its unique role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly notes that 'Booting is the one thing this server will not do for you implicitly,' telling the agent when an explicit boot call is necessary. It also explains the consequences of booting (tens of seconds, window on screen, changing unqualified call resolution), which guides whether to use this tool proactively. It does not name sibling alternatives explicitly, but the usage context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ios_simulator_press_buttoniOS Simulator: Press ButtonA
Press a hardware button. home is the way back to the home screen and the reliable way to background the app under test without terminating it.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Which button. `home` works on Face ID devices too — it is the gesture, not the physical button. | |
| device | No | Which simulator: its UDID or its name as shown by ios_simulator_list. Omit it when exactly one is booted — that is the normal case, and IOS_SIMULATOR_ID pins it when it is not. Unlike simctl's own `booted`, this never picks arbitrarily between two. | |
| settle_ms | No | Milliseconds to wait before the follow-up screenshot, so an animation finishes first. Raise it for a screen that loads data; a capture taken mid-transition shows neither state. This is a pause for an animation, not a wait for work to finish — which is why it stops at ten seconds. For anything longer, use ios_simulator_wait_for_element. | |
| screenshot | No | Return a screenshot of the resulting screen. On by default, and worth leaving on: it is how you find out that the action landed where you meant it to. Turn it off only for a sequence whose intermediate states you do not need to see. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only supply readOnly/idempotent/destructive hints; the description adds the key behavioral consequence that home backgrounds the app without terminating it, and the schema notes that home is a gesture on Face ID devices. It does not contradict the annotations and gives useful behavioral context beyond the structured hints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences with the verb and resource front-loaded and the most useful guidance in the second sentence. There is no filler or repetition of what the schema already states.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich per-parameter descriptions, the annotations, and the simplicity of the action, an agent has enough to select and invoke the tool correctly. The lack of an output schema is mitigated by the screenshot parameter explicitly describing the returned screenshot behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3; the tool description adds value by explaining what the `home` parameter accomplishes (returning home/backgrounding without termination). The remaining parameters are already richly described in the schema, including device-selection behavior and settle_ms semantics, so the overall parameter guidance is strong.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a concrete action ('Press a hardware button') and immediately explains the purpose of the only supported button: returning to the home screen and backgrounding the app without terminating it. This clearly differentiates it from terminate, launch, screenshot, and other simulator actions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear when-to-use context: use home to go back to the home screen or to background the app safely without terminating it. The settle_ms parameter description further routes longer waits to ios_simulator_wait_for_element, but the prose does not enumerate exclusions for every sibling, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ios_simulator_pushiOS Simulator: PushA
Deliver a push notification, with no APNs certificate and no server. The payload is a normal remote-notification body and must contain an aps key. Only remote pushes are simulated — not VoIP, complications or file-provider. The app must be installed; it does not have to be running.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Which simulator: its UDID or its name as shown by ios_simulator_list. Omit it when exactly one is booted — that is the normal case, and IOS_SIMULATOR_ID pins it when it is not. Unlike simctl's own `booted`, this never picks arbitrarily between two. | |
| payload | Yes | The APNs payload, e.g. {"aps":{"alert":{"title":"Watering due","body":"Monstera"},"sound":"default","badge":1}}. Max 4096 bytes. | |
| bundle_id | Yes | The app's bundle identifier, e.g. "io.mgcrea.Canopy". List them with ios_simulator_list_apps. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only provide readOnly/idempotent/destructive hints, so the description carries most of the burden. It discloses the simulated nature, the payload requirement to contain an 'aps' key, and the fact that the app need not be running. It stops short of describing the visible result or any permission behavior, but the core behavior is clear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences with no filler. Each clause adds a necessary constraint or limitation, and the most important scoping information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-parameter action with a nested payload and no output schema, the description plus schema gives the agent everything needed to invoke it correctly: device selection behavior, payload format and size, bundle id pattern, and push-type restrictions. No critical selection or invocation information is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds semantic value beyond the schema: it requires the payload to be a 'normal remote-notification body' containing an 'aps' key. The schema already covers device selection rules, the payload example, byte limit, and bundle id pattern.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with a specific verb and resource: 'Deliver a push notification' to the iOS simulator. It immediately distinguishes this tool from real APNs delivery by adding 'with no APNs certificate and no server,' and no sibling tool performs push, so there is no ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a clear context for use: simulator push testing without needing APNs infrastructure. It also states explicit exclusions ('not VoIP, complications or file-provider') and prerequisites ('The app must be installed; it does not have to be running'), though it does not name alternative tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ios_simulator_restart_wdaiOS Simulator: Restart WebDriverAgentA
Start the WebDriverAgent runner, or restart it after it has died. Only the UI tree and the input tools need it — screenshots and everything simctl does keep working without it. The runner is started detached so it outlives this conversation, and its output goes to a log file rather than to you. It does not wait: give it fifteen seconds or so, then check ios_simulator_diagnostics.
| Name | Required | Description | Default |
|---|---|---|---|
| port | No | Port to bind, passed to the runner as USE_PORT. Defaults to IOS_SIMULATOR_WDA_PORT. Two simulators need two ports: they share this Mac's loopback, and a runner with no USE_PORT scans 8100-8199 and silently takes the next free one. | |
| device | No | Which simulator: its UDID or its name as shown by ios_simulator_list. Omit it when exactly one is booted — that is the normal case, and IOS_SIMULATOR_ID pins it when it is not. Unlike simctl's own `booted`, this never picks arbitrarily between two. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses key behavioral traits: the runner is started detached, it outlives the conversation, output goes to a log file, and it does not wait. This is exactly the kind of context an agent needs to use the tool correctly and verify success.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, each earning its place: purpose, scope, runtime behavior, and verification step. The description is front-loaded with the core function and avoids fluff or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a side-effecting tool with no output schema, the description covers what the tool does, when to use it, what side effects to expect, how long to wait, and where to check results. That is sufficient for an agent to invoke and verify it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool description itself does not add parameter-level meaning, but the input schema provides 100% coverage with detailed descriptions for both `port` and `device`. Baseline 3 is appropriate because the schema already carries the semantic weight.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource: 'Start the WebDriverAgent runner, or restart it after it has died.' It clearly differentiates from siblings by stating that only UI tree and input tools need it, while screenshots and simctl operations do not.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says when this tool is needed and when it is not: 'Only the UI tree and the input tools need it.' It also gives the follow-up action ('check ios_simulator_diagnostics') and a timing expectation, which is strong practical guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ios_simulator_screenshotiOS Simulator: ScreenshotARead-only
Capture the screen and return it as an image. By default it is scaled to exactly the device's point size, which means a position read off this image can be passed straight to ios_simulator_tap with no conversion — the returned metadata says coordinateSpace: "points" when that holds. Pair it with ios_simulator_ui_tree rather than choosing between them: the image shows you what the screen looks like, the tree gives you exact labels and identifiers. Re-screenshot after every action rather than chaining blind taps.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Which simulator: its UDID or its name as shown by ios_simulator_list. Omit it when exactly one is booted — that is the normal case, and IOS_SIMULATOR_ID pins it when it is not. Unlike simctl's own `booted`, this never picks arbitrarily between two. | |
| quality | No | JPEG quality 1-100. Flat interface screenshots stay perfectly legible at 70. | |
| save_path | No | Also write the full-resolution PNG to this absolute path, for attaching to a bug report. The returned image is still the downscaled one. | |
| max_dimension | No | Longest side of the returned image, in pixels. Leave it unset unless you have a reason: the default matches the device's point size, and any other value makes image positions stop being tap coordinates (the result then reports `coordinateSpace: "image_pixels"` and the `pointsPerPixel` factor to multiply by). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses the key behavioral traits: default scaling to device point size, the resulting coordinateSpace metadata ('points'), the shift to image_pixels when max_dimension is overridden, and the fact that save_path writes a full-resolution PNG while 'the returned image is still the downscaled one.' This is exactly the kind of non-obvious behavior an agent needs to interpret results correctly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, each earning its place: core purpose, the critical coordinate-space behavior, sibling complementarity, and workflow rule. The most decision-relevant fact (tap-coordinate compatibility) is front-loaded in sentence two. No filler, no repetition of schema content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having no output schema, the description conveys the return semantics that matter (image plus coordinateSpace metadata), and the schema handles the four optional parameters exhaustively. The readOnly annotation covers the safety profile. Nothing an agent needs to invoke this correctly — coordinate systems, sibling relationships, workflow cadence, parameter trade-offs — is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3 — and indeed the schema's per-parameter descriptions are rich on their own. The main description adds one genuinely additive semantic: the default scaling means 'a position read off this image can be passed straight to ios_simulator_tap with no conversion,' which gives the default parameter behavior a concrete cross-tool consequence not stated in the schema. This nudges it above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource — 'Capture the screen and return it as an image' — and immediately distinguishes itself from the closest sibling, ios_simulator_ui_tree: 'the image shows you what the screen looks like, the tree gives you exact labels and identifiers.' An agent can tell exactly what this tool does and how it differs from alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit pairing guidance: 'Pair it with ios_simulator_ui_tree rather than choosing between them,' complete with the reason for each tool's role. It also prescribes a workflow rule ('Re-screenshot after every action rather than chaining blind taps') and the device parameter description further advises when to omit it. This is actionable usage direction, not just a vague context hint.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ios_simulator_set_environmentiOS Simulator: Set EnvironmentAIdempotent
Stage the simulator before a screenshot or a test: dark mode, Dynamic Type size, increased contrast, a frozen status bar, a simulated location, and app permissions. None of this is possible on a physical device, and it is most of the reason to prefer a simulator for UI work. Every field is optional; those given are applied in order and the result reports the state afterwards. A status bar override survives a reboot, so clear it when you are done or it quietly pollutes later screenshots.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Which simulator: its UDID or its name as shown by ios_simulator_list. Omit it when exactly one is booted — that is the normal case, and IOS_SIMULATOR_ID pins it when it is not. Unlike simctl's own `booted`, this never picks arbitrarily between two. | |
| location | No | Teleport the device, for location-gated screens. | |
| appearance | No | Interface style. | |
| permission | No | Set an app permission directly. This is how you reach the denied branch of a permission check, which is otherwise a prompt nobody can tap. | |
| status_bar | No | Freeze the status bar. Overrides persist until cleared. | |
| content_size | No | Dynamic Type size. The accessibility- sizes are where layouts break. | |
| clear_location | No | Stop simulating a location. | |
| clear_status_bar | No | Drop every status bar override, restoring the real one. | |
| increase_contrast | No | Increase Contrast accessibility mode. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations already marking the tool as non-read-only, idempotent, and non-destructive, the description adds important behavioral context beyond the annotations: fields are applied in order, the result reports the resulting state, and status bar overrides persist across reboots and can pollute later screenshots if not cleared. This is genuinely useful operational warning.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded. The first sentence states purpose and lists capabilities; the second justifies simulator preference; the third explains optionality and ordering; the fourth warns about persistence. Each sentence earns its place without redundancy or fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex 9-parameter tool with no output schema, the description covers the essential invocation semantics: optional fields, application order, state reporting, and the key persistence caveat. It doesn't detail what 'reports the state afterwards' includes, but given the strong schema coverage, this is complete enough for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds value by summarizing the parameter groups and by stating two cross-cutting facts not in the schema: every field is optional, and provided fields are applied in order. This helps an agent understand interactions between parameters like clear_location and location.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-resource pair: 'Stage the simulator before a screenshot or a test' and then enumerates the exact capabilities (dark mode, Dynamic Type, increased contrast, frozen status bar, simulated location, app permissions). This clearly distinguishes it from sibling tools like screenshot, tap, or launch, which do different jobs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear usage context: use this tool to prepare state before screenshots or tests. It also explains why simulator-only features matter for UI work. It does not explicitly name alternatives or exclusion conditions, but no sibling tool offers equivalent functionality, so the guidance is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ios_simulator_swipeiOS Simulator: SwipeA
Drag from one point to another, in points — how you scroll a list, pull to refresh, or swipe a row open. To scroll down a page, swipe from low on the screen to high on it. duration_ms is what separates a scroll from a fling: a short one throws the list past where you aimed.
| Name | Required | Description | Default |
|---|---|---|---|
| to_x | Yes | Horizontal position in points, from the left edge. This is the same space as the `tap` field from ios_simulator_ui_tree and as a default ios_simulator_screenshot image — no conversion. | |
| to_y | Yes | Vertical position in points, from the top edge. Same space as ios_simulator_ui_tree `tap` and a default ios_simulator_screenshot image. | |
| device | No | Which simulator: its UDID or its name as shown by ios_simulator_list. Omit it when exactly one is booted — that is the normal case, and IOS_SIMULATOR_ID pins it when it is not. Unlike simctl's own `booted`, this never picks arbitrarily between two. | |
| from_x | Yes | Horizontal position in points, from the left edge. This is the same space as the `tap` field from ios_simulator_ui_tree and as a default ios_simulator_screenshot image — no conversion. | |
| from_y | Yes | Vertical position in points, from the top edge. Same space as ios_simulator_ui_tree `tap` and a default ios_simulator_screenshot image. | |
| settle_ms | No | Milliseconds to wait before the follow-up screenshot, so an animation finishes first. Raise it for a screen that loads data; a capture taken mid-transition shows neither state. This is a pause for an animation, not a wait for work to finish — which is why it stops at ten seconds. For anything longer, use ios_simulator_wait_for_element. | |
| screenshot | No | Return a screenshot of the resulting screen. On by default, and worth leaving on: it is how you find out that the action landed where you meant it to. Turn it off only for a sequence whose intermediate states you do not need to see. | |
| duration_ms | No | How long the drag takes. 400 is a controlled scroll; under 150 becomes a fling with momentum, which lands somewhere you did not choose. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the minimal annotations, the description discloses that duration_ms distinguishes a controlled scroll from a momentum fling, and that short drags 'throw the list past where you aimed.' This adds meaningful behavioral context. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place: the core action, the practical direction mapping, and the duration behavior. The most important conceptual guidance is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description, combined with the richly documented 100% schema coverage, gives an agent everything needed to invoke the tool correctly. No output schema exists, but returning a screenshot is handled by the screenshot parameter, which is already documented.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds value by explaining the direction-to-screen relationship and the semantic difference between scroll and fling via duration_ms, which enriches the raw parameter meanings.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a concrete action and object: 'Drag from one point to another, in points.' It then names real user goals — scroll a list, pull to refresh, swipe a row open — which clearly separates it from sibling tap and type tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit guidance for when to use the gesture, including how to scroll down and what duration produces a fling. It does not explicitly name alternatives or state when not to use it, but the use cases are clear enough for an agent to select it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ios_simulator_tapiOS Simulator: TapA
Tap a position on screen, in points. Prefer ios_simulator_tap_element when the target has a label or an accessibility identifier — a position stops being right the moment the layout shifts, and nothing about a wrong tap looks wrong. Coordinates come from a default ios_simulator_screenshot image or from a tap field in ios_simulator_ui_tree, which are the same space.
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | Horizontal position in points, from the left edge. This is the same space as the `tap` field from ios_simulator_ui_tree and as a default ios_simulator_screenshot image — no conversion. | |
| y | Yes | Vertical position in points, from the top edge. Same space as ios_simulator_ui_tree `tap` and a default ios_simulator_screenshot image. | |
| device | No | Which simulator: its UDID or its name as shown by ios_simulator_list. Omit it when exactly one is booted — that is the normal case, and IOS_SIMULATOR_ID pins it when it is not. Unlike simctl's own `booted`, this never picks arbitrarily between two. | |
| hold_ms | No | How long to hold the touch, in milliseconds. Around 700 makes it a long press, which is what opens context menus and edit affordances. | |
| settle_ms | No | Milliseconds to wait before the follow-up screenshot, so an animation finishes first. Raise it for a screen that loads data; a capture taken mid-transition shows neither state. This is a pause for an animation, not a wait for work to finish — which is why it stops at ten seconds. For anything longer, use ios_simulator_wait_for_element. | |
| screenshot | No | Return a screenshot of the resulting screen. On by default, and worth leaving on: it is how you find out that the action landed where you meant it to. Turn it off only for a sequence whose intermediate states you do not need to see. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only carry readOnly/destructive/idempotent hints, all false, so they don't reveal failure modes. The description adds meaningful behavioral context: coordinate taps silently break after layout changes and 'nothing about a wrong tap looks wrong.' This is the kind of behavioral warning that helps an agent decide between coordinate and element taps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences each carry distinct value: what the tool does, when not to use it, and how coordinates are sourced. The warning is front-loaded right after the purpose, before any lower-priority detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description plus fully documented input schema give an agent everything needed to select and invoke the tool correctly: purpose, coordinate space, failure mode, and parameter semantics. It stops short of explicitly describing the return value beyond the screenshot parameter, but the schema already covers that detail.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema covers 100% of parameters with detailed descriptions, including units, defaults, and distinctions like 'pause for animation, not wait for work.' The description reinforces the coordinate-space relationship, but does not need to compensate for schema gaps because none exist.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb and object — 'Tap a position on screen, in points' — and immediately differentiates itself from ios_simulator_tap_element by naming the condition under which the element-based sibling should be preferred. The coordinate-source sentence also anchors exactly what the tool acts on.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit routing guidance: prefer ios_simulator_tap_element when the target has a label or accessibility identifier, with a concrete reason (layout shifts make coordinates stale). It also tells the agent where coordinates come from — default screenshot or ui_tree tap field — closing the main usage ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ios_simulator_tap_elementiOS Simulator: Tap ElementA
Tap the element with this accessibility identifier or label, letting the device resolve its position. This is the tool to reach for: it survives the screen scrolling, the layout changing and the copy being reworded, none of which a coordinate does. Give exactly one of id, label or predicate; identifiers from ios_simulator_ui_tree.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Accessibility identifier — the `id` field from ios_simulator_ui_tree, e.g. "garden.tab". The most durable way to address an element, because it is set in code and does not change when the visible text does. | |
| index | No | Which match to tap when several match, zero-based, counted in the order ios_simulator_ui_tree lists them. Giving it turns off the control preference `label` normally applies, because it means you have read the tree and are counting real positions in it. Leave it off unless that is what you are doing. | |
| label | No | Exact accessibility label, i.e. the visible text — e.g. "Today". Matched exactly, and it changes with the app's language, so prefer `id` where one exists. A label is shared by a control and every container around it, so this matches controls first and falls back to the rest only when no control carries it. | |
| device | No | Which simulator: its UDID or its name as shown by ios_simulator_list. Omit it when exactly one is booted — that is the normal case, and IOS_SIMULATOR_ID pins it when it is not. Unlike simctl's own `booted`, this never picks arbitrarily between two. | |
| predicate | No | Escape hatch: a raw NSPredicate over element attributes, e.g. `type == "XCUIElementTypeButton" AND label BEGINSWITH "Add"`. | |
| settle_ms | No | Milliseconds to wait before the follow-up screenshot, so an animation finishes first. Raise it for a screen that loads data; a capture taken mid-transition shows neither state. This is a pause for an animation, not a wait for work to finish — which is why it stops at ten seconds. For anything longer, use ios_simulator_wait_for_element. | |
| screenshot | No | Return a screenshot of the resulting screen. On by default, and worth leaving on: it is how you find out that the action landed where you meant it to. Turn it off only for a sequence whose intermediate states you do not need to see. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
It discloses useful behavioral traits beyond annotations: the device resolves the element's position, and the approach is robust to scrolling, layout changes, and reworded copy. Annotations only cover read-only/idempotent/destructive hints, so this extra context genuinely helps an agent predict behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences with no filler: the core action comes first, followed by the rationale and the essential param rule. The 'identifiers from ios_simulator_ui_tree' note is compact and useful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter action tool with no output schema, the description covers the main decisions an agent must make: which selector to use, where identifiers come from, and how this differs from coordinates. The screenshot parameter description already clarifies the output expectation, though the description itself could have mentioned what happens on no-match or multiple-match cases.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents all 7 parameters thoroughly, so this dimension starts near baseline. The description adds a key semantic constraint not enforced by the schema: exactly one of id, label, or predicate must be provided, and it points to ios_simulator_ui_tree as the source of identifiers.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and object: tap an element by accessibility identifier or label. It also contrasts itself with coordinate-based interaction, signaling clearly that this is the element-aware counterpart to ios_simulator_tap.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly frames this as 'the tool to reach for' when the element may move or the text may change, and explains why it beats coordinate-based taps. It does not name ios_simulator_tap or list exclusions, but the usage context is clear and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ios_simulator_terminateiOS Simulator: TerminateAIdempotent
Kill a running app. The app is not uninstalled and its data is untouched — this is how you get back to a cold start without erasing anything.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Which simulator: its UDID or its name as shown by ios_simulator_list. Omit it when exactly one is booted — that is the normal case, and IOS_SIMULATOR_ID pins it when it is not. Unlike simctl's own `booted`, this never picks arbitrarily between two. | |
| bundle_id | Yes | The app's bundle identifier, e.g. "io.mgcrea.Canopy". List them with ios_simulator_list_apps. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide idempotentHint=true and destructiveHint=false, and the description adds meaningful context: the app is not uninstalled, its data remains intact, and the result is a cold start. This goes beyond the structured hints without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no filler. It front-loads the core action, then immediately states the key behavioral nuance (no uninstall, data untouched) and the practical purpose (cold start).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter kill operation, the description plus schema and annotations cover what an agent needs: required bundle_id, optional device selection guidance, non-destructive behavior, idempotency, and the use case. No out-of-schema return format is necessary for a command like this.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents both parameters fully, so the baseline is 3. The description adds value for the optional device parameter by explaining when to omit it, how IOS_SIMULATOR_ID applies, and that it avoids simctl's arbitrary selection behavior, which helps an agent pick the right value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Kill a running app') and a clear resource, and goes beyond a simple restatement of the title by explaining what it does not do: it does not uninstall the app and does not touch its data. This distinguishes it from destroy/erase-style operations, and 'back to a cold start without erasing anything' sharpens the intended effect.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a clear context for use: when you want a cold start without erasing app data. It implicitly contrasts with uninstall/erase operations, though it does not explicitly name an alternative sibling tool or say when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ios_simulator_typeiOS Simulator: TypeA
Type text into whatever currently has keyboard focus, or into a named field. Focus is the trap: with nothing focused the keystrokes go nowhere and the call still succeeds, so pass id or label to have the field tapped first unless you know a field is already active.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Accessibility identifier of the field to focus first — from ios_simulator_ui_tree. | |
| text | Yes | The text to type. Sent character by character, as a real keyboard would. | |
| label | No | Exact label of the field to focus first, if it has no identifier. | |
| device | No | Which simulator: its UDID or its name as shown by ios_simulator_list. Omit it when exactly one is booted — that is the normal case, and IOS_SIMULATOR_ID pins it when it is not. Unlike simctl's own `booted`, this never picks arbitrarily between two. | |
| settle_ms | No | Milliseconds to wait before the follow-up screenshot, so an animation finishes first. Raise it for a screen that loads data; a capture taken mid-transition shows neither state. This is a pause for an animation, not a wait for work to finish — which is why it stops at ten seconds. For anything longer, use ios_simulator_wait_for_element. | |
| screenshot | No | Return a screenshot of the resulting screen. On by default, and worth leaving on: it is how you find out that the action landed where you meant it to. Turn it off only for a sequence whose intermediate states you do not need to see. | |
| clear_first | No | Replace the field's contents instead of appending. Only possible when `id` or `label` names the field — there is no way to clear a field addressed only by focus. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, it discloses the important silent-success trap: with no focus, keystrokes go nowhere but the call still succeeds. It also explains that id/label trigger a pre-tap. It does not cover what happens if the named field is not found, but the core behavioral risk is clearly exposed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The main description is two tight sentences with the most important caveat (focus trap) front-loaded. Every sentence carries load, and the parameter descriptions handle the remaining detail without bloating the main description.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The schema covers all seven parameters, including device selection, screenshot behavior, settle semantics, and clear_first constraints, so an agent has most of what it needs. Missing top-level detail about return shape and invalid-identifier behavior is a minor gap given no output schema, but the overall definition is still quite complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds meaningful cross-parameter semantics by explaining that id/label are how the caller ensures focus, and it ties clear_first to the presence of id/label. This goes beyond the simple field-level descriptions in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: typing text into the current keyboard focus or a named field. It also explains the two ways to target input, which distinguishes it from the tap-oriented siblings and makes the tool's job immediately clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit usage rule: pass id or label to tap the field first unless a field is already active, and warns against relying on focus when nothing is focused. It does not name alternative sibling tools in the main description, though the settle_ms parameter does direct longer waits to ios_simulator_wait_for_element.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ios_simulator_ui_treeiOS Simulator: UI TreeARead-only
List the addressable elements on screen — type, label, accessibility identifier, and the exact point to tap — flattened rather than nested. Prefer this over reading coordinates off a screenshot whenever you can: a label or identifier survives the screen moving, and a pixel position does not. The raw hierarchy is tens of KB, so this returns controls only by default; use contains or types to narrow further and detail to widen. A short answer is not proof the screen is bare — check the filtered field, which counts what the filters left out and names the argument that brings it back. Coordinates are in points, the same space ios_simulator_tap takes.
| Name | Required | Description | Default |
|---|---|---|---|
| types | No | Keep only these element types, without the `XCUIElementType` prefix, e.g. ["Button", "Cell"]. | |
| detail | No | How much of the hierarchy to return. `interactive` (default) is controls only — buttons, cells, fields, switches — and is what you want to decide where to tap. `labelled` adds text and images that carry a label, for reading the screen's content. `all` is every visible node and is usually far too large to be useful. | interactive |
| device | No | Which simulator: its UDID or its name as shown by ios_simulator_list. Omit it when exactly one is booted — that is the normal case, and IOS_SIMULATOR_ID pins it when it is not. Unlike simctl's own `booted`, this never picks arbitrarily between two. | |
| contains | No | Keep only elements whose label, identifier or value contains this, case-insensitively — e.g. "Today". | |
| include_invisible | No | Include elements XCUITest marks as not visible. Off by default, because on a scrolling list they outnumber the visible ones many times over — but the flag is not always truthful: a photo picker and a share sheet report their own contents as invisible while they are on screen and respond to a tap. Turn this on when `filtered.notVisible` says something was left out and the screen plainly has more on it than came back. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description reveals important behavioral traits: results are flattened, the raw hierarchy is tens of KB, defaults return only controls, the `filtered` field counts omissions, and coordinates are in the same point space as ios_simulator_tap. It also warns that `include_invisible` is not always truthful, which is valuable non-obvious behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence earns its place: purpose, comparison to screenshots, default behavior, filtering guidance, and coordinate-space note are all packed into a compact, front-loaded description with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having no output schema, the description explains what elements contain, how filtering affects results, what the `filtered` field means, and how coordinates relate to tapping. For a read-only inspection tool with this parameter richness, the description gives an agent enough context to invoke it correctly and interpret results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds practical parameter semantics by explaining how to narrow (`contains`, `types`) and widen (`detail`), and by tying the coordinate output to ios_simulator_tap's input space. This goes beyond merely restating the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'List the addressable elements on screen — type, label, accessibility identifier, and the exact point to tap — flattened rather than nested.' It clearly differentiates the tool from screenshot-based inspection by explicitly saying to prefer this over reading coordinates off a screenshot.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit when-to-use guidance: 'Prefer this over reading coordinates off a screenshot whenever you can: a label or identifier survives the screen moving, and a pixel position does not.' It also advises how to narrow or widen results with `contains`, `types`, and `detail`, and warns to check `filtered` before concluding the screen is empty.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ios_simulator_wait_for_elementiOS Simulator: Wait For ElementARead-only
Poll until an element appears, or until it goes away. This is the tool for a screen that loads: a generation step, a network round trip, a long import. settle_ms on the action tools is a pause for an animation and caps at ten seconds — it is not a wait, and using it as one is how you end up verifying a server instead of the screen. Give exactly one of id, label or predicate, the same way ios_simulator_tap_element takes them. Your MCP client may have a request timeout of its own, commonly 60 seconds, and it will cut this call off before timeout_ms does — for a longer wait, raise it there too or call this twice.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Accessibility identifier — the `id` field from ios_simulator_ui_tree. | |
| label | No | Exact accessibility label, i.e. the visible text. Matched against controls first, as in ios_simulator_tap_element. | |
| absent | No | Wait for the element to *stop* matching instead of to start. This is how you wait out a spinner, a progress view or a placeholder, which is the same wait from the other side. | |
| device | No | Which simulator: its UDID or its name as shown by ios_simulator_list. Omit it when exactly one is booted — that is the normal case, and IOS_SIMULATOR_ID pins it when it is not. Unlike simctl's own `booted`, this never picks arbitrarily between two. | |
| poll_ms | No | How long to wait between polls. Each poll is one query to the device, so a long wait costs less at 2000 than at 250 and arrives at almost the same moment. | |
| predicate | No | A raw NSPredicate, e.g. `type == "XCUIElementTypeButton" AND label BEGINSWITH "Add"`. | |
| screenshot | No | Return a screenshot of the resulting screen. On by default, and worth leaving on: it is how you find out that the action landed where you meant it to. Turn it off only for a sequence whose intermediate states you do not need to see. | |
| timeout_ms | No | How long to keep polling before giving up. Read the note about your client's own request timeout in this tool's description before setting it above 60000. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already covers the safety profile, and the description earns substantial credit beyond it: the warning that an MCP client's own request timeout "will cut this call off before timeout_ms does," the polling semantics, and the "give exactly one of" constraint. No contradiction with the annotation — polling and observing are inherently non-destructive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with purpose front-loaded in the first clause, and every sentence earns its place: the settle_ms exclusion prevents a common misuse and the client-timeout note is a necessary caveat. It is dense, with the timeout caveat arguably better placed after the parameter rule, but there is no waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter polling tool with no output schema, the description covers purpose, use cases, exclusions, parameter exclusivity, and an external failure mode. The remaining gap is the return contract — nothing states what a timeout or successful wait returns beyond the optional screenshot — but this is minor and largely inferable from the polling semantics.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and every parameter carries a rich description, so the baseline is 3. The description adds a genuinely non-derivable constraint — "Give exactly one of id, label or predicate" — and points to ios_simulator_tap_element as the convention reference, which raises it above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource in the opening clause — "Poll until an element appears, or until it goes away" — covering both wait directions immediately. It positions itself as "the tool for a screen that loads" and explicitly contrasts with the settle_ms pause on action tools, so an agent can tell it apart from the tap/action siblings without inspecting schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use context ("a generation step, a network round trip, a long import") alongside an explicit when-not-to: settle_ms "caps at ten seconds — it is not a wait, and using it as one is how you end up verifying a server instead of the screen." It names the alternative pattern it is not, which is the strongest possible routing guidance.
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. Dates show when Glama detected each change.
21 tool updates
v0.2.0- First observed
ios_simulator_add_media - First observed
ios_simulator_diagnostics - First observed
ios_simulator_erase - First observed
ios_simulator_install - First observed
ios_simulator_launch - First observed
ios_simulator_list - First observed
ios_simulator_list_apps - First observed
ios_simulator_open_url - First observed
ios_simulator_power - First observed
ios_simulator_press_button - First observed
ios_simulator_push - First observed
ios_simulator_restart_wda - First observed
ios_simulator_screenshot - First observed
ios_simulator_set_environment - First observed
ios_simulator_swipe - First observed
ios_simulator_tap - First observed
ios_simulator_tap_element - First observed
ios_simulator_terminate - First observed
ios_simulator_type - First observed
ios_simulator_ui_tree - First observed
ios_simulator_wait_for_element
TDQS
Each tool targets a distinct resource or action: simulator state management, app inspection, UI querying, and input injection are cleanly separated. Potentially confusing pairs like tap vs tap_element and list vs list_apps are explicitly disambiguated by coordinate-based vs element-based and simulator-level vs app-level distinctions.
All tools share the ios_simulator_ prefix and use lowercase snake_case, with most names following an imperative verb style. A few noun-like names (diagnostics, screenshot, ui_tree, power) deviate slightly from a strict verb_pattern but remain readable and predictable.
21 tools is slightly above the ideal 3-15 range, but each tool covers a distinct, justifiable operation across simulator lifecycle, app contrl, UI automation, and state staging. The count feels broad rather than bloated.
The tool surface covers the main lifecycle: list/boot/install/launch/terminate/erase, plus UI interrogation and interaction, environment staging, media ingestion, and push notifications. Minor gaps like a single-app uninstall or hardware rotation/shake actions exist, but core simulation and UI-testing workflows are well supported.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Build, run, and inspect iOS apps in disposable hosted Simulators from cloud coding agents.
Drive real devices from your AI Coding tool. Embed a client SDK (Unity, Godot, Flutter, iOS/macOS, Android, React Native, Web) in your app, then capture screenshots, traverse the UI tree, inject taps and key events, and run automated test tasks on the physical device over a secure relay.
Control real Android and iOS devices with LLM agents — tap, swipe, type, automate flows.
- LimrunOAuthcom.limrun
Cloud iOS simulators and Android emulators your agent can create, drive, and throw away.
Related MCP Servers
- AlicenseAqualityAmaintenanceEnables interaction with iOS simulators by providing tools to inspect UI elements, control UI interactions, and manage simulators through natural language commands.175,4712,159MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to automate iOS Simulator interactions including device management, UI element interaction (tap, swipe, type), screenshot capture, and execution of YAML-defined navigation workflows.3MIT
- AlicenseNot gradedqualityDmaintenanceEnables comprehensive control of iOS simulators and real devices through AI assistants, supporting app management, UI automation, screenshots, media operations, and location simulation for iOS development and testing workflows.7MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI to control iOS simulators through the MCP protocol. Supports device management, UI automation, and network interception including screenshot capture, text input, and HTTP request mocking.-
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/mgcrea/mcp-ios-simulator'
If you have feedback or need assistance with the MCP directory API, please join our Discord server