MCP server giving each caller an isolated browser session against a shared persistent Chrome.
28 tools with consistent naming (verb_noun pattern) and descriptions present. However, parameter descriptions are minimal (1-2 lines), schemas lack depth (no minima/maxima, enums, or format constraints), and output schemas are entirely undocumented. Error handling is generic. No tool annotations (readOnlyHint/destructiveHint). Composition is sound, tools are single-responsibility and chainable via sessionId. Naming is clear but descriptions average ~80 chars, below the 194-char baseline for A+ tools. Security: sessionId is passed as parameter (acceptable for session context), but no mention of secret injection or permission gates.
Polls for completion of human takeover of a session.
Clicks on an element at specified coordinates or matching a selector.
Closes an existing browser session by session ID.
Closes a specific tab in a session.
Deletes a saved browser state by name.
Evaluates JavaScript code in the page context and returns the result.
Gets the current stealth mode status.
Output schemas completely undocumented. No tool returns a documented schema, LLMs cannot predict response structure, forcing them to guess field names and types for downstream chaining.
Parameter descriptions are minimal (1-2 lines, ~20-40 chars). Lack actionable constraints: no min/max for numeric params, no enums for categorical params, no format specs for strings. E.g., 'timeout' in wait_for has no unit or range; 'key' in press_key has no valid key list.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). Risk classification is inferred from tool names only. LLMs cannot distinguish safe retries from destructive operations without explicit hints.
Inferred effective spec: 2025-06-18+.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 55 | 2025-06-18+ | v2 |
Lists all active browser sessions with their page counts and active URLs.
Lists all saved browser states.
Lists console messages (log, error, warning) from the page.
Lists network requests made by the page.
Lists all pages/tabs in a session with their URLs, titles, and active status.
Lists all page visits in a session with timestamps and URLs.
Loads a previously saved browser state into the current session.
Moves the mouse to specified coordinates.
Navigates the active tab to a specified URL.
Opens a new tab/page in a session with optional URL.
Opens a new isolated browser session with optional viewport and mobile user agent settings.
Presses a keyboard key.
Requests human takeover of a browser session and returns a takeover URL.
Saves the current browser state (cookies, storage, etc.) with a given name.
Scrolls the page by specified amounts.
Enables or disables stealth mode to hide automation signals.
Switches to a specific tab by index in a session.
Takes a screenshot of the current page and returns it as base64-encoded JPEG.
Takes a snapshot of the current page DOM and returns it as HTML.
Types text into the focused element.
Waits for a condition to be met (selector, navigation, or timeout).
Error handling is generic (CallToolResult::error with text). No recovery guidance, no error classification (retryable vs fatal), no actionable messages. E.g., 'session not found' should suggest 'call list_browser_sessions() to see active sessions'.
Tool descriptions average ~80 chars, below the 194-char baseline. Lack WHEN/WHY context. E.g., 'Clicks on an element' does not explain when to use click vs evaluate, or what happens if selector and coordinates both provided.