MCP server for iOS Simulator interaction - screenshot, tap, swipe, and verify UI changes
Strong tool naming (verb_noun pattern consistently applied across 19 tools). Descriptions are detailed and contextual (avg ~180 chars), exceeding baseline minimums. All parameters have type definitions and descriptions. However, output schemas are not explicitly documented in the source code, responses are inferred from tool behavior rather than formally specified. Error handling is minimal; tools lack recovery guidance and actionable error messages. No input validation constraints visible (e.g., coordinate bounds for tap/swipe are not enforced in schema). Tool composition is excellent, each tool has a single responsibility and chains naturally (e.g., sim_screenshot → sim_tap). Security is adequate for a local simulator tool but lacks audit logging.
Add photos, videos, or contacts to the simulator's library. Supports common image formats (PNG, JPEG), video (MOV, MP4), and contacts (VCF).
Install an app bundle (.app) on the simulator. The app_path should point to a built .app bundle (typically found in Xcode's DerivedData build directory).
Launch an app by its bundle identifier on the simulator. The app must already be installed. Example bundle IDs: com.apple.mobilesafari, com.apple.Preferences
Terminate a running app by its bundle identifier.
Uninstall an app from the simulator by bundle identifier.
Boot an iOS Simulator device and open the Simulator app. Use sim_list_devices to find available device UDIDs. After booting, the Simulator window will appear on screen.
Output schemas not formally documented. Tool responses are inferred from behavior (e.g., sim_screenshot returns base64 image + dimensions) but no explicit schema definitions visible in source. LLMs cannot reliably plan downstream operations without knowing response structure.
No error handling guidance. Tools lack actionable error messages. E.g., if sim_tap fails due to accessibility permissions, the error should guide the user to grant Terminal accessibility access. Currently, errors are likely raw exceptions.
Input validation constraints not enforced in schema. Coordinate parameters (x, y) for tap/swipe have min=0 but no max bounds tied to screen dimensions. sim_set_location latitude/longitude have min/max but no validation that coordinates are realistic (e.g., preventing invalid lat/lon combos).
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 59 | <=2025-11-25 | v2 |
Simulate a double tap at the specified pixel coordinates. Useful for zoom gestures, text selection, etc. Coordinates match sim_screenshot dimensions.
List available iOS/tvOS/watchOS/visionOS simulator devices. Returns name, UDID, state (Booted/Shutdown), runtime, and availability. Use the UDID from this list as the device_id parameter in other tools.
Simulate a long press (touch and hold) at the specified coordinates. Default duration is 1 second. Useful for context menus, drag initiation, or reorder mode.
Open a URL in the simulator. Supports http/https links (opened in Safari) and custom URL schemes for deep linking (e.g., myapp://screen/settings).
Copy text to the simulator's pasteboard (clipboard). The text will be available to paste within any app on the simulator. Useful for setting up test data or transferring text to the device.
Take a screenshot of the simulator screen. Returns the image as base64-encoded PNG or JPEG (configurable via SCREENSHOT_JPEG_QUALITY env var, default 80). Also returns the image dimensions (width, height in pixels). Use these dimensions for coordinate mapping in tap/swipe operations.
Scroll the screen in a given direction. A higher-level convenience over sim_swipe that automatically calculates start/end points. Direction refers to where the CONTENT moves: - 'down': Content moves up, revealing content below (most common for scrolling) - 'up': Content moves down, revealing content above - 'left': Content moves right, revealing content to the left - 'right': Content moves left, revealing content to the right
Send a simulated push notification to an app on the simulator. The payload must be a valid APNs payload object with an 'aps' key. Example minimal payload: { "aps": { "alert": { "title": "Hello", "body": "World" } } }
Set the simulated GPS location of the device. Useful for testing location-based features. Examples: - London: latitude=51.5074, longitude=-0.1278 - New York: latitude=40.7128, longitude=-74.0060 - Tokyo: latitude=35.6762, longitude=139.6503
Grant, revoke, or reset a privacy permission for an app. Available services: all, calendar, contacts-limited, contacts, location, location-always, photos-add, photos, media-library, microphone, motion, reminders, siri. Note: Some permission changes will terminate the app if it's running.
Shutdown a running simulator device. Pass a specific UDID or 'all' to shutdown all booted simulators.
Simulate a swipe gesture from one point to another. Coordinates are in pixels matching sim_screenshot dimensions. Common patterns: - Scroll down (see more below): swipe from lower to upper Y - Scroll up (see above content): swipe from upper to lower Y - Swipe left (next page): swipe from right to left X - Navigate back: swipe from left edge (x~50) to right (x~600)
Simulate a tap (touch) at the specified pixel coordinates on the simulator. Coordinates are in pixels, matching the dimensions returned by sim_screenshot. You MUST call sim_screenshot first to see what's on screen and establish coordinates. Example workflow: 1. sim_screenshot -> see screen (1170x2532) 2. Identify a button at approximately (585, 1200) 3. sim_tap(x=585, y=1200) 4. sim_screenshot -> verify the result Requires macOS Accessibility permission for the host terminal app.
No confirmation/dry-run for destructive operations. sim_app_uninstall and sim_shutdown are marked DESTRUCTIVE but lack a confirm_before_execute pattern. Agents could accidentally uninstall apps or shut down simulators without user approval.
Missing pagination/limits for list_devices. If many simulators exist, sim_list_devices could return a large unstructured list. No documented limit, offset, or cursor support.