Skip to main content
Glama
mgcrea

@mgcrea/mcp-ios-simulator

by mgcrea

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
IOS_SIMULATOR_IDNoUDID, name, or `booted`. Two booted and no value is an error that names them.
IOS_SIMULATOR_DEBUGNoLog every `simctl` and WebDriverAgent call to stderr.false
IOS_SIMULATOR_CONFIGNoPath to the config file; used to move the default config location.~/.config/ios-simulator-mcp/config.json
IOS_SIMULATOR_WDA_URLNoExplicit override; rarely needed.http://127.0.0.1:8100
IOS_SIMULATOR_WDA_PORTNoMust match the runner's `USE_PORT`. One port per simulator.8100
IOS_SIMULATOR_OUTPUT_DIRNoScreenshots, launch logs, the runner log.$TMPDIR/mcp-ios-simulator
IOS_SIMULATOR_TIMEOUT_MSNoBudget for one `simctl` call; a boot is slow.120000
IOS_SIMULATOR_LAUNCH_ARGSNoLaunch arguments applied when `launch` passes none of its own.
IOS_SIMULATOR_ALLOW_WRITESNo`0` drops the fourteen driving tools from `tools/list`.on
IOS_SIMULATOR_MAX_TREE_BYTESNoByte cap on a `ui_tree` payload.24000
IOS_SIMULATOR_WDA_TIMEOUT_MSNoBudget for one WebDriverAgent call.30000

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": true
}
resources
{
  "listChanged": true
}

Tools

Functions exposed to the LLM to take actions

NameDescription
ios_simulator_diagnosticsA

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.

ios_simulator_listA

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.

ios_simulator_list_appsA

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.

ios_simulator_screenshotA

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.

ios_simulator_ui_treeA

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.

ios_simulator_wait_for_elementA

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.

ios_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.

ios_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.

ios_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.

ios_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.

ios_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.

ios_simulator_powerA

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.

ios_simulator_eraseA

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.

ios_simulator_installA

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.

ios_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.

ios_simulator_terminateA

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.

ios_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.

ios_simulator_set_environmentA

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.

ios_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.

ios_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.

ios_simulator_restart_wdaA

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.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription
diagnosticsThe same report as ios_simulator_diagnostics, as a resource.

Latest Blog Posts

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