Compact facade MCP server aggregating cua-driver + computer-use-oss + osascript for macOS desktop automation
Desktop-hub exposes 12 tools with mixed quality. Strengths: all tools have descriptions (50-150 chars, adequate); input schemas present with typed parameters; error handling via McpError. Critical weaknesses: (1) Naming lacks clarity, 'act', 'act_batch', 'desk_call', 'desk_describe' are vague and don't follow verb_noun convention; 'act' could mean any desktop action, forcing LLMs to read descriptions. (2) Parameter descriptions are minimal (10-30 chars), 'Process ID of target window' lacks context on when/why to use it. (3) No output schemas documented; LLMs cannot predict response structure. (4) Proxy tools (click, type_text, press_key, set_value) duplicate act/act_batch functionality, violating single-responsibility principle. (5) No pagination, limits, or result-shaping guidance. (6) Error recovery guidance missing, SESSION_ENDED_RE handling is internal, not surfaced to LLM. Baseline: 549 production tools average 18-char names starting with action verbs; 94% have docstrings; 100% of A+ tools document return types. This server achieves ~60% of those baselines.
Execute a single desktop action (click, type, press key, set value, etc.) with facade-level validation and token-efficient parameter handling
Execute multiple desktop actions in sequence with fresh token injection between actions and facade-level validation
Click on an element (proxied to cua backend)
Call a tool on a downstream backend (cua or oss) by name with arguments
Describe available tools on a downstream backend or get schema for a specific tool
Get current window state (alias for window_state)
List all open windows on the desktop
Vague tool names violate verb_noun convention. 'act', 'desk_call', 'desk_describe' do not clearly signal intent. LLMs must read full descriptions to disambiguate. Rename: 'act' → 'perform_desktop_action', 'desk_call' → 'call_backend_tool', 'desk_describe' → 'list_backend_tools'.
No output schemas documented. LLMs cannot predict response structure (e.g., does window_state return a tree, a flat list, or a diff object?). Add explicit outputSchema to all tool definitions.
Duplicate tools violate composition principle. 'click', 'type_text', 'press_key', 'set_value' are thin proxies to 'act' with identical semantics. Remove proxies or document why they exist (e.g., for backward compatibility). Single canonical interface reduces LLM confusion.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 52 | 2025-06-18+ | v2 |
Press a keyboard key (proxied to cua backend)
Execute an AppleScript or JXA script locally via osascript
Set the value of a field (proxied to cua backend)
Type text into a field (proxied to cua backend)
Get current window state with optional diff mode to report only changes since last call
Parameter descriptions are minimal (10-30 chars). 'Process ID of target window' lacks context: when should LLM pass pid vs window_id? What happens if both are omitted? Expand to 50-100 chars with dependency hints and constraints.
Error recovery guidance is internal (SESSION_ENDED_RE, revive logic). LLMs cannot see this and will not know to retry after session expiry. Surface recovery hints in tool descriptions: 'If call fails with "session ended", the server will auto-retry once.'