MCP server that reads and drives a real, logged-in Chrome — cross-platform, Ubuntu-headless first-class.
TabPilot presents 8 tools with complete schemas and descriptions. Naming follows verb_noun conventions and is action-oriented (browser_status, list_tabs, read_tab, query_dom, open_tab, close_tab, navigate, activate_tab). Descriptions are substantial (100-300+ chars) and explain WHAT the tool does and WHEN to use it. However, critical gaps exist: parameter descriptions lack actionable constraints (no enums for 'mode' in read_tab, no bounds on numeric limits), error handling is minimal (tools return raw errors without recovery guidance), and output schemas are not formally documented. The tool decorator pattern wraps exceptions (BridgeOffError, TabPilotError) into readable text, which is good, but the wrapped errors lack next-step guidance. Parameter descriptions vary in depth, some are excellent (e.g., read_tab's selector: 'Read only this element's subtree. Use it, it is the cheapest way to keep a read small and on-topic.') while others are sparse (open_tab's activate: 'Bring the new tab to the front.'). The codebase shows thoughtful design (regex url_pattern for flexible tab addressing, mode variants, selector support), but does not expose formal output schemas or per-parameter validation rules to the LLM. Tools score individually from 50-75; the average is 62.
Bring a target browser tab to the front and focus its window.
Report which backend is connected, what it can do, and how many tabs are open.
Close a tab.
List open tabs with their ids, titles and URLs.
Point an existing tab at a new URL.
Open a URL in a new tab and return its id.
Inspect specific elements: tag, text, attributes, size, visibility.
Output schemas are not formally documented for any tool. LLMs cannot predict response structure and must infer from tool names and descriptions. This invites hallucinated field names and failed downstream chains.
Mode parameter in read_tab ('readable', 'text', 'html') is described as free-form string, not an enum. LLMs may pass invalid modes; no validation guidance given.
Numeric parameters (limit in query_dom, text_max, max_chars in read_tab) lack min/max bounds. LLMs can pass unbounded or negative values, inviting API errors or timeouts without recovery guidance.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 59 | 2026-07-28+ | v2 |
Read a tab's content, converted to markdown and capped in size.
Error handling is minimal. Tools wrap exceptions into 'ERROR' + text, but do not categorize errors or provide recovery next steps. A missing tab returns a raw error; the LLM has no guidance on whether to retry, use url_pattern, or list_tabs first.
close_tab and activate_tab document mutual exclusivity (tab_id vs url_pattern) in natural language only. No machine-readable constraint enforces this; LLMs may pass both and encounter ambiguous behavior.
activate_tab uses a chain of defaults ('uses the frontmost tab or matches by url_pattern') with unclear precedence. Which is tried first? What if url_pattern matches multiple tabs? Description is too vague.
attrs parameter in query_dom lists default attributes in text but does not provide an enum or comprehensive list of valid attribute names. LLMs cannot self-correct if they pass an invalid attribute.
No tool explicitly states whether it is idempotent (safe to retry) or has side effects (irreversible). open_tab, navigate, close_tab, and activate_tab all modify state, but their retry safety is not documented.