MCP server that drives macOS browsers (Chrome family + Safari) via AppleScript/JXA. No extension, no debug flags.
Perch defines 8 tools with complete input schemas and descriptions, but quality is uneven. Tool names follow verb_noun convention (list_tabs, eval_js, screenshot, activate_tab, navigate, close_tab, new_tab, wait), which is good. However, descriptions are terse (10-80 chars), below the 50-200 char baseline for LLM-optimized docs. Parameter descriptions exist but lack actionable constraints: 'JavaScript code to evaluate' doesn't specify timeout behavior, error handling, or return type expectations. Output schemas are not documented, callers don't know what eval_js returns (string? object? null?). Error handling is minimal: no guidance on permission errors, stale tab indices, or recovery paths. The daemon-based architecture is sophisticated but undocumented in tool descriptions, leaving agents unaware of timeout semantics or fallback behavior.
Activate (bring to foreground) a specific browser tab.
Close a specific browser tab.
Evaluate JavaScript in a target browser tab and return the result.
List all open tabs across all browser windows. Returns bare array by default, or {tabs, total} when filtered.
Navigate a browser tab to a specified URL.
Open a new tab in a browser window.
Take a screenshot of a browser window and return image data with metadata.
Output schemas not documented. Callers don't know what eval_js, screenshot, or wait return. LLMs cannot plan downstream operations without knowing response structure.
Descriptions are terse (10-80 chars, well below 50-200 baseline). 'Evaluate JavaScript in a target browser tab and return the result' lacks context on timeout, error modes, or return type. LLMs cannot infer when to use eval_js vs wait.
Parameter descriptions lack actionable constraints. 'JavaScript code to evaluate' doesn't specify: Can it return promises? What timeout applies? What happens on error? 'Optional limit on number of tabs returned' doesn't state min/max bounds.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | F | 49 | 2026-07-28+ | v2 |
Wait for a condition to be true in a browser tab, with optional timeout.
Error handling is implicit. Permission errors, stale tab indices, and timeout semantics are handled in code but not surfaced in tool descriptions. Agents don't know to call list_tabs after a timeout or how to recover from 'JavaScript from Apple Events is off'.
Daemon architecture and timeout behavior undocumented. The 30s default timeout, JXA_OVERHEAD, and fallback-to-one-shot logic are invisible to callers. Agents cannot reason about why a call timed out or how to retry.