Skip to main content
Glama
ton-to-ton

Real Browser MCP

by ton-to-ton

Real Browser MCP

Browser automation over MCP using a real Chrome-family browser and your existing profile.

This project is based on the upstream browser-bridge architecture:

MCP Server <-> Local Broker (unix socket) <-> Native Host <-> Chrome Extension

It keeps the parts that made the upstream bridge reliable:

  • Chrome extension for real tabs and real profiles

  • Native Messaging instead of exposing a WebSocket port

  • Local broker with per-session tab ownership

  • CLI installer for extension + native host setup

The main entrypoint is a stdio MCP server, so Codex and other stdio-capable MCP clients can load the same browser tools directly. The server stays stdio-only, but now also exposes MCP resources/* and prompts/* for discovery-oriented clients.

The product focus is browser RPA over your real Chrome profile:

  • logged-in business sites

  • real downloads, cookies, and storage state

  • repeatable list/detail/download/extract workflows

  • deterministic run records that can be resumed or inspected later

Status

Implemented in this repo:

  • Chrome extension

  • Native host

  • Local broker

  • stdio MCP server

  • CLI commands for install, status, tools, self-test, and MCP serving

  • Extension-backed self-test coverage for screenshot, download, structured extract, task runner, and network mock flows

Related MCP server: Tabrix

Install

  1. Install dependencies if you want to use agent mode later:

npm install

This only installs dependencies. The browser/native-host setup stays behind the explicit npx real-browser-mcp install step.

  1. Install the extension and native host.

If you are running inside WSL and want to automate native Windows Chrome, use the Windows runtime explicitly:

npx real-browser-mcp install --runtime-target windows

This is the standard WSL path. The installer places the runtime under C:\Users\<you>\.real-browser-mcp\ and auto-installs a portable Windows node.exe there if Windows Node is missing. See WSL Quick Start below for the full flow.

If you want a local runtime instead:

npx real-browser-mcp install

From WSL, npx real-browser-mcp install --runtime-target local keeps the runtime inside WSL/Linux instead of Windows.

  1. Load the unpacked extension in Chrome:

  • Open chrome://extensions

  • Turn on Developer mode

  • Click Load unpacked

  • Select the extension directory printed by the installer

If you want native isolated contexts (browser_context_* on the native backend), open the extension details page and enable Allow in Incognito.

When the extension prompts for permissions, grant site access and the optional runtime permissions used by the current flow:

  • nativeMessaging

  • downloads

  • debugger

  • cookies

  • <all_urls>

After npx real-browser-mcp update, reload the extension from chrome://extensions so Chrome picks up the refreshed files from the runtime path printed by the updater.

You can verify the native backend is connected with:

npx real-browser-mcp tool browser_status --backend native

From WSL, add --runtime-target windows if you want to probe the Windows runtime explicitly.

hostConnected: true means the extension reached the native host through the broker.

  1. Register the MCP server with your MCP client.

For Codex:

codex mcp add real-browser-mcp -- ~/.real-browser-mcp/mcp-wrapper.sh

For OpenCode, add this to ~/.config/opencode/opencode.json or ~/.config/opencode/opencode.jsonc:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "real-browser-mcp": {
      "type": "local",
      "command": ["/Users/<you>/.real-browser-mcp/mcp-wrapper.sh"],
      "enabled": true
    }
  }
}

If opencode is on your PATH, npx real-browser-mcp install and npx real-browser-mcp update will create or refresh that MCP entry automatically. If you use a custom OpenCode config file, set OPENCODE_CONFIG before running those commands. Existing opencode.json and opencode.jsonc files are both detected.

If you are developing inside this repo, the checked-in opencode.json already points OpenCode at the local node bin/cli.js mcp entrypoint, so launching OpenCode from the repo root picks it up automatically.

  1. Restart your MCP client.

The installer copies the unpacked extension into the selected runtime directory, registers the Native Messaging host, refreshes the global OpenCode MCP entry when opencode is on your PATH (or an OpenCode config already exists), and can prompt you to add the Codex MCP entry automatically if codex is on your PATH. It also installs a stable MCP wrapper under ~/.real-browser-mcp/, so MCP clients do not depend on a transient npx cache path. If you already have a ~/.codex-browser/ install, npx real-browser-mcp update migrates or merges it into the selected runtime directory. After that migration, open chrome://extensions once and load the unpacked extension again from the path printed by the updater.

WSL

WSL Quick Start

For the default WSL-to-Windows Chrome setup, use the Windows runtime explicitly:

npx real-browser-mcp install --runtime-target windows

The standard WSL flow is now:

  1. The installer sets up the real browser runtime under C:\Users\<you>\.real-browser-mcp\

  2. If Windows does not already have node.exe, the installer downloads and installs a portable official Node.js build under C:\Users\<you>\.real-browser-mcp\portable-node\

  3. Windows Chrome loads the unpacked extension from C:\Users\<you>\.real-browser-mcp\extension

  4. WSL-side MCP clients keep using ~/.real-browser-mcp/mcp-wrapper.sh

No manual REAL_BROWSER_MCP_WINDOWS_NODE setup is required for the default path.

After loading the extension in Windows Chrome, verify the bridge from WSL:

npx real-browser-mcp tool browser_status --backend native --runtime-target windows --json

Expect hostConnected: true and nativeReady: true.

When you run the CLI from WSL, the first install or update will ask which runtime target to use:

  • Windows native Chrome (recommended, default)

  • Linux/WSL local runtime

In Windows-target mode:

  • the real browser runtime is installed under your Windows profile

  • the installer prefers a Windows node.exe on PATH, but automatically bootstraps a portable Windows Node.js under C:\Users\<you>\.real-browser-mcp\portable-node\ when Windows Node is missing

  • Windows Chrome loads the unpacked extension from the Windows path printed by the installer

  • the WSL-side ~/.real-browser-mcp/mcp-wrapper.sh becomes a proxy that forwards OpenCode/Codex into the Windows runtime

  • npx real-browser-mcp tool ... --runtime-target windows and npx real-browser-mcp self-test --runtime-target windows also use that same Windows runtime

That means a separate global Node.js install on Windows is optional for the WSL flow.

If you want to override the default Windows-side paths, these environment variables are available:

  • REAL_BROWSER_MCP_WINDOWS_NODE: explicit Windows node.exe path

  • REAL_BROWSER_MCP_WINDOWS_BASE_DIR: explicit Windows runtime base directory

  • REAL_BROWSER_MCP_WINDOWS_USERPROFILE: explicit Windows profile directory used to derive the runtime base directory

The default WSL flow no longer requires setting REAL_BROWSER_MCP_WINDOWS_NODE just to get started.

You can switch explicitly at any time:

npx real-browser-mcp install --runtime-target windows
npx real-browser-mcp update --runtime-target local

Agent Mode via TCP Gateway (WSL → Windows native browser)

agent-browser normally communicates over a Unix socket. When the MCP server runs in WSL but the real browser (and agent-browser daemon) runs on Windows, the agent-gateway bridges the two over TCP.

Starting the gateway on Windows:

# On the Windows side (PowerShell or cmd), with a shared secret:
set REAL_BROWSER_MCP_AGENT_GATEWAY_TOKEN=<your-secret>
node C:\Users\<you>\.real-browser-mcp\node_modules\.bin\real-browser-mcp agent-gateway

Or via the CLI (generates and persists a token automatically in ~/.real-browser-mcp/config.json):

npx real-browser-mcp agent-gateway

The gateway defaults to 127.0.0.1. To bind to a non-loopback interface so WSL can reach it, set the host explicitly and provide a token:

# On Windows — bind to all interfaces, require token auth
set REAL_BROWSER_MCP_AGENT_GATEWAY_HOST=0.0.0.0
set REAL_BROWSER_MCP_AGENT_GATEWAY_TOKEN=<your-secret>
node bin/agent-gateway.cjs

Security invariant: The gateway refuses to start if the resolved host is non-loopback (0.0.0.0, an explicit IP, etc.) and no token is configured. This prevents accidental unauthenticated LAN exposure.

Connecting from WSL:

# On the WSL side — point the agent backend at the Windows gateway
export REAL_BROWSER_MCP_AGENT_HOST=<windows-ip>   # e.g. 172.x.x.x
export REAL_BROWSER_MCP_AGENT_GATEWAY_TOKEN=<your-secret>
npx real-browser-mcp backend agent
npx real-browser-mcp tool browser_status

The token value set in REAL_BROWSER_MCP_AGENT_GATEWAY_TOKEN must be identical on the Windows gateway side and the WSL client side. The MCP server sends an auth handshake line before any protocol traffic so the gateway can verify the client before proxying.

Fallback: OPENCODE_BROWSER_AGENT_GATEWAY_TOKEN and OPENCODE_BROWSER_AGENT_GATEWAY_HOST are accepted as fallbacks for backward compatibility, but REAL_BROWSER_MCP_* names take precedence and are the canonical names to use.

Development

For maintainer work in this repo, rebuild the runtime payload after changing files in src/:

npm run build
node build-cws-package.mjs

src/*.ts changes are not live until dist/*.js is rebuilt.

For sandboxed or test runs, you can redirect mutable runtime state without changing the installed broker/native-host path:

REAL_BROWSER_MCP_STATE_DIR=/tmp/real-browser-mcp-state node bin/cli.js tool browser_status --backend native

This moves contexts, tasks, RPA runs, logs, and artifacts under the override directory while still talking to the normal installed browser bridge.

Usage

After registration, your MCP client gets these tools:

  • browser_status

  • browser_get_tabs

  • browser_open_tab

  • browser_close_tab

  • browser_navigate

  • browser_query

  • browser_click

  • browser_hover

  • browser_type

  • browser_press_key

  • browser_select

  • browser_check

  • browser_uncheck

  • browser_focus

  • browser_blur

  • browser_drag

  • browser_evaluate

  • browser_handle_dialog

  • browser_scroll

  • browser_wait

  • browser_screenshot

  • browser_snapshot

  • browser_download

  • browser_list_downloads

  • browser_set_file_input

  • browser_highlight

  • browser_console

  • browser_errors

  • browser_context_list

  • browser_context_create

  • browser_context_use

  • browser_context_dispose

  • browser_cookies_get

  • browser_cookies_set

  • browser_cookies_clear

  • browser_storage_state_export

  • browser_storage_state_import

  • browser_emulate

  • browser_network_list

  • browser_route

  • browser_extract

  • browser_task

  • rpa_templates_list

  • rpa_runs_list

  • rpa_run_get

  • rpa_run_cancel

  • rpa_run

  • browser_trace_start

  • browser_trace_stop

  • browser_har_start

  • browser_har_stop

  • browser_video_start

  • browser_video_stop

browser_status now includes backend selection metadata for the active backend, including backendPreference, backendSource, selectionReason, backendRuntime, permission state, route/mock support, and whether isolated contexts and artifact capture are available.

For the native backend, use nativeReady / basicNativeReady plus statusSummary to tell whether normal profile-backed browser tools are usable. foregroundNativeReady and rpaExecutionReady are narrower and cover foreground-window-only flows such as rpa_run, although rpa_run will now try to bring a regular Chrome window to the foreground automatically before failing. rpaReady is still returned as a compatibility alias for rpaExecutionReady. browser_status also reports runtimeReady, runtimeStatusError, selectionRefreshedAt, regularHostSelectionSource, and ffmpeg so you can tell whether the status came from a fresh probe and why video support is or is not available.

The MCP surface also includes text-based resources and prompts:

  • Resources:

    • real-browser-mcp://server/info

    • real-browser-mcp://server/capabilities

    • real-browser-mcp://runtime/status

    • real-browser-mcp://runtime/contexts

    • real-browser-mcp://runtime/tabs

    • real-browser-mcp://runtime/tasks

    • real-browser-mcp://runtime/rpa-runs

  • Resource templates:

    • real-browser-mcp://runtime/tasks/{taskId}

    • real-browser-mcp://runtime/rpa-runs/{runId}

    • real-browser-mcp://runtime/tabs/{tabId}/snapshot

    • real-browser-mcp://runtime/tabs/{tabId}/console

    • real-browser-mcp://runtime/tabs/{tabId}/errors

    • real-browser-mcp://runtime/tabs/{tabId}/network

  • Prompts:

    • inspect_page

    • debug_page

    • download_from_page

    • capture_artifacts

    • run_browser_task

The resource layer is read-only and text-based. Prompts are runbooks that tell an MCP agent which browser_* tools to call; they do not execute tools by themselves.

For local debugging without an MCP client session:

npx real-browser-mcp tools
npx real-browser-mcp tool browser_status
npx real-browser-mcp tool browser_status --json
npx real-browser-mcp self-test

For read-only dataset collection against a live tab, use the snapshot collector script:

npm run collect:snapshot -- --config examples/hyperliquid-snapshot-config.json

For repeated capture windows, use count + intervalMs:

npm run collect:snapshot -- --config examples/hyperliquid-sequence-config.json

The sequence example now expects a real strategy event channel. Emit events into the local bridge first:

node scripts/runtime-event-bridge.mjs emit \
  --channel hyperliquid-hype-usdc \
  --event-json '{"source":"strategy-runtime","type":"breakout_candidate","symbol":"HYPE/USDC","signalContext":"sequence-monitor","confidence":0.82}'

Then the collector can resolve the latest event for that channel on each capture.

You can override labels per capture session:

npm run collect:snapshot -- \
  --config examples/hyperliquid-snapshot-config.json \
  --symbol HYPE/USDC \
  --label fake-breakout \
  --signal-context liquidation-cascade \
  --event-json '{"eventId":"evt-123","source":"strategy-feed","type":"breakout_candidate"}'

To auto-attach runtime events on every capture, either point the collector at a JSON file or a command that prints JSON:

npm run collect:snapshot -- \
  --config examples/hyperliquid-sequence-config.json \
  --event-command 'node scripts/runtime-event-bridge.mjs latest --channel hyperliquid-hype-usdc'

For WSL-only or containerized capture without the native-extension or agent-browser backends, the repo also supports a dedicated Chromium CDP collector path. Start the long-lived browser once:

npm run capture:docker:up
curl http://127.0.0.1:9222/json/version

capture:docker:up waits until the container-internal CDP endpoint is ready and prints the debugger URL. It then makes a best-effort attempt to expose the same CDP endpoint at 127.0.0.1:$CDP_PORT inside WSL and reports that result as hostReachable. If startup fails, it also prints docker compose ps and recent container logs. When Docker Desktop does not expose the published port back into WSL, the helper starts a local 127.0.0.1:$CDP_PORT relay. The raw Docker-published port is kept separate (CDP_PUBLISH_PORT, default 39222) so the relay can own 127.0.0.1:$CDP_PORT inside WSL without colliding with Docker's own port forward. Standalone npm run capture:docker:up now fails if the host-facing 127.0.0.1:$CDP_PORT endpoint is still unreachable after the relay attempt. The one-shot Docker capture commands still allow host-unreachable mode, including relay-startup failures, because collection runs inside the container. The default startup path is idempotent and reuses the long-lived browser container. If you need to rebuild the Chromium container after changing launch parameters, run npm run capture:docker:down first or set CDP_FORCE_RECREATE=1.

Then capture against that CDP endpoint directly:

npm run collect:snapshot:cdp -- \
  --config examples/hyperliquid-symbols/hype-snapshot-config.json \
  --cdp-url http://127.0.0.1:9222

For a single end-to-end run that starts Docker, waits for CDP readiness, and saves a HYPE chart image, you can also run:

npm run capture:docker:hype

This one-shot path runs the collector inside the Docker container, so it does not depend on the host being able to curl 127.0.0.1:9222. The default HYPE preset now expands the viewport, switches the TradingView chart to 1h, hides matching announcement overlays when they are present, and crops the screenshot to the chart iframe instead of the full trading page.

To switch the preset interval explicitly, run one of:

npm run capture:docker:hype:5m
npm run capture:docker:hype:1h
npm run capture:docker:hype:1d

You can also override the timeframe on any config-driven run:

npm run capture:docker:hype -- --timeframe 5m

If you need a different relay/container port, set CDP_PORT for both startup and one-shot capture, for example CDP_PORT=9333 npm run capture:docker:hype. If you also want to change the raw Docker-published port, set CDP_PUBLISH_PORT as well.

For repeated HYPE/USDC capture with a preset count and intervalMs, use:

npm run capture:docker:hype:sequence

That preset uses examples/hyperliquid-symbols/hype-sequence-config.json with count=60 and intervalMs=1000.

If you want the latest finalized HYPE chart artifact in a form that another agent can consume directly, run:

npm run capture:docker:hype:latest

That prints JSON with the latest chart.png, chartAbsolutePath, metadata.json, capture directory, timeframe, and image dimensions so a multimodal model can pick up the newest artifact without scanning the tree manually. For the shortest agent-facing handoff, see docs/hyperliquid-chart-analysis.md.

If multiple pages or chart tabs are open, the CDP collector reuses a uniquely matching page or opens the configured openUrl target when nothing matches. If multiple pages match the configured filters, it stops and asks you to pin the exact page with --tab-id <targetId> from http://127.0.0.1:9222/json/list.

You can still override label, signal context, output directory, and runtime event inputs (--event-json, --event-file, --event-command) the same way:

npm run collect:snapshot:cdp -- \
  --config examples/hyperliquid-symbols/btc-snapshot-config.json \
  --cdp-url http://127.0.0.1:9222 \
  --label setup-review \
  --signal-context breakout-monitor

The CDP collector keeps the same artifact directory layout as the standard collector (chart.png, metadata.json, page-text.json, selectors.json, optional snapshot.json and runtime-event.json). Its metadata also includes CDP-specific tab targeting details: metadata.tab.targetId is the real CDP target for /json/list and --tab-id, while metadata.tab.id / runtimeEvent.captureContext.tabId are stable synthetic numeric compatibility keys derived from that target and marked with idKind / tabIdKind = "synthetic-cdp-hash". The CDP path is intentionally read-only and aimed at public/chart-state capture rather than real-profile account state.

If your strategy can stream ndjson, you can keep the bridge updated continuously:

python3 your_strategy.py | node scripts/runtime-event-bridge.mjs ingest-stdin --channel hyperliquid-hype-usdc

Each line should be one JSON object such as:

{"source":"strategy-runtime","type":"liquidation_cascade","symbol":"HYPE/USDC","signalContext":"sequence-monitor","confidence":0.91,"emittedAt":"2026-03-18T05:20:00Z"}

The collector is intentionally read-only. It saves a screenshot, browser_snapshot, page_text, and selected DOM regions into a timestamped folder under artifacts/. This is useful for chart labeling, vision-model training data, and correlating runtime events with visible chart state. Keep trading execution on structured exchange APIs or websocket feeds; treat browser UI captures as secondary context rather than the primary source of truth.

For symbol-specific capture folders and presets, see the example configs under examples/hyperliquid-symbols/ such as examples/hyperliquid-symbols/hype-snapshot-config.json and examples/hyperliquid-symbols/gold-snapshot-config.json. These presets can carry symbol-specific notes and extra selectors for majors, higher-beta alts, or event-sensitive pairs. The verified chart-focused Docker presets currently cover BTC, ETH, SOL, SUI, XRP, SPX, WTIOIL, S&P500, XYZ100, GOLD, GLD, SLV, SPY, QQQ, QQQM, AAPL, AMZN, META, MSFT, GOOGL, HOOD, CRCL, THBILL, TSLA, NVDA, and HYPE.

Some requested symbols intentionally resolve to a different live market title:

  • GLD/USDC -> XAUT/USDC

  • SLV/USDC -> SILVER (xyz)

  • SPY/USDC -> USA500 (cash)

  • QQQ/USDC -> USTECH100 (km)

  • QQQM/USDC -> USTECH100 (km)

  • S&P500/USDC -> S&P500 (xyz)

If you override a preset with --symbol, pass the same --symbol again to npm run capture:docker:latest so the artifact lookup filters the same market. If you need the literal route instead of the alias, prefix the symbol with raw:, for example --symbol raw:GLD/USDC.

For non-trading work, start from one of the generic templates:

npm run collect:snapshot -- \
  --config examples/generic-site-snapshot-config.json \
  --url-includes your-site.example \
  --title-includes "Target Page" \
  --label site-review \
  --signal-context site-review

npm run collect:snapshot -- \
  --config examples/generic-procurement-snapshot-config.json \
  --url-includes procurement.example.gov \
  --title-includes "Tender" \
  --label tender-review \
  --signal-context deadline-check

npm run collect:snapshot -- \
  --config examples/generic-webapp-snapshot-config.json \
  --url-includes app.example.com \
  --title-includes "Dashboard" \
  --label ui-review \
  --signal-context regression-check

npm run collect:snapshot -- \
  --config examples/generic-social-snapshot-config.json \
  --url-includes social.example.com \
  --title-includes "Feed" \
  --label social-review \
  --signal-context content-review

These templates are meant for public procurement portals, internal web apps, and general website review tasks. Replace the target filters and selectors to match the page you care about. The procurement template is now tuned for real tender-review work: it checks buyer/authority, procedure, reference, published/closing/deadline markers, lot/status cues, documents/attachments, clarification or Q&A sections, and generic listing tables so it works better on both notice detail pages and search result pages. It also includes common Japanese markers such as 締切, 発注者, 調達機関, 公告, 資料, 添付, 質問, 質問回答, and 落札. When procurement captures use selectors like downloadLinks, the dataset builder now emits explicit aggregate features such as download_link_count_total and download_link_present_count, which makes attachment-heavy pages easier to analyze downstream. For social-media review work, you can use the generic social template or start directly from examples/social/x-snapshot-config.json, examples/social/instagram-snapshot-config.json, and examples/social/threads-snapshot-config.json for read-only feed/profile/post capture on X, Instagram, and Threads. The social presets now expose explicit postLinks/statusLinks/threadLinks and mediaImages/mediaVideos selectors, and the dataset builder turns those into aggregate features like social_post_link_count_total and social_media_count_total.

You can then build a labeled dataset manifest and train a lightweight local baseline classifier:

npm run build:vision-dataset -- \
  --input-dir artifacts/hyperliquid-snapshots \
  --output-dir artifacts/vision-datasets/hyperliquid-patterns \
  --label-key label

python3 scripts/vision-pattern-classifier.py train \
  --dataset artifacts/vision-datasets/hyperliquid-patterns/train.jsonl \
  --val-dataset artifacts/vision-datasets/hyperliquid-patterns/val.jsonl \
  --model-out artifacts/vision-datasets/hyperliquid-patterns/model.json

python3 scripts/vision-pattern-classifier.py predict \
  --model artifacts/vision-datasets/hyperliquid-patterns/model.json \
  --image artifacts/hyperliquid-snapshots/<session>/<capture>/chart.png

The dataset builder now extracts selector-derived features from each capture's selectors.json, plus context features from metadata.json and runtime-event.json such as notes, signal context, runtime event type, and sidecar metrics. The baseline classifier combines those features with the grayscale image vector. predict will automatically read sibling selectors.json, metadata.json, and runtime-event.json files next to the image when available. The dataset builder also normalizes one-off capture labels into reusable canonical labels such as breakout-long, breakout-candidate, liquidation-cascade, rejection-wick, risk-block, and setup-review, while preserving the original label alongside the canonical one in the JSONL records. Train/validation splits are stratified by canonical label and keep at least one training sample per label when possible. The current classifier is a dependency-free nearest-centroid grayscale-plus-selector baseline. It is intended as a local bootstrap for setup labels such as fake breakout, liquidation cascade, and rejection wick. The current default weights (image=0.5, selector=0.2, context=1.25) are tuned from a small repeated-label sweep on this repo's local dataset, so runtime/context sidecars currently carry more weight than raw pixels. You can later swap it for a stronger local vision stack while keeping the same capture folders and dataset manifest.

For low-level MCP smoke testing, the installed wrapper now responds to resources/list, resources/read, prompts/list, and prompts/get in addition to initialize and tools/*.

browser_screenshot also accepts {"fullPage": true} for full-page PNG capture, {"path": "artifacts/page.png"} to write the PNG directly to disk, and one-shot width / height / deviceScaleFactor overrides for higher-resolution capture. npx real-browser-mcp self-test now verifies:

  • hover, focus, key press, checkbox toggle, dialog handling, and drag/drop

  • structured extraction for links, cards, list_items, detail_fields, and tables

  • deterministic browser_task step execution and resume

  • built-in rpa_run workflows for list/detail/download/extract/save_output

  • cookie round-trip and storage state export/import

  • debugger-backed network capture plus URL blocking and response mocking

  • viewport and color-scheme emulation

  • visible screenshot

  • full-page screenshot

  • direct URL download

  • selector-triggered download

  • slow download with wait=true

  • concurrent download association

Capability Notes

  • The default backend preference is native: Real Browser MCP uses the Chrome extension backend unless you explicitly opt into agent or auto.

  • Use npx real-browser-mcp backend native when you want your existing Chrome profile, signed-in sessions, and real downloads by default.

  • Use npx real-browser-mcp backend agent when you want isolated browser_context_* sessions plus browser_trace_*, browser_har_*, and browser_video_*.

  • Use npx real-browser-mcp backend auto only when you want the legacy agent-first auto-selection behavior.

  • Use --backend native|agent|auto on real-browser-mcp status|tools|tool|mcp when you want a one-off session override without changing the persisted default.

  • browser_extract and browser_task are backend-neutral layers built on top of the existing primitives, so they work with both the extension backend and the agent backend.

  • browser_extract supports text, links, headings, forms, tables, cards, list_items, detail_fields/pairs, and jsonld. When you pass an explicit selector that matches nothing, it now returns an empty structured result with selectorMatched: false instead of silently scraping the whole page.

  • rpa_run is native-first in v1, targets the real Chrome profile, automatically tries to foreground a regular Chrome window before enforcing the strict RPA binding, uses broker-owned tabs for that prep step, rolls back temporary prep tabs/claims when preflight fails, holds a single-profile lock while the run is active or paused, and its saved runs remain inspectable across later MCP sessions.

  • browser_status now exposes nativeReady, rpaExecutionReady, statusSummary, foregroundProfileLabel, and rpaLock so an operator can distinguish general native readiness from stricter RPA readiness. rpaReady remains as a compatibility alias.

  • browser_route now supports action=block, action=mock, and action=clear.

  • REAL_BROWSER_MCP_BACKEND=native|agent|auto still overrides the persisted default for the current process.

Commands

npx real-browser-mcp install
npx real-browser-mcp update
npx real-browser-mcp status
npx real-browser-mcp backend [native|agent|auto]
npx real-browser-mcp uninstall
npx real-browser-mcp mcp
npx real-browser-mcp tools
npx real-browser-mcp tool browser_status
npx real-browser-mcp tool browser_status --json
npx real-browser-mcp self-test

Agent Mode (Opt-In)

The upstream agent-browser backend is still wired through the bundled tool layer, but it is only used when you explicitly select it.

npx real-browser-mcp agent-install
npx real-browser-mcp backend agent

Useful overrides:

  • REAL_BROWSER_MCP_BACKEND=native|agent|auto

  • REAL_BROWSER_MCP_SESSION_ID

  • REAL_BROWSER_MCP_HOST_ID

  • REAL_BROWSER_MCP_AGENT_SESSION

  • REAL_BROWSER_MCP_AGENT_SOCKET

  • REAL_BROWSER_MCP_AGENT_AUTOSTART=0

  • REAL_BROWSER_MCP_AGENT_DAEMON

  • REAL_BROWSER_MCP_AGENT_HOST

  • REAL_BROWSER_MCP_AGENT_PORT

Uninstall

npx real-browser-mcp uninstall
codex mcp remove real-browser-mcp

Then remove the unpacked extension from chrome://extensions.

A
license - permissive license
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ton-to-ton/real-browser-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server