browser-relay-mcp

browser-relay-mcp

Unlimited, session-authenticated web search and fetch for AI tools using your own browser. Supports authenticated/paywalled pages without API keys.

Category
Visit Server

README

browser-relay-mcp

Unlimited, session-authenticated web search + fetch for your AI tools — driven through your own browser, behind a local MCP server.

No API keys, no per-query billing, no rate-limit walls. Searches and page fetches run in a real browser that is already logged into the sites you use, so paywalled / authenticated pages come back as clean readable text just like you'd see them.

Two interchangeable drivers sit behind one MCP surface:

  • relay (default) — drives your logged-in Chrome via a loaded extension. The extension polls the local relay at http://localhost:15552, runs the search/fetch in a tab, and posts the result back. Your sessions, your cookies.
  • cloak — an embedded patchright stealth browser, launched in-process by the relay. For bot-protected or unattended pages where you don't want to (or can't) use your attended Chrome. Requires patchright install chromium once.

Every MCP tool takes a driver parameter, so a caller can pick per-request.

Architecture

                          ┌─────────────────────────────────────────┐
  MCP client              │  browser-relay-mcp                        │
  (Claude, STORM, …)      │                                           │
        │                 │   MCP server  (stdio / FastMCP)           │
        │  search/fetch/  │       │                                   │
        │  search_and_    │       │  HTTP                             │
        │  fetch/resume/  │       ▼                                   │
        └───────────────► │   relay  (FastAPI @ localhost:15552)      │
           tool call      │       │                                   │
                          │       ├── driver=relay ─► job queue ──────┼──┐
                          │       │                                   │  │ poll /pending
                          │       │                                   │  │ post /result
                          │       └── driver=cloak ─► patchright ─────┼─┐│
                          └─────────────────────────────────────────┘ ││
                                                                       ││
                  ┌────────────────────────────────────────────────┐  ││
                  │  embedded stealth Chromium (in-process) ◄────────┼──┘│
                  └────────────────────────────────────────────────┘   │
                  ┌────────────────────────────────────────────────┐   │
                  │  YOUR logged-in Chrome  +  Browser Relay ext ◄───┼───┘
                  │  (polls localhost:15552, runs job in a tab)      │
                  └────────────────────────────────────────────────┘

The MCP server auto-starts the relay backend on first use (a local FastAPI process on 127.0.0.1:15552). The relay driver needs the Chrome extension loaded and pointed at that URL; the cloak driver needs patchright install chromium.

Install

1. The MCP server

Run it with uv — no checkout required:

uvx browser-relay-mcp

Add it to your MCP client config:

{ "mcpServers": { "browser-relay": { "command": "uvx", "args": ["browser-relay-mcp"] } } }

2. The Chrome extension (for the relay driver)

  1. Open chrome://extensions, enable Developer mode.
  2. Load unpacked → select the extension/ directory (or unzip a packaged build — see Packaging).
  3. Open the extension's options and set the Relay server URL to http://localhost:15552.
  4. The popup status should read Relay OK / connected.

The extension only acts on pages the relay explicitly tells it to drive — see docs/privacy-policy.md.

3. The cloak browser (for the cloak driver)

One-time, to download the stealth Chromium build patchright uses:

patchright install chromium

If you only ever use driver: "relay", this step is optional. When it's missing, /health reports the cloak driver as unavailable instead of failing your relay calls.

Tools

All tools return a JSON string. The driver parameter selects which backend runs the request.

Tool Signature Returns
search search(query, k=10, engine="bing", driver="relay") {status, query, engine, driver, count, results:[{title, url, snippet}]}
fetch fetch(url, include_html=False, driver="relay") {status, url, driver, title, text, excerpt, length[, html]}
search_and_fetch search_and_fetch(query, k=5, engine="bing", driver="relay") {status, query, engine, driver, count, results:[{title, url, snippet, text, length, fetch_error}]}
resume resume(resume_token) the completed result, action_required again if still blocked, or error if the token expired
health health() relay + extension + cloak connectivity and queue depth (see below)

search_and_fetch runs the search, then fetches the top-k results in parallel. A page that fails to fetch records its own fetch_error and text=""; the batch still returns. Per-result escalation inside the batch is non-interactive — a blocked result is reported as fetch_error: "action_required: <action>", and you re-drive it with an individual fetch(url).

health shape

{
  "status": "ok",
  "extension_connected": true,
  "extension_status": "connected",
  "last_poll_age_seconds": 2.1,
  "search_queued": 0,
  "fetch_queued": 0,
  "in_flight": 0,
  "max_fetch_tabs": 5,
  "engine": "bing",
  "pending_actions": [],
  "version": "0.1.0",
  "drivers": {
    "relay": { "extension_connected": true, "extension_status": "connected", "last_poll_age_seconds": 2.1 },
    "cloak": { "available": true, "profile_path": "…/browser-relay/cloak-profile", "pages_open": 0 }
  }
}

extension_status is one of connected, stale (extension was seen but hasn't polled within ~75s), or never_seen. The cloak block reports available: false with an error when patchright's browser isn't installed.

Escalation flow (CAPTCHA / login)

When a search or fetch hits a CAPTCHA or a login wall, the call doesn't fail — it pauses and surfaces the blocked browser to you:

search/fetch  ──►  status: "action_required"
                   { driver, action: "solve_captcha" | "login",
                     message, resume_token, query|url }
                          │
        you solve the CAPTCHA / sign in
        in the surfaced browser window
                          │
                          ▼
        resume(resume_token)  ──►  status: "ok" (completed result)
                                   status: "action_required" (still blocked — solve again, same token)
                                   status: "error" (token expired, default TTL 300s)
  • relay: the extension holds the tab open; you solve it in your Chrome.
  • cloak: the embedded browser window is non-headless on purpose so you can solve the challenge there.

resume reuses the held tab/page rather than starting over, and the same resume_token stays valid across repeated action_required rounds until it succeeds or the TTL (BROWSER_RELAY_ACTION_TTL, default 300s) expires.

STORM adapter

adapters/storm.py maps a search_and_fetch result into the STORM / dspy retriever shape, so browser-relay can back STORM's knowledge-curation retrieval:

from adapters.storm import to_storm

# `result` is the parsed dict from search_and_fetch(...)
sources = to_storm(result)
# -> [{ "url", "title", "description", "snippets": [chunks of the page text] }, ...]

Only results that actually came back with text are included; page text is chunked (1000 chars/chunk) into snippets.

Run the acceptance checks

The PRD acceptance criteria are split between a live human-attended script and unit tests.

Live (C1–C4) — requires Chrome with the extension loaded and signed in:

# 1. start the relay
cd server && uv run browser-relay-mcp --backend --port 15552

# 2. in Chrome: load unpacked extension/, set server URL to http://localhost:15552 (status: connected)

# 3. run the checks
uv run --with httpx python tests/acceptance/run_acceptance.py

Expected output ends with ALL ACCEPTANCE CRITERIA PASSED. See tests/acceptance/README.md for what each criterion verifies (C3 is the headline test: 50 sequential searches with 0 errors and 0 silent-empty result sets).

STORM adapter (C5) — unit test:

cd adapters && python -m pytest tests/test_storm.py

Server + cloak suites:

cd server && uv run pytest                      # full server suite
BROWSER_RELAY_RUN_CLOAK_TESTS=1 uv run pytest   # include live cloak tests

Extension unit tests:

npm test

Packaging the extension

bash scripts/package-extension.sh
# wrote dist/browser-relay-extension.zip

This regenerates the injected bundles (npm run build:inject) and zips extension/ (tests excluded) for the Chrome Web Store or manual install. dist/ is gitignored.

Configuration

Env var Default Purpose
BROWSER_RELAY_URL http://127.0.0.1:15552 Relay base URL the MCP server talks to
BROWSER_RELAY_FETCH_CAP 5 Max parallel fetch tabs
BROWSER_RELAY_SEARCH_CONCURRENCY 1 Concurrent searches (near-serial by design)
BROWSER_RELAY_SEARCH_MIN_SPACING_MS 500 Minimum spacing between search dispatches
BROWSER_RELAY_ACTION_TTL 300 Seconds a paused (action_required) request stays resumable
BROWSER_RELAY_DEFAULT_ENGINE bing Default search engine
BROWSER_RELAY_CLOAK_PROFILE_DIR user cache dir Persistent profile for the cloak browser

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
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
E2B

E2B

Using MCP to run code via e2b.

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