MCP server giving agents semantic macOS app control via the Accessibility API and ScreenCaptureKit.
Server has 9 tools with explicit Zod schemas and descriptions. Naming follows verb_noun convention (click, type_text, key_press, scroll, check_permissions, screenshot, wait, list_windows, get_frontmost_window). Descriptions are present and actionable (avg ~100 chars). However, several tools lack parameter descriptions for all fields, output schemas are not formally documented, and error handling is minimal. Tool composition is sound (single responsibility), but parameter validation and recovery guidance are weak.
Report macOS Accessibility + Screen Recording permission status for the helper binary.
Click at (x, y) within the window captured by `capture_id`. Coordinates are screenshot-pixel space.
Return the currently frontmost app + window. Safe default before any action.
Send a keyboard shortcut (key + optional modifiers) to the frontmost window.
List visible windows with title, bundle ID, pid, and frame. Optionally filter by bundle ID.
Capture a screenshot of a target window (default: frontmost). Returns capture_id used to anchor subsequent click/scroll calls, plus base64-encoded PNG.
Output schemas not formally documented. Tools return text/image content but LLMs cannot infer structure of JSON responses (e.g., screenshot returns capture_id, target, size fields). Agents must guess field names for downstream calls.
Error handling absent. Tools return bare 'ok' on success but no guidance on failure modes. If click fails (invalid capture_id, out-of-bounds coordinates), LLM receives no recovery hint. No categorization of retryable vs fatal errors.
check_permissions and get_frontmost_window have empty input schemas ({}). While valid, they provide no parameter documentation. Descriptions are minimal (70 chars). LLMs cannot infer when to call these vs alternatives.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 59 | 2026-07-28+ | v2 |
Scroll the frontmost window in the given direction.
Type text into the focused element of the frontmost window. Rejects obvious secrets.
Pause for `ms` milliseconds (default 1000). Counts against the rate limit.
wait tool description lacks context on why an agent should call it. 'Pause for ms milliseconds' does not explain when delays are necessary (e.g., waiting for UI to render after a click). No guidance on rate limiting or timing dependencies.
type_text tool rejects secrets but provides no list of patterns rejected. Description says 'Rejects obvious secrets (sk-…, ghp_…, AKIA…, long base64)' but LLM cannot predict what 'long base64' means. No error message guidance if rejection occurs.