Browser MCP - the browser tool that can stop and ask you. A 2FA code, a CAPTCHA, a choice only you can make: it asks on your own screen, then carries on in the tab you were already signed into. 40 tools, any MCP client, MIT.
Browser MCP has 13 tools with solid naming (verb-forward: browser_*) and comprehensive descriptions. However, the server has critical quality issues: (1) Tool #13 'browser_scroll' is MISSING its input schema entirely, it declares no properties, making it unusable. (2) Several tools mix English and Danish parameter names (eget_vindue, fokuser, vindue_x, vindue_y, vindue_bredde, vindue_hoejde, fokuseret, placeret_som_bedt) which breaks agent parsing and is non-standard for English-primary MCP. (3) Parameter descriptions are often excessively long (200+ chars) with editorial tone rather than machine-parseable constraints. (4) No documented output schemas, LLMs cannot know what fields to expect. (5) Limited error handling guidance. (6) Some parameters lack explicit type information (e.g., browser_scroll properties are empty object). The tool definitions are visible and well-described, but the schema gaps, language mixing, and missing output documentation prevent higher scores. Average tool score is 62; individual tools range 45 - 75.
Click an element on the page. Supports CSS selectors AND text-based selectors. Auto-scrolls element into view. Uses real mouse events (works on Angular/React SPAs and CSP-strict sites like Google, Stripe). Examples: "button:text(Get started)", "text=Submit", "#my-button", "a.btn-primary"
ESCAPE HATCH: Click at raw viewport coordinates (CSS pixels) with fully trusted mouse events. Use when a visible button resists every selector strategy (Azure portal dialogs, Knockout-bound divs, canvas UIs): take a screenshot, read the button's position, click its center. Combine with browser_screenshot for coordinates.
True double-click on an element (two trusted press/release pairs with escalating clickCount). Use for open-item actions (calendar events, file lists) where two single clicks would trigger inline-rename instead (e.g. OWA month view).
Execute JavaScript in the current page. IMPORTANT: the parameter is `code` (NOT `script` - though that alias is accepted), and it must be an EXPRESSION, not statements: use an IIFE `(() => { ...; return x; })()`. Top-level `return` is a syntax error (the handler wraps code in parentheses).
Read EVERY row of a long or virtualised list by scrolling its container until no new rows appear. Use this instead of browser_get_page_content whenever a page shows a repeating list longer than the viewport - mail lists (Outlook, Gmail), invoice/billing tables, search results, transaction histories. Those UIs keep only ~7 rows in the DOM at a time, so a single page read returns a sliver and looks complete. Pass the CSS selector of one repeating row (e.g. '[role="option"]', 'tr', '[role="listitem"]'); the scrollable ancestor is found automatically. Returns deduplicated row text plus reached_end so you know whether you saw the whole list.
browser_scroll (tool #13) has NO input schema, inputSchema declares 'properties: {}' and no required array. This tool is completely unusable; agents cannot invoke it with any parameters.
Mixed English/Danish parameter names in browser_navigate: eget_vindue, fokuser, vindue_x, vindue_y, vindue_bredde, vindue_hoejde. Agent systems and LLMs expect English-only parameter names for consistency. Parameter descriptions should not use non-English field names.
No documented output schemas. Tools describe what they return in prose (e.g., 'Returns base64 PNG' for browser_screenshot) but do not declare the output structure in a formal schema. Agents must infer the response format.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 64 | 2026-07-28+ | v2 |
Fill a form input field with a value. Supports CSS selectors AND text-based selectors. Auto-scrolls and focuses the element. Works on CSP-strict sites via Chrome Debugger API. For date inputs use browser_set_date, for autocomplete/combobox use browser_set_combobox.
Get the content of the current page as text or HTML. Pass `selector` to read one part of a large page instead of all of it - on a big logged-in app the full HTML can run past a million characters. The answer is capped at 30000 characters by default and says so when it had to cut, with the real length, so a truncated page is never mistaken for a whole one.
Navigate the active browser tab to a URL. Reuses the current tab by default (no tab spam). Pass new_tab=true only when you need to keep the current page open.
Press a keyboard key (Enter, Tab, Escape, ArrowDown, etc.). Useful for submitting forms, navigating dropdowns, closing dialogs. Supports modifier keys (ctrl, alt, shift, meta).
RECOVERY: Force-detach and re-attach the Chrome debugger on the current tab. Use when interactive tools (click/fill/press_key) start timing out or reporting ghost-attach ("Debugger attach failed ... ghost") while list_tabs still works - faster than reloading the extension.
Right-click an element (trusted CDP mouse events) to open page-level context menus (web apps like OWA/Google Docs render their own). Note: Chrome's NATIVE context menu does not open via CDP - only in-page menus.
Take a screenshot of the visible area of the current tab. Returns base64 PNG, or saves to disk if path is provided.
Scroll the page or a scrollable container.
Parameter descriptions are excessively verbose (200 - 400+ chars in many cases, e.g., eget_vindue, fokuser). They read as editorial/narrative documentation rather than concise parameter guidance.
browser_double_click, browser_right_click, browser_click_xy, browser_reattach_debugger lack concrete usage guidance. Descriptions state WHAT but not WHEN or WHY to use them vs. alternatives (e.g., 'Use browser_double_click for calendar events' is present, but browser_right_click lacks similar context).
browser_screenshot, browser_execute_script, browser_press_key lack error handling guidance. No mention of what happens on failure (e.g., 'If element not found', 'If script times out') or how the agent should recover.
browser_navigate's 'new_tab' and window parameters lack mutual exclusivity guidance. Passing both new_tab and eget_vindue is ambiguous, the description says 'Requires new_tab' but does not clarify what happens if both are true or both are false.
browser_extract_list accepts flexible 'max_rows' (default 500, max 5000) but no guidance on what happens if the list is infinite (e.g., infinite scroll or pagination loop). The 'reached_end' field is mentioned but not formally documented in an output schema.