browser-for-ai
Provides CDP-native control of Google Chrome, enabling page navigation, rich interaction (including canvas/WebGL coordinate & touch), full network/console inspection, traffic shaping, session persistence, and reverse-engineering site API flows into runnable code.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@browser-for-aiReverse engineer the login flow on example.com into runnable code"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
browser-for-ai (bfa)
English · ภาษาไทย
A CDP-native MCP server that lets an AI agent (Claude Code and any other MCP client) drive a real Chrome at full depth — reading the network and console the way a human does with DevTools open, operating the page robustly, and reverse-engineering a site's API flow into runnable code.
Why bfa
The things a screenshot-only browser tool can't do:
⭐ Turn a real session into runnable code. Mark a flow, perform it in the browser, and bfa synthesizes replay code (curl / TypeScript / Go / Python) with cross-call dependencies chained automatically — an auth token from one response becomes a variable the next request re-uses, not a baked-in literal.
flow_replaythen runs it for real to prove the reversal reproduces.🔬 See the whole network. Full request/response bodies (text and binary base64), headers, timing, redirect hops, and WebSocket frames — surfaced by the exact question you're asking:
failures,pending(hangs),slow.🎮 Drive anything. Ref / CSS interaction and raw coordinate + touch for
<canvas>/ WebGL surfaces with no DOM. Every action reports the network / console / URL delta it caused.🧪 Shape traffic. Block / mock / modify requests, and throttle to Slow 3G / offline / custom bandwidth with CPU slowdown.
🗂️ Real sessions. Many concurrent sessions, incognito, attach to your logged-in Chrome, save/restore cookies + storage, and complete cache clearing.
How it compares
Capability | bfa | typical browser MCPs |
Reverse a captured flow → runnable code, dependency-chained + replay-verified | ✅ | ✗ (at most Playwright-script codegen from UI actions) |
Full response bodies (text + binary) & WebSocket frames, on by default | ✅ | mostly metadata only |
Secret redaction in the emitted code | ✅ | ✗ |
Coordinate + touch interaction for canvas / WebGL | ✅ | some (vision mode) |
Attach to your logged-in Chrome | ✅ | ✅ (common) |
Network / CPU throttling presets | ✅ | some |
Cloud-scaled browsers · stealth · proxies · CAPTCHA | ✗ (local by design) | some cloud tools |
bfa is a local, developer-facing inspection & reverse-engineering tool, not a cloud scraping farm — that focus is why the first three rows are rare elsewhere.
Related MCP server: Browser-MCP Navigator
Requirements
Node.js ≥ 20
Google Chrome installed (or set
BFA_CHROME_PATHto your Chrome binary)
Install & build
git clone https://github.com/icueth/browser-for-ai.git
cd browser-for-ai
npm install
npm run build # → dist/server.jsRegister with Claude Code
claude mcp add browser-for-ai --scope user -- node /absolute/path/to/browser-for-ai/dist/server.jsIf
nodecomes from a version manager (nvm, asdf, …), pass the absolute path to the node binary — the MCP server is spawned by a non-interactive shell that won't resolve aliases.
Verify with claude mcp get browser-for-ai (should say ✔ Connected). Tools
load into a new session, so start a fresh Claude Code session afterward.
Quick start
browser_launch { "mode": "fresh", "url": "https://example.com" } // real window
page_screenshot
net_list // recent requests
net_failures // anything that errored
net_pending // anything still hanging
page_snapshot // ref-annotated DOM
page_click { "selector": "#login" }
net_get { "url": "/api/login" } // one call in full: headers + bodies
browser_close { "all": true }Sessions
browser_launch { mode, url?, port?, profile?, incognito?, headless?, viewport? }
fresh— launch our own Chrome (headful by default;headless: truefor none).attach— connect to a Chrome started with--remote-debugging-port(onlyportis used; default9222).incognito: true— isolated context, no prior state.Profiles. No
profile→ ephemeral temp profile wiped on close. A named{ "profile": "work" }persists under~/.bfa/profiles/workso logins survive. Two concurrent sessions on the same named profile collide; unnamed ones are always safe.Viewport at launch, or
page_set_viewporton a live session.
Manage with browser_sessions, browser_use { sessionId }, browser_tabs,
browser_close. Most tools accept an optional sessionId; without it they target
the active session.
Tool reference (44)
Sessions & lifecycle
tool | purpose |
| launch fresh / attach a session |
| list open sessions |
| set the default session |
| list a session's tabs/targets |
| close one session, or |
| clear cache + cookies + storage |
| bypass-cache reload |
Navigation, state & read
tool | purpose |
| navigate to a URL |
| url, title, readyState, viewport |
| resize a live session's viewport |
| compact, ref-annotated DOM (source of element refs) |
| delta since last observe — new console/network/URL/DOM |
| PNG of viewport, full page, or one element |
| evaluate JS in the page, return the value |
Interaction
tool | purpose |
| click a ref / selector (reports the delta) |
| type into a field ( |
| fill several fields in one call |
| choose an |
| press a key or combo (e.g. |
| hover an element |
| scroll the window, or an element into view |
| attach file(s) to a file |
| click at raw |
| touch-tap at |
| drag between two points/elements |
Network (deep read)
tool | purpose |
| recent requests (filter by url/method/type/status) |
| one request in full: headers, request & response bodies |
| 4xx/5xx + transport failures with error detail |
| requests still in flight (hang candidates) |
| finished requests slower than a threshold |
| WebSocket connections + recent frames |
| wait until a matching request appears / settles |
Traffic shaping & emulation
tool | purpose |
| block / mock / modify matching requests (CDP Fetch) |
| list active intercept rules |
| remove intercept rules |
| emulate network (offline / 3G / 4G / custom) + CPU slowdown |
Console
tool | purpose |
| console messages (filterable by regex) |
| errors + uncaught exceptions with stacks |
API-flow extraction
tool | purpose |
| mark the start of a flow in the recording |
| export captured calls as JSON summary or HAR |
| generate replay code (curl/ts/go/python) with deps chained |
| execute the reversed flow for real (Node fetch) to verify |
Session persistence
tool | purpose |
| save cookies + local/session storage to |
| re-apply a saved session (origin-scoped) |
Reverse-engineering an API flow → runnable code
The flagship workflow. A page logs in with POST /api/login (returns a token),
then calls GET /api/me with Authorization: Bearer <token>:
browser_launch { "mode": "fresh", "url": "https://app.example.com/login" }
flow_mark { "label": "login flow" }
page_fill { "fields": [
{ "selector": "#user", "value": "alice" },
{ "selector": "#pass", "value": "s3cret" }
]}
page_click { "selector": "#submit" }
flow_synthesize { "target": "curl" }produces:
resp0=$(curl -s -X POST 'https://app.example.com/api/login' \
-H 'content-type: application/json' \
-d '{"user":"alice","pass":"s3cret"}')
token=$(echo "$resp0" | jq -r '.token') # ← lifted from the response
curl -s -X GET 'https://app.example.com/api/me' \
-H "authorization: Bearer $token" # ← re-used, not a literalflow_synthesize also emits TypeScript / Go / Python, flow_replay runs the
sequence for real (deps resolved from each live response) and reports ✓ / ✗
per call, and { "redact": true } swaps secret-bearing header values and
whole-token bodies for env placeholders.
Dependency detection is heuristic (exact / url-encoded / base64 / JWT-claim / substring). Unmatched values stay literal for you to review; always read the generated code before shipping it.
Cookbook
A. Debug a slow or hung page
browser_launch { "mode": "fresh", "url": "https://myapp.com" }
net_pending // the request that never finishes → the hang
net_slow { "thresholdMs": 1000 } // finished-but-slow calls, slowest first
net_failures // 4xx/5xx + transport errors
console_errors // the thrown stack trace
net_get { "url": "/api/user" } // the failing call in fullB. Reverse-engineer an API into runnable code
browser_launch { "mode": "fresh", "url": "https://app.com/login" }
flow_mark { "label": "login+fetch" }
page_fill { "fields": [
{ "selector": "#user", "value": "me" },
{ "selector": "#pass", "value": "pw" }
]}
page_click { "selector": "#submit" }
flow_synthesize { "target": "python" } // code with the token chained in
flow_replay // ✓/✗ per call — verifiedC. Stay logged in across runs
session_save { "name": "myapp" } // first run, after logging in
// later:
browser_launch { "mode": "fresh" }
session_restore { "name": "myapp" } // back in, no re-loginD. Drive a canvas / WebGL app
browser_launch { "mode": "fresh", "incognito": true, "url": "https://game.example",
"viewport": { "width": 390, "height": 844 } } // portrait
page_click_at { "x": 195, "y": 700 } // press a button drawn on the canvas
net_ws // read the app's WebSocket frames
net_pending // catch asset-load hangsE. Test under a bad network / mocked endpoint
net_throttle { "preset": "slow-3g", "cpuRate": 4 } // degrade the connection + CPU
net_intercept_add { "urlIncludes": "/api/config", "action": "mock",
"status": 200, "body": "{\"feature_x\":true}" }
browser_hard_reload
net_slow // see what drags under 3G
net_throttle { "preset": "none" } // reset to full speedF. Upload a file through a form
page_snapshot
page_upload { "selector": "input[type=file]", "files": ["/abs/path/resume.pdf"] }
page_click { "selector": "#submit" }
net_get { "url": "/upload" } // confirm the multipart requestCanvas / WebGL games
Puppeteer defaults to an 800×600 landscape viewport. A portrait game then renders letterboxed, and its full-screen input overlay can swallow coordinate clicks. Launch (or resize) with a portrait viewport so the canvas fills the screen:
browser_launch { "mode": "fresh", "incognito": true, "url": "…",
"viewport": { "width": 390, "height": 844 } }
page_set_viewport { "width": 390, "height": 844 } // on a live sessionKeep hasTouch:false (default) so page_click_at (a real mouse click) drives
games listening for mouse input. For touch-only games, set the viewport
hasTouch:true and use page_tap_at { x, y }.
Attach to a real, logged-in Chrome
./bin/bfa-chrome 9222 # dedicated profile
./bin/bfa-chrome 9222 "$HOME/Library/Application Support/Google/Chrome" # your real profileThen: browser_launch { "mode": "attach", "port": 9222 }.
⚠️ Pointing
bfa-chromeat your real Chrome profile hands the agent every logged-in session on your machine — email, cloud consoles, banking, source control. It can read those pages and act as you. Prefer the dedicated-profile form; use the real profile only when you need an existing login and accept that blast radius.
Roadmap
Gaps we know about, in rough priority order:
iframe-aware refs —
page_snapshot/ interaction currently resolve the top document only; cross-frame ref support is the next correctness item.Device emulation presets — bundle UA + viewport + touch + geolocation + permission grants into one call.
PDF export —
Page.printToPDFfor report/invoice-style pages.Playwright/Puppeteer test emission — a new
flow_synthesizetarget that outputs a runnable test script, not just replay code.Natural-language element targeting — an optional LLM-assisted layer over the existing deterministic ref model.
Performance tracing — a thin
Tracing.start/stopwrapper.
Out of scope by design: cloud-scaled browsers, stealth/anti-bot, and residential proxies — bfa stays a local inspection tool.
Notes & limitations
The agent sees whatever the attached/launched browser sees. Treat an attached real-profile Chrome as full access to your logged-in accounts.
Native dialogs (
alert/confirm/beforeunload) are auto-dismissed so the session never hangs on one.flow_replayonly replayshttp/https, times out per request, is capped overall (60 s / 200 steps), and never touches the live browser session.Dependency detection and secret redaction are best-effort heuristics — review generated code and exported HAR before sharing or running against production.
Development
npm run typecheck
npm test # unit + real-Chrome integration + in-memory MCP e2e
npm run buildLicense
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityBmaintenanceA Chrome DevTools Protocol-based MCP server that enables AI coding assistants to control browsers for JavaScript debugging, reverse engineering, web scraping, and API debugging.9461Apache 2.0
- FlicenseBqualityBmaintenanceUltra-fast browser automation server over Chrome DevTools Protocol (CDP), exposed as MCP, enabling AI agents to control a real Chrome browser with low latency and minimal token usage.21
- Flicense-qualityDmaintenanceMCP server that connects AI agents to browser DevTools via CDP, enabling real-time access to console logs, network requests, and page state.
- AlicenseAqualityAmaintenanceMCP server that lets AI agents drive your real Chromium browser with your existing signed-in sessions, providing visible, local, and inspectable automation for tasks like navigation, clicking, typing, and form filling.251Apache 2.0
Related MCP Connectors
Live browser debugging for AI assistants — DOM, console, network via MCP.
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
A paid remote MCP for AI agent browser DevTools MCP, built to return verdicts, receipts, usage logs,
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/icueth/browser-for-ai'
If you have feedback or need assistance with the MCP directory API, please join our Discord server