MCP server for iOS simulator automation — with clipboard-based text input that works with React Native
phantom-touch has 16 well-organized tools with consistent naming conventions (all start with 'pt_' prefix + verb_noun pattern). All tools have descriptions and Zod-validated schemas with input parameters. However, descriptions are sometimes brief (10-50 chars) and lack depth; several parameters lack sufficient guidance on format/constraints; output schemas are not documented; error handling is generic; and no tool annotations (readonly/destructive hints) are present. The codebase is well-structured and tools are properly registered, but falls short of production-grade documentation standards.
Boot an iOS simulator by its UDID. The booted simulator becomes the active device for subsequent commands.
Read the current contents of the simulator's clipboard/pasteboard.
Get the screen dimensions (width and height in pixels) of the simulator.
Launch an iOS application by its bundle identifier (e.g. 'com.example.myapp'). The simulator must be booted first.
List all installed apps on the simulator with their bundle IDs and display names.
List all visible UI elements on the current screen with their types, labels, values, and coordinates. Use this to find elements to tap or type into. Each element shows its position (x,y) and size.
Output schemas not documented. Tools return text responses with isError flag, but LLM cannot predict response structure for downstream chaining. Missing documentation of response fields (content array structure, text content format, base64 encoding for screenshots).
Generic error handling. All tools catch errors and return 'Error: {error.message}' without categorization (retryable vs fatal) or recovery guidance. LLM cannot determine if a failure is transient or permanent, forcing blind retries.
Missing tool annotations (toolAnnotations=false). No readOnlyHint, destructiveHint, or idempotentHint attributes. Agents cannot infer which tools are safe to retry, which mutate state, or which are idempotent, risking duplicate side effects (e.g. launching app twice).
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 57 | 2026-07-28+ | v2 |
| 2026-03-09 | D | 55 | - | v1 |
List all available iOS simulators with their UDID, name, state (Booted/Shutdown), and runtime version. Use this first to find a simulator to work with.
Open a URL or deep link on the simulator. Can be used to open web pages in Safari or trigger deep links into apps (e.g. 'myapp://screen/profile').
Press a hardware button on the simulator (Home, Lock, Siri, Apple Pay).
Take a screenshot of the current simulator screen. Returns the image as base64-encoded PNG. Use this to see what's currently displayed on screen.
Set the simulator's clipboard/pasteboard content. Useful for preparing text to paste into fields.
Shut down a running iOS simulator.
Swipe from one point to another on the screen. Use for scrolling, dismissing, or navigating between screens.
Tap on the screen at the specified (x, y) coordinates. Use pt_list_elements first to find the coordinates of the element you want to tap.
Terminate (force close) a running iOS application.
Type text into the currently focused field, or tap a field first then type. STRATEGIES: - "paste" (default, RECOMMENDED): Uses clipboard + Cmd+V paste. Works reliably with React Native controlled TextInput components that use onChangeText. - "keyboard": Uses HID keyboard events. Faster but may NOT work with React Native controlled inputs. IMPORTANT: For React Native apps, always use the "paste" strategy (the default). If you know the (x,y) coordinates of the text field, provide them to auto-tap and focus first.
Insufficient parameter guidance on format/constraints. 'duration' params (pt_tap, pt_swipe) lack min/max bounds; 'button' enum in pt_press_button is documented but other enums (strategy in pt_type_text) could benefit from clearer guidance on when to use each.
Descriptions lack depth on prerequisites and dependencies. pt_launch_app states 'simulator must be booted first' but does not guide LLM on how to verify or bootstrap. pt_type_text mentions React Native strategy but lacks guidance on when clipboard vs keyboard mode fails.
No input validation or constraint documentation for coordinate-based tools. pt_tap, pt_swipe accept x/y as numbers but do not validate against screen size; LLM can pass out-of-bounds coordinates. No guidance on coordinate system origin or unit (pixels assumed but not stated).