Skip to main content
Glama
pony-browser-mcp
by pssrh

Pony Browser MCP

Pony Browser MCP connects an MCP client to the user's existing Chrome profile through a loopback-only WebSocket. It adds dedicated agent windows, named task groups, workspace cleanup, and explicit human review prompts to the upstream Browser MCP implementation.

The project has two local components:

  1. The Chrome Web Store extension, installed once per Chrome profile and then updated by Chrome.

  2. The MCP server, launched on demand by Codex or another MCP client through stdio.

The server intentionally listens only on 127.0.0.1. It is not a shared remote browser service and does not expose browser control on the LAN.

Codex setup

After a release is published:

npm install --global https://github.com/pssrh/pony-browser-mcp/releases/download/v1.0.1/pony-browser-mcp-1.0.1.tgz
codex mcp add pony-browser -- pony-browser-mcp

For shared Windows, macOS, or Linux machines, install the signed extension through the managed-policy scripts in enterprise/. Chrome then checks the GitHub Pages update manifest and upgrades the extension without a Chrome Web Store listing. Developers can still load extension/ unpacked for local testing.

Related MCP server: browser-use-mcp

Build and verify

npm ci
npm test
npm run build:cws

The Web Store ZIP and npm tarball are written to dist/ with SHA-256 files.

Privacy

The extension has no analytics or vendor backend. Browser data requested by an MCP client travels over localhost to that client. The client may then send the data to its configured model provider under the client's own privacy policy. See the full privacy policy.

Attribution

This project is a fork of Browser MCP by Agent360, used under the MIT License. See NOTICE.md and LICENSE.

Available Tools

45 tools
browser_aboutA

Returns Browser MCP info and pre-filled URLs the user can click to submit feature wishes, share use-cases, or report bugs. Call this PROACTIVELY whenever the user (a) mentions a feature they wish existed ("I wish browser-mcp could...", "it would be nice if..."), (b) says something is missing, broken, or unexpected, (c) asks how Browser MCP works or who maintains it, or (d) describes something cool they built with browser-mcp. Pass intent="wish" | "use_case" | "bug" | "info" plus an optional title and body, and offer the returned submit_url to the user. Browser MCP is community-shaped — this tool is how the user contributes back.

Inputs: body, title, intent.

browser_ask_userA

Show an overlay dialog asking the user to perform an action or provide information (credentials, 2FA, CAPTCHA, OAuth consent). Can include input fields for the user to fill in. Returns user responses.

Inputs: message (required), title, fields, timeout.

browser_cleanup_workspaceA

Close tabs for a task group (removes the Chrome tab group). Optionally keep the dedicated window with one about:blank for reuse. Can also close leftover groups whose titles match prefixes (junk cleanup).

Inputs: task, keep_window, close_titles, close_title_prefixes.

browser_clickA

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"

Inputs: selector (required).

browser_click_xyA

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.

Inputs: x (required), y (required).

browser_clipboard_statsA

SECRET-SAFE: Inspect the system clipboard's SHAPE without exposing content: length, trimmed length, has_whitespace, looks_like_uuid, looks_like_url. Use to verify a copy landed (e.g. "is this a ~40-char secret or a UUID from the wrong button?") before pasting.

Inputs: no named parameters.

browser_close_tabA

Close a browser tab by ID. Only tabs owned by the current session can be closed.

Inputs: tab_id (required).

browser_console_logsA

Get recent console.log/warn/error messages from the page. Installs a lightweight interceptor on first call. Returns the last N console messages.

Inputs: count.

browser_copy_to_clipboardA

SECRET-SAFE: Copy an element's value/text (or an attribute) to the system clipboard WITHOUT returning the content — only the character count comes back. Use for credentials/tokens that must move from a page (e.g. Azure "new client secret" value) to a field or CLI (pbpaste) without ever entering the conversation. CSS selectors only.

Inputs: selector (required), attribute.

browser_dismiss_overlaysA

Dismiss visible popups, modals, tooltips, banners, and "Are you sure?"-style overlays in one call. Heuristic-based: finds close affordance via aria-label, text content (Skip/Cancel/Ikke nu/Don't show/Got it/Close), or × character button. Use when a flow is interrupted by unexpected dialogs (cookie banners, onboarding tooltips, draft-confirm prompts on Meta Ads, etc.). Returns list of what was dismissed.

Inputs: scope, max_passes.

browser_double_clickA

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).

Inputs: selector (required).

browser_drop_fileA

Upload a file by finding a hidden within a drag-drop zone's subtree (or parent up to 2 levels). Use when browser_upload_file fails because the dropzone has no visible file input. Returns clear error if no input is found anywhere — pure drop-zones without backing inputs require manual handling.

Inputs: selector (required), file, files.

browser_ensure_windowA

Create or reuse a dedicated Chrome window for agent work (keeps tabs/groups off the user browsing window). Persist and pass back window_id on later calls.

Inputs: url, task, width, height, +2 more.

browser_execute_scriptA

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).

Inputs: code (required).

browser_extract_tokenC

Navigate to a provider's API settings page so you can read its API token from the page.

Inputs: provider (required).

browser_fetchA

Make an HTTP request from the extension background (NOT subject to CORS). Use this when page-context fetch would be blocked by CORS or CSP. Useful for API calls to Google, Stripe, Slack APIs while on their pages.

Inputs: url (required), body, method, headers.

browser_fillA

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.

Inputs: value (required), selector (required).

browser_get_cookiesB

Get cookies for a specific domain.

Inputs: domain (required).

browser_get_local_storageA

Read localStorage from the current page. Pass key for a specific value, or omit for all.

Inputs: key.

browser_get_new_tabA

Get the most recently opened tab (useful after clicking links that open new tabs, OAuth popups, etc.).

Inputs: no named parameters.

browser_get_page_contentB

Get the content of the current page as text or HTML.

Inputs: format, workspace, use_debugger.

browser_handle_dialogA

Handle JavaScript alert(), confirm(), or prompt() dialogs. Call this BEFORE triggering the action that causes the dialog. Waits for the dialog to appear, then accepts or dismisses it.

Inputs: text, action, timeout.

browser_hoverA

Hover over an element to trigger tooltips, dropdown menus, or hover states. Supports CSS and text selectors.

Inputs: selector (required), duration.

browser_list_framesA

List all frames (iframes) in the current page with their URLs and indices.

Inputs: no named parameters.

browser_list_tabsA

List tabs in the active workspace (or all workspaces). Shows Chrome tab group names/colors.

Inputs: workspace, all_workspaces.

browser_navigateA

Navigate to a URL. Pass task="短任务名" so Chrome creates/uses a tab group with that exact name (Codex-style). Parallel tasks MUST use different task names. workspace/group are aliases of task. Optional window_id keeps work in a dedicated Chrome window (separate from the user window).

Inputs: url (required), task, group, new_tab, +3 more.

browser_paste_from_clipboardA

SECRET-SAFE: Paste the system clipboard into a form field WITHOUT the content ever being returned — only the character count comes back. Pairs with browser_copy_to_clipboard for credential moves between pages/apps. Trims whitespace by default (trim:false to keep).

Inputs: selector (required), trim.

browser_press_keyA

Press a keyboard key (Enter, Tab, Escape, ArrowDown, etc.). Useful for submitting forms, navigating dropdowns, closing dialogs. Supports modifier keys (ctrl, alt, shift, meta).

Inputs: key (required), alt, code, ctrl, +2 more.

browser_reattach_debuggerA

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.

Inputs: no named parameters.

browser_right_clickA

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.

Inputs: selector (required).

browser_screenshotA

Take a screenshot of the visible area of the current tab. Returns base64 PNG, or saves to disk if path is provided.

Inputs: path.

browser_scrollA

Scroll the page to an element or by pixel amount. Useful for reaching elements below the fold.

Inputs: x, y, selector.

browser_select_frameA

Execute JavaScript in a specific iframe by frame index. Use browser_list_frames first to find the right index.

Inputs: frame_index (required), code.

browser_select_optionA

Select an option from a dropdown menu. Works with native elements AND custom dropdowns (Angular Material, React Select, etc.). For custom dropdowns: clicks the trigger, waits for options, then clicks the matching option by text. For autocomplete (typing filters options) use browser_set_combobox instead.

Inputs: option (required), selector (required), wait.

browser_set_comboboxA

Set value(s) on an autocomplete/combobox input. Handles the click → type query → wait for filtered listbox → click option flow as one MCP call. Supports multi-select (e.g., Languages on Meta Ads). Use when browser_select_option fails because options render lazily after typing.

Inputs: selector (required), multi, value, values, +2 more.

browser_set_cookiesB

Set one or more cookies for a domain.

Inputs: name (required), value (required), url, path, +5 more.

browser_set_dateA

Robustly set a date input — handles native , masked text inputs (e.g. MM/DD/YYYY), and calendar pickers (MUI, react-datepicker, AntD, Lexical/Meta). Tries native value-set, format-aware typing via Input.insertText, and ARIA-based picker navigation in sequence with read-back verification. Use instead of browser_fill when fill fails or for any input that opens a calendar widget.

Inputs: date (required), selector (required), skip_picker.

browser_set_local_storageA

Set a localStorage key-value pair on the current page.

Inputs: key (required), value (required).

browser_set_optionsA

Set session options. use_debugger=false (default) avoids the yellow Chrome "debugging this browser" banner; set true only when scripting fails on CSP-strict sites.

Inputs: use_debugger.

browser_solve_captchaA

Detect and solve CAPTCHAs on the current page. Auto-detects reCAPTCHA v2/v3, hCaptcha, Cloudflare Turnstile, and FunCaptcha. Tries auto-click first (often clears reCAPTCHA v2 when signed into Google), then returns a screenshot for AI vision analysis, then falls back to asking the user. Returns detection info and solving status.

Inputs: cells, action.

browser_switch_tabA

Switch to a specific browser tab by ID. Get tab IDs from browser_list_tabs or browser_get_new_tab.

Inputs: tab_id (required).

browser_upload_fileA

Upload a file to a element on the page. Uses Chrome Debugger API to set files programmatically — no dialog needed. For drag-drop zones without visible file input use browser_drop_file.

Inputs: files (required), file, selector.

browser_use_workspaceA

Switch the active Chrome tab group to a task name. Creates the group if missing.

Inputs: name, task, group, workspace.

browser_waitA

Wait for an element to appear on the page. Supports CSS and text-based selectors.

Inputs: selector (required), timeout.

browser_wait_for_networkA

Wait for a network request to complete. Useful after clicking buttons that trigger API calls — ensures data is loaded before reading the page. Monitors real network traffic via Chrome DevTools Protocol.

Inputs: timeout, url_pattern.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.6/5.0

    Scored across 45 tools

    Disambiguation4/5

    Most tools target clearly distinct actions or resource types, and the descriptions heavily cross-reference when to prefer one alternative over another (e.g., browser_set_date vs browser_fill, browser_drop_file vs browser_upload_file). The main ambiguity risk comes from the cluster of click variants and form-input tools, but the descriptions do enough to disambiguate them.

    Naming Consistency4/5

    The browser_ prefix and snake_case style are consistent, and most names follow a verb_noun pattern. A few exceptions like browser_screenshot, browser_console_logs, browser_clipboard_stats, and browser_about deviate from the verb-first convention, creating minor inconsistency.

    Tool Count2/5

    45 tools is well above the 25+ threshold for 'too many' and will create real selection overhead for agents. While browser automation is a broad domain, the surface could likely be consolidated or split into focused servers.

    Completeness4/5

    The toolset is remarkably comprehensive, covering navigation, interaction, forms, files, dialogs, tabs/windows, frames, network, storage, clipboard, and user-in-the-loop flows. Minor gaps exist—such as explicit back/forward/reload navigation and delete-cookie/clear-storage operations—but most workflows can still be completed through workarounds.

    Maintenance

    ActivityNo data
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables remote AI agents to control a local, authenticated desktop browser over MCP through an outbound WebSocket bridge and Chrome extension, supporting tab management, navigation, page reading, clicking, typing, scrolling, screenshots, and JavaScript evaluation.
      1
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables MCP-driven browser automation from any MCP client by pairing with a Chrome extension, translating tool calls into WebSocket commands to drive Chrome without an Electron host.
      2,571 npm
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables local MCP clients to inspect and interact with Chromium pages, manage isolated workspaces, hand off live tabs, and use scoped account and file grants under explicit human-approved permissions.
      3
      Apache 2.0
    • A
      license
      Not graded
      quality
      A
      maintenance
      A local MCP server that lets AI coding tools drive the user's own already-logged-in Chrome — clicking, typing, reading pages, taking screenshots, and inspecting cookies, network, and console through the extension rather than a debug port. All communication stays on the machine, with agent-opened tabs grouped and kept out of focus.
      1 npm
      ISC