MCP server for autonomous macOS, iOS Simulator, and Android screen recording with frame extraction.
Strong tool definitions with comprehensive descriptions and well-structured schemas. All 12 tools have clear, action-verb names and detailed descriptions (avg 250+ chars). Input schemas are complete with typed parameters and descriptions. However, output schemas are not formally documented in the code, responses are described in prose rather than JSON Schema. Error handling guidance is embedded in descriptions but not structured. Tool composition is excellent: single-responsibility tools chain well (start_recording → stop_recording → extract_frames). Parameter naming is consistent and human-friendly (target aliases, natural identifiers). Security considerations are documented (permissions, TCC, Accessibility). Minor gaps: no explicit enum constraints in schema (e.g., target values are described but not constrained), and no structured error classification.
Diagnose macOS Screen Recording permission for Claude Code/Codex users. Use this before retrying `start_recording target="macos"` or `start_app_window_recording` when macOS TCC may be blocking capture. The response tells the client whether Screen Recording currently works, which launcher process macOS is evaluating, where the user must grant permission, and that the MCP client must be fully restarted after changing the setting. Surface `user_message` directly when explaining the setup to the user. This tool only checks Screen Recording. iOS Simulator and Android recordings do not need Screen Recording. Pointer tools (`move_pointer` and `hover_sequence`) need Accessibility permission instead.
Reap recordings owned by dead prior server PIDs (current OS user only). The server automatically runs this before each start_recording, but call it explicitly if start_recording fails with stale-process errors. The response includes a list of cleaned-up sessions with their final status.
Extract key frames from a video file. Use this after stop_recording to extract frames from a completed recording. The tool supports scene detection (default) or fixed-fps extraction. Frames are saved as PNG files in the output directory and optionally returned as inline images. The response includes images (inline PNG content if inline_images=True), frame_paths, and dropped_for_max (number of frames dropped due to max_frames limit).
Move the mouse pointer through a sequence of points with smooth interpolation. This is the preferred tool for hover-only UI verification (no clicks). The pointer moves smoothly between points with configurable hold time at each point. Use this instead of move_pointer when hovering over multiple UI elements. Requires Accessibility permission on macOS.
Output schemas not formally documented. Responses described in prose (e.g., 'response includes session_id, video_path, target...') rather than JSON Schema. LLMs cannot reliably parse unstructured output or plan downstream tool calls without explicit field definitions.
Enum constraints not declared in input schemas. Target parameter accepts 'macos'/'mac'/'desktop' but schema shows type:string without enum. Mode parameter accepts 'scene'/'fixed_fps' but not constrained. LLMs may hallucinate invalid values.
Error handling not structured. Recovery guidance embedded in descriptions (e.g., 'check file_size_bytes > 0', 'call check_macos_permissions') but no formal error classification (retryable vs user-fixable vs fatal). Agents cannot programmatically determine next steps.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 68 | 2026-07-28+ | v2 |
List all active recording sessions for this server process. Returns a list of session metadata including session_id, target, video_path, started_at, and pid. Use this to recover a lost session_id or verify that a recording is still active.
Move the mouse pointer to a single (x, y) coordinate. This is a synchronous operation that warps the cursor and posts a mouse-move event. Use hover_sequence or move_sequence for smooth interpolated movement across multiple points. Requires Accessibility permission on macOS.
Move the mouse pointer through a sequence of points with smooth interpolation. The pointer moves smoothly between consecutive points with configurable interpolation steps and delays. This is useful for simulating natural mouse movement across multiple UI elements. Requires Accessibility permission on macOS.
Record a screen for a fixed duration and extract key frames in one call. This is a convenience tool that combines start_recording, stop_recording, and extract_frames. It is useful for quick, self-contained recordings with automatic frame extraction. For agent-driven UI verification with manual pointer operations, prefer the manual-stop workflow (start_recording without duration_seconds, then stop_recording). The response includes session_id, video_path, file_size_bytes, images (inline PNG content if inline_images=True), frame_paths, and dropped_for_max.
Start recording a visible macOS app window by name or bundle ID. This is the preferred method for recording a single foreground application window. The tool automatically detects the window bounds and records only that region. If the window is not visible or too small, the response includes an error and the detected window info for repositioning. The response includes session_id, video_path, target, mode, started_at, pid, window_name, window_bounds, and visible_ratio.
Start recording a macOS, iOS Simulator, or Android screen target. Target aliases: - macOS: "macos", "mac", or "desktop" - iOS Simulator: "ios_simulator", "ios-simulator", "ios", or "simulator" - Android: "android" Common options include orientation and rotate_degrees. macOS options include region, display, include_cursor, include_clicks, and include_audio. iOS Simulator options include device, udid, and display ("internal" or "external"). Android options include serial, size, and bit_rate. Omit duration_seconds for the preferred manual-stop workflow, then call stop_recording with the returned session_id. The response includes session_id, video_path, target, mode, started_at, pid, and target_key.
Stop all active recording sessions for this server process. Optionally filter by target (e.g., 'macos', 'ios_simulator', 'android'). Use this when a session_id is lost or duplicate-target protection blocks a new start_recording call. The response includes a list of stopped sessions with their final video_path and file_size_bytes.
Stop a recording session and return the video file path and metadata. Use this after calling start_recording or start_app_window_recording without a duration_seconds parameter. The response includes the final video_path, file_size_bytes, and duration_seconds. Always check file_size_bytes > 0 before extracting frames; a zero-byte file indicates the recording failed.
Parameter constraints not machine-parseable. Descriptions state 'Defaults to 0.1' and 'range 0.0 - 1.0' in prose; JSON Schema lacks minValue/maxValue. Numeric bounds (e.g., scene_threshold, min_visible_ratio) should be declared formally.
No pagination support documented. list_active_sessions returns all sessions without limit or offset. If many sessions exist, response could bloat context. Should support limit/offset and return total_count.