Token-efficient Linux/X11 computer-use tools for Pi (mariozechner/pi-coding-agent). AT-SPI + xdotool, ~1k LOC.
8 tools with clear action verbs and reasonable descriptions (avg 60 chars). All have input schemas with type definitions. However, parameter descriptions are sparse or missing entirely, most params lack guidance on format, constraints, or when to use them. Output schemas are undocumented. Error handling is minimal (generic RuntimeError). No tool annotations (readOnlyHint/destructiveHint). Composition is sound (single responsibility, chainable refs like @wN/@eN), but LLM-facing descriptions could be richer per the 50-200 char baseline for A-grade tools.
Click @eN, @wN, or absolute x,y. button=left|middle|right.
Batch multiple actions ({type:click|type_text|set_text|keypress|scroll, ...}).
Press keys/chords: ['Enter'], ['ctrl','a'], ['ctrl+l','Return'].
Enumerate visible X11 windows with @wN refs, titles, pids, geometry, focus.
Capture window PNG + AT-SPI @eN targets. Empty window = focused.
Scroll at ref/coords by pixel delta.
Replace value of an @eN text/entry via AT-SPI (falls back to ctrl+a + type).
Parameter descriptions missing or minimal. 'ref', 'x', 'y', 'button', 'click_count' in click() lack guidance on format, constraints, or when to use each. LLMs cannot infer whether 'ref' expects '@e5' or '@w2' without explicit description.
Output schemas undocumented. Tools return dicts/lists but LLMs have no schema to understand structure. E.g., screenshot() returns [dict, Image], what fields in dict? What does Image contain? Agents cannot plan downstream calls without this.
No tool annotations (readOnlyHint/destructiveHint). LLMs cannot distinguish safe read-only tools (list_windows, screenshot) from destructive ones (click, type_text, keypress, scroll). This violates current MCP spec (2026-07-28) which expects tool annotations for agent planning.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 55 | 2026-07-28+ | v2 |
Type literal text at the current cursor.
Error handling is generic. _bridge_call() raises RuntimeError with minimal context. No recovery guidance, no categorization (retryable vs fatal), no invalid-value echoing. LLMs cannot self-correct or plan recovery.
Parameter constraints not enforced or documented. click_count, scroll_x/scroll_y have no min/max. button enum is present but other params lack format guidance. E.g., 'keys' in keypress() accepts list[str] but no description of valid key names or chord syntax.