BrowserBuddy

BrowserBuddy

An MCP server that turns your real Chrome or Firefox browser into a shared space with an AI assistant, enabling it to act, observe, wait for you, collaborate step-by-step, and learn tasks from demonstrations.

Category
Visit Server

README

<!-- Auto-generated by selfdoc from docs/_README.md — do not edit -->

BrowserBuddy

browserbuddy 0.1.0 — an MCP stdio server plus a cross-browser WebExtension. Requires Node.js 22 or newer.

What it is

BrowserBuddy turns your real browser — Chrome or Firefox — into a space you share with an AI assistant. The assistant is not driving a separate throwaway browser somewhere off to the side — it is in the same window you are, with your logins, your tabs, and your session. It can do things for you, but it can also watch what you do, learn a task by watching you do it once, and work alongside you one step at a time.

Five capabilities:

  • Act for you. Navigate, click, fill forms, scroll, zoom, screenshot, download, read page content, evaluate JavaScript.
  • Watch you. Your navigation, clicks, typing, scrolling, copy/paste, tab switches and downloads stream to the assistant as a queryable event log.
  • Wait for you. browser_wait_for_user blocks until your next action, so the assistant can pause mid-task and let you take over.
  • Work in lockstep. The assistant does a step, waits for you to do yours, then continues — a genuine turn-taking loop rather than a one-shot script.
  • Learn from you. Record a demonstration, perform the task once yourself, and the assistant keeps a cleaned step list it can replay later against different values.

How it compares

Most browser tooling for assistants (chrome-devtools-mcp, Playwright MCP, and anything else built on the Chrome DevTools Protocol) drives a browser through a debug port — usually a fresh profile, always with an automation surface a site can detect: navigator.webdriver, the CDP infobar, an open debugging port. BrowserBuddy is a plain browser extension running in the browser you already use, so it inherits your real sessions and logins, opens no debug port, and sets no automation flags. The larger difference is direction: CDP tools only let an assistant act. BrowserBuddy also lets it see — what you clicked, what you typed, where you went — which is what makes lockstep collaboration and learning from demonstration possible at all.

Setup

1. Load the extension

One extension/ directory serves both browsers; the manifest declares both a service worker (Chrome) and an event page (Firefox), and each browser picks its own.

Chrome:

  1. Open chrome://extensions.
  2. Turn on Developer mode (top right).
  3. Click Load unpacked and select the extension/ directory of this repo.

Firefox (128 or newer):

  1. Open about:debugging, choose This Firefox.
  2. Click Load Temporary Add-on… and select extension/manifest.json.
  3. Grant host permissions: open about:addons → BrowserBuddy → Permissions → enable Access your data for all websites. Firefox treats MV3 host permissions as opt-in, and without this grant the content script cannot run, so page reads, clicks, fills and observation will all fail.

A temporary add-on is removed when Firefox exits; reload it after a restart. Firefox older than 128 refuses to install the extension (strict_min_version — main-world script injection, which browser_eval needs, does not exist before 128).

The toolbar badge shows a green while the extension is connected to the hub, and is cleared when it is not.

The hub URL is a hardcoded constant in extension/background.js:

const WS_URL = 'ws://127.0.0.1:8590/ws';

There is no options page and no configuration UI. If you run the server on another port, edit that line and reload the extension.

2. Install the dependencies

npm install

Node.js 22 or newer is required.

3. Register the MCP server with Claude Code

claude mcp add browserbuddy -- node /absolute/path/to/browserbuddy/server/src/index.js serve

The CLI is a single command:

Command Description
serve Run the MCP stdio server and the WebSocket hub the browser extension connects to.

serve accepts two flags:

Flag Default Purpose
--port <n> 8590 WebSocket hub port on 127.0.0.1. If you change it, edit WS_URL in extension/background.js to match and reload the extension.
--data-dir <path> server/data Where event logs and demonstrations are written.

4. Ordering does not matter

The server process runs only while a Claude Code session has the MCP server loaded; it exits with that session. The extension reconnects on its own on a fixed 1s/2s/5s/10s retry ladder, with a 30-second alarm as a backstop, so you can start the browser first, Claude Code first, or restart either one mid-session. When the hub is down, no events are recorded and every acting tool fails loudly rather than pretending to work.

If port 8590 is already occupied, the server exits immediately instead of picking another port — a silently relocated hub would leave the extension connected to nothing.

Tool catalog

25 MCP tools: 18 acting, 3 observing, 4 learning.

Acting

Tool Arguments Purpose
browser_tabs List open tabs with id, url, title and which is active.
browser_open_tab url? Open a new tab, optionally at a URL. Returns the new tabId.
browser_close_tab tabId Close a tab.
browser_focus_tab tabId Make a tab the active one.
browser_navigate url, tabId? Navigate a tab to a URL.
browser_back tabId? Go back in history.
browser_forward tabId? Go forward in history.
browser_reload tabId? Reload the page.
browser_read mode: text|outline|links|forms (default text), tabId? Read the page as plain text, a heading outline, a link list, or a form/field inventory.
browser_screenshot tabId? Capture the tab as a JPEG image (tab is activated first).
browser_click selector? or text?, tabId? Click an element by selector, or by visible text. At least one of the two is required.
browser_fill selector, value, submit? (default false), tabId? Set a field's value (React-compatible) and optionally submit the form.
browser_scroll direction: up|down|top|bottom, amount? (default 1), tabId? Scroll up or down by a number of viewport pages, or jump to the top or bottom.
browser_zoom factor, tabId? Set the tab's zoom factor (1 is 100%).
browser_set_clipboard text Put text on the system clipboard.
browser_download url, filename? Download a URL through the browser (with your cookies).
browser_page_state tabId? Cheap status read: url, title, readyState, scroll offset, focused element selector.
browser_eval code, tabId? Evaluate JavaScript in the page's main world and return the result.

Every tool that takes an optional tabId defaults to the active tab of the last-focused window.

Observing

Tool Arguments Purpose
browser_state Connection status, active tab, whether a demonstration is recording, and event counters (eventCount, latestSeq). If the tab lookup fails it reports activeTabError instead of failing the call.
browser_observe sinceSeq?, limit? (integer 1–200, default 30), types?, actor? (user|agent|all, default user) Read recent events from the log, filtered by sequence number, type or actor. The most recent matches are kept.
browser_wait_for_user types?, tabId?, timeoutSec? (integer 1–600, default 120) Block until your next matching action, then return that event, or {timedOut: true}. The lockstep primitive.

Learning

Tool Arguments Purpose
demo_record_start name, description?, overwrite? (default false) Begin recording a demonstration under a name.
demo_record_stop Stop recording, clean the captured steps, and persist them.
demo_list List saved demonstrations with names, descriptions and step counts.
demo_get name Retrieve a demonstration's cleaned step list.

Demonstration replay is deliberately agent-mediated: there is no demo_replay tool. The assistant reads the steps with demo_get and re-performs them with the acting tools, substituting new values and adapting to whatever the page actually looks like now.

Ways of working

Do it for me

You describe the outcome; the assistant works alone. "Open my orders page, find the order from last Tuesday, and tell me its tracking number." The assistant uses browser_open_tab, browser_read, browser_click, and reports back. You never touch the keyboard.

Watch and narrate

You drive; the assistant observes. Ask it to follow along, and it polls browser_observe (or blocks on browser_wait_for_user) while you work — noticing which fields you filled, which link you followed, what you copied. Useful for "am I doing this right?", for having it write down what you just did, or for debugging a flow you can reproduce but not describe.

Lockstep

Turn-taking on one task. The assistant fills the parts of a form it knows, then calls browser_wait_for_user and stops. You solve the CAPTCHA, pick the option only you can pick, or approve the payment. Your action wakes the assistant, it reads the new page state, and it continues from there. Anything requiring your judgement or your second factor fits this shape.

Teach by demonstration

  1. Ask the assistant to run demo_record_start with a name, e.g. file-expense-report.
  2. Perform the task yourself, once, at normal speed.
  3. Ask it to run demo_record_stop. Your clicks, typing, key presses, submits, navigations, page loads, tab changes and downloads are reduced to a clean step list — repeated typing in one field collapses to its final value, and a page load that merely echoes a navigation is dropped. Scrolling, copying and pasting are never recorded. Anything redacted is flagged rather than stored.
  4. Later: "file an expense report for the 48 EUR taxi on the 3rd." The assistant calls demo_get file-expense-report, reads how you did it, and performs the same steps with the new values — re-finding elements live rather than blindly replaying coordinates.

Privacy and data

<div class="callout callout-important"> <p class="callout-title">Important</p> <p>Redaction happens at the source, inside the page, before anything is sent. A sensitive value never reaches the hub, never reaches the disk, and is never visible to the assistant.</p> </div>

A field's value is replaced with [REDACTED] when any of the following hold:

  • the input's type is password;
  • its autocomplete attribute starts with cc- (credit card fields);
  • its name, id or aria-label matches /pass(word)?|card|cvv|cvc|ssn|secret|token|otp|pin\b/i.

This applies uniformly to observed input events, page reads (browser_read in forms mode) and recorded demonstration steps. Redacted values are never transmitted to the hub, never written to disk, and never visible to the assistant — it sees only that a redacted field exists and was filled. A forms-mode read of a redacted field carries an explicit redacted: true flag alongside the [REDACTED] value; unredacted fields carry no flag.

Redaction also covers the ways a sensitive value could leak through a different event:

  • Clicks. A click event describes the element by its visible text; when the element has none, the fallback would be its value. For a sensitive element the text is [REDACTED] instead.
  • Copy. The preview is [REDACTED] when either the copy target or the focused element is a sensitive field, since the selection lives in the focused field.
  • Paste. The preview is [REDACTED] when the field being pasted into is sensitive.

What is stored, and where:

Data Location Format
Event log server/data/events/ JSONL, one event per line, one file per UTC day (YYYY-MM-DD.jsonl), appended across server restarts
Recent events in-process ring buffer (1000 entries) memory only
Demonstrations server/data/demos/ one JSON file per demonstration

Everything is plain text on your local disk. Nothing is sent anywhere: the hub binds to 127.0.0.1 only, and the only data that leaves your machine is whatever the assistant itself reads into your Claude Code conversation — which is exactly the data you asked it to look at. Events flow only while the hub is running; with no Claude Code session loaded, the extension is a disconnected no-op that records nothing.

Copy and paste events from ordinary page content keep only a preview of at most 200 characters, not the full clipboard contents.

Limitations

Accepted trade-offs in version 0.1.0:

  • Synthetic clicks are isTrusted: false. Extension-generated events are distinguishable from human ones. Most sites do not care; a few hardened ones (some payment and anti-fraud flows) ignore them. Those steps need you — which is what lockstep is for.
  • browser_eval is subject to page CSP. A strict Content-Security-Policy can block main-world evaluation. This is reported as a hard error, not silently worked around.
  • Screenshots capture the visible tab only. The browser can only capture what is on screen, so browser_screenshot activates the target tab first. Expect your foreground tab to change.
  • No browser-internal pages. Content scripts cannot run on chrome:// or about: pages, the Chrome Web Store, addons.mozilla.org, or other extensions' pages, so nothing there can be observed or acted on.
  • Firefox suspends the background at idle. Firefox does not count WebSocket traffic as background activity, so at idle it suspends the extension's event page and the 30-second alarm revives it — roughly one reconnect per minute, during which acting tools fail with the not-connected error (retry succeeds within ~30 s) and observed events are buffered, not lost. Chrome keeps the socket's service worker alive continuously.
  • One browser profile at a time. The hub accepts a single extension connection; a new hello closes the previous one. This also means Chrome and Firefox cannot be connected simultaneously.
  • Port 8590 must be free. The server exits rather than falling back to another port.

<div class="callout callout-warning"> <p class="callout-title">Warning</p> <p>Screenshots on Firefox need a gesture. Firefox MV3 never treats granted host permissions as capture permission, so <code>browser_screenshot</code> fails with a hard error explaining the one supported path: click the BrowserBuddy toolbar button on the tab (this grants <code>activeTab</code>), then retry. The grant lasts until the tab navigates. On Chrome no gesture is needed.</p> </div>

Layout

  • extension/ — cross-browser MV3 extension (Chrome and Firefox, one codebase)
    • manifest.json — MV3 manifest: permissions, both background entry points (service worker + event page), Firefox settings
    • background.js — background script (service worker on Chrome, event page on Firefox): WebSocket client, tab-level observation, RPC dispatch, badge state
    • content.js — injected into pages: DOM observation, selector construction, redaction, DOM-level RPC execution
  • package.json — the npm package root (browserbuddy); npm install and npm test run from here
  • server/ — Node.js process, MCP stdio server and WebSocket hub in one
    • src/index.jsbrowserbuddy bin entry point
    • src/cli.js — strictcli command definition (serve) and server startup
    • data/ — runtime state (gitignored)
      • events/ — JSONL event logs
      • demos/ — recorded demonstrations
  • docs/
    • ARCHITECTURE.md — components, data flow, and the reasoning behind the design
    • PROTOCOL.md — the complete extension/hub wire protocol

License

Apache-2.0

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured