Browser Controller MCP sunucusu
Commit 14 Kas 2026Bir MCP server ve eklenti aracılığıyla AI agent'ların, giriş bilgileriniz ve çerezleriniz dahil olmak üzere mevcut Chrome tarayıcı oturumlarınızı kontrol etmesine olanak tanır.
Ayrıca bilinen adı compnew2006/browser-controller
- Yıldızlar
- 9
- Araçlar
- 25
- İndirmeler, 30 gün
- —
- En son sürüm
- —
- Son commit
- 14 Kas 2026
- Lisans
- MIT
Browser Controller MCP nedir?
Browser Controller bir MCP sunucusudur. Bir MCP server ve eklenti aracılığıyla AI agent'ların, giriş bilgileriniz ve çerezleriniz dahil olmak üzere mevcut Chrome tarayıcı oturumlarınızı kontrol etmesine olanak tanır. 25 araç sunar; örneğin url, tabId, snapshot.
Özet, projenin README dosyasından oluşturuldu
Browser Controller MCP sunucusu hakkında
Browser Controller, AI agent'ların aktif Chrome, Edge veya Brave tarayıcı oturumlarınızla etkileşime girmesini sağlar. Headless otomasyonun aksine bu araç, mevcut profillerinizi kullanır; yani agent'lar yeniden kimlik doğrulaması gerektirmeden gerçek giriş bilgilerinize, çerezlerinize ve kimliği doğrulanmış oturumlarınıza erişebilir. Yerel bir daemon ve bir Chrome eklentisi aracılığıyla çalışarak, tüm verilerin bulut telemetrisi olmadan localhost üzerinden makinenizde kalmasını sağlar.
Geliştiriciler bunu Cursor, Claude Desktop veya Windsurf gibi MCP uyumlu istemcilerle kullanabilirler. Sistem, belirli sekme ID'lerini kullanarak birden fazla agent'ı eş zamanlı olarak destekler; bu sayede siz başka bir sekmede gezinmeye devam ederken bir agent bir sekme üzerinde çalışabilir. Chrome DevTools Protocol aracılığıyla yüksek sadakatli etkileşim sunarak tıklama ve yazma işlemlerinin güvenilir kullanıcı etkinlikleri olarak algılanmasını sağlar. Sunucu; navigasyon, element etkileşimi ve JavaScript değerlendirmesi için 19 araçla birlikte konsol günlüklerini ve ağ isteklerini izleme yeteneklerini de içerir.
Neler yapabilirsiniz
- 1Otomatik yazılım doğrulamaBir AI agent, yerel uygulamanıza gidip kullanıcı arayüzü ile etkileşime girerek bir kod düzeltmesini doğrulayabilir.
- 2Çoklu agent paralel iş akışlarıFarklı AI agent'ları, birbirlerine müdahale etmeden aynı anda ayrı tarayıcı sekmelerinde çalıştırın.
- 3Hata ayıklama ve ağ incelemesiWeb uygulamalarını sorun gidermek için agent'tan konsol hatalarını analiz etmesini veya ağ trafiğini durdurup incelemesini isteyin.
Projenin README dosyasından alınmıştır. Her kullanım durumu, oradaki bir alıntı ile kontrol edilir.
Browser Controller MCP araçları 25
README dosyasından algılandıurltabIdsnapshotactionbrowserisolationaccesstrustedreadtargetquerymaxChars
| url | — | |
| tabId | — | |
| snapshot | — | |
| action | — | |
| browser | — | |
| isolation | — | |
| access | — | |
| trusted | — | |
| read | — | |
| target | — | |
| query | — | |
| maxChars | — |
25 aracın tümünü gösterDaha az araç göster
propertiesruleslistenersenableddefaultActionsiteRulesbuttonexpectobservehoverselectuntilactions
| properties | — | |
| rules | — | |
| listeners | — | |
| enabled | — | |
| defaultAction | — | |
| siteRules | — | |
| button | — | |
| expect | — | |
| observe | — | |
| hover | — | |
| select | — | |
| until | — | |
| actions | — |
Yapılandırma
WS_PORT
| Ad | Açıklama | Sunucu |
|---|---|---|
| WS_PORT | — |
Otomatik kontroller
Çalıştırıldı 14 Kas 2026Tam rapor →Henüz doğrulanmadı. Bir sunucunun 80 puana, ciddi bir bulgu olmamasına ve kontrol edebilmemiz için yeterli veriye ihtiyacı vardır. Kontroller nasıl çalışır · Daha fazla puan için nelerin düzeltileceği
- Kaynak deposu bağlantılı ve erişilebilircompnew2006/browser-controller is public and reachablegithub.com/compnew2006/browser-controller ↗Geçti
- Paket, bu depoyu kaynağı olarak gösteriyorKontrol edilmedi
- Derleme kökeni (Sigstore onayı)Kontrol edilmedi
- Açık kaynak lisansı (OSI)MITspdx.org/licenses/MIT.html ↗Geçti
- Son bir yıl içinde commit veya sürüm mevcutLast commit or release 2026-11-09github.com/compnew2006/browser-controller ↗Geçti
- OpenSSF ScorecardOpenSSF Scorecard 6.9 / 10; weakest: Code-Review 0, Token-Permissions 0, CII-Best-Practices 0scorecard.dev/viewer/?uri=github.com/compnew2006/browser-con ↗Kısmi 10/15
- Paket adı popüler bir pakete yakın değilKontrol edilmedi
- Pakette veya bağımlılıklarında kritik uyarı yokKontrol edilmedi
- Modele yönelik gizli talimat yok25 tool descriptions and the README read; no override phrases, credential paths or hidden charactersGeçti
- Yıkıcı araçlar etiketlenmişNo tool named like delete, drop or execGeçti
- Uzak uç nokta MCP el sıkışmasına yanıt veriyorKontrol edilmedi
What this project solves
You ship a fix. Your agent says "done, please verify." You alt-tab to Chrome, navigate to the page, log in, click around, find the bug.
Your agent just wrote the code. It could also verify it. It already has your browser open right there. It just can't see it.
Now it can. Browser Controller gives any MCP-compatible AI agent (Cursor, Claude Desktop, Windsurf, …) direct control of the browser you already have open — your real sessions, your logins, your cookies. No headless browser, no fresh profile, no re-authentication.
Version 3.0 is a breaking release: 19 tools, one target locator, and text results with structured receipts for actions. See Migrating from 2.x.
Key capabilities
- Multiple agents at once. Cursor can drive tab 10 while Claude drives tab 11 — both through one shared daemon, neither blocking the other.
- Tab targeting, not "the active tab." Every page action names a
tabId. Move your mouse, switch tabs, watch YouTube — the agent keeps working on the tab you told it to. It never hijacks the page you're reading. - Tab ownership without lock calls. A tab that
browser_navigateopens for a session belongs to that session until it closes. Another session's call on that tab fails at once withTAB_LOCKED. - Per-tab isolation. Element refs are per page, and logs and network buffers are per tab. A ref from tab 10 can never click something in tab 20.
- Per-tab concurrency. Two actions on the same tab serialize (no races); actions on different tabs run in parallel.
- Agent-control shield. While a tool runs on a tab, you see a translucent blue inner frame and your input on that tab is blocked (mouse, keyboard, wheel). It disappears when the action finishes.
- Visible agent cursor (optional). Switch on Show agent cursor in the popup's Settings and agent mouse actions draw a pointer that glides to its target first. Off by default.
- Real, trusted input. Clicks, typing, keys, wheel and drags go through the Chrome DevTools Protocol, so the page sees
isTrustedevents and focus, Tab, Enter and autocomplete behave as they do for a person. There is no synthetic-event fallback: if the debugger cannot attach, input fails withDEBUGGER_UNAVAILABLE. The yellow "being debugged" banner shows while the debugger is attached. - One locator.
targettakes a ref (e12),text=Sign in, viewport coordinates (x,y), a CSS selector, or an accessible{ role, name, nth? }object. Shadow roots and same-origin iframes are searched; cross-origin iframes are listed as not readable. - Honest results. A success is compact text. A failure is an
isErrorresult whose text isCODE: message, so the agent acts on the code instead of guessing. - Batches.
browser_batchruns up to 50 tool calls in one round trip and stops at the first failing step (onError:"continue"runs the rest and names every failure). - The page is read after it settled. An action waits for the page to stop changing before the call returns, and a navigation waits for the page it loaded to draw, so the read that follows sees what the action produced, not the page before it.
browser_wait {until:"stable"}waits for the same thing on demand. - A session can be fenced in.
browser_tabs {action:"session"}opens the session for reading only (every call that changes something is refused), or isolates it (the agent touches the tabs it opened, and only those). - Console-style JavaScript.
browser_evaluateaccepts code as you'd type it in DevTools: top-levelawait, several statements withreturn, DOM nodes come back as readable descriptions. Over CDP, page CSP does not block it. - Console, network and mocks on demand.
browser_logsreads a tab's console (uncaught errors with stacks) and its network requests, with response bodies on request.browser_mockanswers or blocks one tab's requests, so the page really receives the fake response. - Frozen tabs don't freeze the agent.
browser_navigatereplaces a tab that stopped answering, and its result says so with anote:line naming the newtabId. - Several browsers. Every connected Chrome profile is its own connection.
browser_tabs { action: "profiles" }lists stable IDs, local labels, the default, and whether each profile has open tabs without switching the session. Use the ID to select a profile;automeans the earliest-connected default. Set a recognizable local label in the extension's Settings. - Authenticated local connection. Token + enrollment secret, so no other local process can silently drive your browser — and after a one-time
npm run setup:pairingthe extension pairs itself. Everything stays on localhost — no cloud, no telemetry. - Versioned compatibility handshake. The daemon and extension advertise a protocol version and capabilities before tool traffic is accepted. A peer from before 3.0 is refused with an actionable error instead of producing unexplained timeouts.
- Consoles and appliances. A hypervisor web client is an ordinary page to the agent, and the guest behind it is reachable through the same tools — the guest is a canvas, so it needs its own rules for reading, clicking and typing. The field guide is
docs/esxi-vm-console-automation.md.
How it works
Three pieces, all on your machine. Nothing leaves localhost. The daemon control plane is hard-bound to 127.0.0.1; there is no supported remote/n8n listener.
flowchart LR
subgraph Client["MCP client (Cursor / Claude / Windsurf)"]
A["agent"]
end
subgraph Thin["thin MCP client — mcp-server/dist/index.js"]
B["DaemonClient<br/>speaks MCP over stdio<br/>spawns daemon if not running<br/>gets its own sessionId"]
end
subgraph Daemon["daemon — single long-running process, owns port 7225"]
C["daemon.ts<br/>multiplexes N clients → 1 extension<br/>sessions · rate limit · heartbeats"]
D["bridge.ts (ExtensionBridge)<br/>HTTP /pair /status /kill<br/>WebSocket for the extension"]
end
subgraph Ext["Chrome extension (Manifest V3 service worker)"]
E["connection.js<br/>pairing · reconnect backoff"]
F["router.js<br/>tool dispatch"]
G["tab-concurrency.js<br/>per-tab mutex · ownership · shield"]
H["handlers/*<br/>interaction · inspection · evaluate · navigation · tabs<br/>logs · mock · emulate · cdp"]
I["page-exec.js safeExec<br/>chrome.scripting func: — CSP-safe"]
E --> F --> G --> H --> I
end
P["Page — your real sessions"]
A -->|stdio MCP| B
B -->|IPC socket + token| C
C --> D
D <-->|Authenticated WebSocket<br/>protocol version + capabilities| E
I --> P
Key idea: the first time any agent runs, the thin client spawns a background daemon that owns port 7225 and the extension connection. Every subsequent agent (even from a different MCP client) connects to that same daemon over a local IPC socket and gets its own sessionId. The extension sees one stable connection and routes each call to the exact tab the caller specified.
Quick Start
The project is not on the Chrome Web Store or npm — you install it from this repository. Two parts: the MCP server (runs on your machine, talks to your AI agent) and the Chrome extension (sits in your browser, executes commands).
Prerequisites: Node.js 22.18+ within the 22.x line, 24.11+ within the 24.x line, or 26+; and Chrome/Chromium/Edge. CI tests the minimum and latest releases of the 22, 24, and 26 lines. Later Node.js major versions are allowed by engines but are not covered by the current CI matrix.
1. Clone & build
git clone https://github.com/compnew2006/browser-controller.git
cd browser-controller
npm install
npm run build # compiles TypeScript → mcp-server/dist/
2. Load the Chrome extension
- Open
chrome://extensionsand enable Developer mode (toggle in the top right) - Click Load unpacked and select the
extension/folder from the cloned repo - Pin the Browser Controller icon to your toolbar
Gray dot = waiting for the daemon. Green = connected.
3. Add the MCP server to your client
Cursor: Settings → MCP → "Add new MCP server". Claude Desktop: edit claude_desktop_config.json. Windsurf: Settings → MCP. Any MCP-compatible client works.
Replace /path/to/browser-controller with the absolute path of your clone (Windows: use C:\\path\\to\\browser-controller\\mcp-server\\dist\\index.js):
{
"mcpServers": {
"browser-controller": {
"command": "node",
"args": ["/path/to/browser-controller/mcp-server/dist/index.js"]
}
}
}
By default the daemon names each connection after its parent IDE ("Cursor", "Claude", …). To override — e.g. when several agents share one IDE, or to label them by project — pass --agent <name> in the args. It takes priority over every auto-detection:
{
"mcpServers": {
"browser-controller": {
"command": "node",
"args": [
"/path/to/browser-controller/mcp-server/dist/index.js",
"--agent",
"My Project Agent"
]
}
}
}
The name appears in the popup's Connected Agents list. (You can also set the MCP_AGENT_NAME env var — equivalent.) Reconnecting with the same name replaces the old entry, so IDE restarts don't pile up duplicates.
4. Pair the extension with the daemon
Run this once from the repo root:
npm run setup:pairing
Then click Reload on Browser Controller in chrome://extensions. The extension pairs itself — nothing to copy or paste. Green dot = you're connected. Your agent can now see your browser.
What the command sets up:
- A small local helper (a Chrome native messaging host,
mcp-server/dist/native-host.js), registered with every Chromium browser it finds: Chrome (stable, Beta, Canary), Chromium, Edge and Brave. It is a per-user install (on Windows, underHKCU\Software\…\NativeMessagingHosts) and needs no admin rights. - Chrome lets only this extension's ID start the helper. An unpacked extension's ID comes from its folder path; the command prints the ID it computed, and it must match the one shown in
chrome://extensions. If you loaded the extension from another folder, pass its ID:npm run setup:pairing -- --extension-id <id>. - A launcher in
.native-host/that pins the currentnode, because a browser started from the Dock or Start menu does not see your shell'sPATH.
The extension asks the helper only when the daemon refuses its secret — the first time, and after you rotate the secrets — so a rotation needs no action either. Check the setup with npm run pairing:status (it never prints the secret) and remove it with npm run pairing:uninstall. Run npm run setup:pairing again after moving the repository or switching Node installations, since the launcher pins both paths. When pairing cannot happen, the popup's activity log says why and what to run.
Only the enrollment secret is needed — the extension fetches the auth token from the daemon by itself.
- Start the daemon once by asking your agent to "list my browser tabs". It creates the secrets in
~/.browser-controller/(Windows:%USERPROFILE%\.browser-controller\), and the MCP client prints the enrollment secret to its log on first run. - Copy the
secretvalue:cat ~/.browser-controller/enrollment.json - Click the extension icon → Settings tab → paste it into Enrollment Secret (leave the port at
7225unless you changedWS_PORT).
These secrets protect the local control channel. To rotate them without deleting vault and memory data, use
npm run pairing:rotateand then restart the daemon as described in SECURITY.md. Processes running as the same OS user can read the secrets; pairing is not a same-user sandbox.
Runtime lifecycle (authoritative daemon)
The daemon is the only process that owns the extension-facing runtime. MCP
clients are thin stdio adapters and may start it automatically, but deployment
scripts should use the lifecycle commands below so there is one restart owner.
Do not run a second daemon.js or install a launch supervisor that competes for
port 7225.
npm run build
npm run daemon:start # start, or report the already-running PID
npm run daemon:status # JSON health/runtime information
npm run daemon:health # authenticated daemon + extension check; exit 1 if unhealthy
npm run daemon:stop # graceful SIGTERM; removes runtime metadata
npm run daemon:restart # stop, then start; preserves token/enrollment
The daemon survives browser/Chrome restarts: token, enrollment secret, and
pairing remain in ~/.browser-controller/ (override with BC_STATE_DIR), and
the extension reconnects to the same endpoint. The lifecycle wrapper reads the
daemon.json PID and is safe to run repeatedly; a stale lock is removed only
when its recorded PID is not alive.
For service monitoring, backup boundaries and recovery drills, see the operations and recovery runbook.
MCP clients reconnect after every drop of their daemon connection (a restart,
a crash). Each try connects to the daemon that answers, or waits for one that
is starting (its daemon.lock names a live PID), or, when none is alive,
starts one (never with BROWSER_CONTROLLER_DAEMON_MODE=connect). Tries back
off from 0.25 s to 5 s; after 8 failed tries the client waits for its next tool
call to try again. A tool call made while the client reconnects waits up to
10 s for it. A call that was running when the connection dropped fails
NOT_CONNECTED: daemon connection closed and is not repeated: it may have run.
A client starts a daemon at most 3 times a minute, so a daemon that cannot stay
up is not restarted in a loop; calls then fail NOT_CONNECTED: Not connected to daemon: … with the reason and the path of daemon.log.
When several clients start a daemon at the same moment, the first one takes
daemon.lock. Each other one writes one line, … lock is held by live process <pid>; this daemon exits and clients use that one, and exits with code 0; its
client connects to the first. A daemon.log larger than 5 MB is moved to
daemon.log.1 before the next daemon starts (one old copy is kept).
Expected endpoints
- MCP endpoint: stdio, launched as
node mcp-server/dist/index.js(the standardmcpServerscommand/args form is shown above). - Extension runtime:
ws://127.0.0.1:7225by default, with HTTP/pair,/status, and/kill?sessionId=...on the same port. These are daemon/popup endpoints, not an MCP HTTP transport. - MCP client IPC:
~/.browser-controller/daemon.sockon Unix or\\.\pipe\browser-controlleron Windows. It is internal and token-authenticated. - State:
~/.browser-controller/{daemon.json,daemon.lock,token.json, enrollment.json,daemon.log}.WS_PORT,WS_HOST, andBC_STATE_DIRare the supported configuration overrides.
This preserves the real Chrome session workflow: no Playwright/headless browser is launched, and the existing Chrome profile, cookies, logins, and tabs remain the browser being controlled.
Permission and trust boundary
The unpacked extension deliberately requests Chrome's powerful debugger, scripting, webRequest, and <all_urls> permissions, plus nativeMessaging, which it uses only to ask the local pairing helper for the enrollment secret, and webNavigation, which it uses only to know which tab opened a new one. Together they let a connected MCP agent read network metadata, run functions in the pages you select, drive trusted input and evaluate JavaScript through the debugger, and answer requests in a tab with mock responses. A connected MCP agent can therefore read and change sensitive pages in your signed-in browser. Install the extension only from source you trust, pair it only with a trusted local daemon, and do not expose the daemon port beyond localhost. Chrome-protected pages such as chrome://, the Web Store, and DevTools remain inaccessible.
Using it
The model is tab-first: the agent always says which tab to act on. It never assumes "the active tab."
Basic workflow
- List tabs to get a
tabId:browser_tabs { action: "list" } → 123 [user, focused] "Inbox" mail.example.com/inbox 456 [own] "Sign in" login.example.com - Snapshot that tab to see its structure and get element refs. Use
queryon large pages:browser_snapshot { tabId: 456, query: "Sign in" } → textbox "Email" [e5] button "Sign in" [e3] - Act with the same
tabIdand atarget:browser_type { tabId: 456, target: "e5", text: "hello@example.com" } browser_type { tabId: 456, key: "Tab" } browser_click { tabId: 456, target: "text=Sign in" } - Wait for what you expect, then verify:
browser_wait { tabId: 456, target: "text=Welcome" } browser_text { tabId: 456 }
A ref (e5) is valid for the tab and page that produced it. If its element was re-rendered, the call finds the element again by its snapshot description and adds a note: e5 was re-found after the page changed line. The note appears in the results of click (also hover and drag), type with a target, fill, snapshot, text, scroll and wait with a target, and inspect_element. Screenshot finds the element again without the note. A ref from an earlier page of the tab (after a navigation or reload) fails REF_GONE ("from an earlier page"). A ref that was never issued in the tab fails at once with REF_NOT_FOUND. If the element cannot be found again, the call fails REF_GONE: take a new browser_snapshot.
Browser Controller MCP soruları
Browser Controller MCP hangi araçları sunar?
25 araç sunar; bunlar arasında url, tabId, snapshot, action, browser yer alır.
Headless bir tarayıcı mı kullanıyor?
Hayır, agent'lara halihazırda açık olan tarayıcınız üzerinde, gerçek oturumlarınızı, giriş bilgilerinizi ve çerezlerinizi kullanarak doğrudan kontrol imkanı sağlar.
Birden fazla AI agent tarayıcıyı aynı anda kullanabilir mi?
Evet, birden fazla agent, birbirlerini engellemeden tek bir paylaşımlı daemon üzerinden farklı sekmeleri eş zamanlı olarak yönetebilir.
Verilerim buluta gönderiliyor mu?
Hayır, her şey yerel makinenizde kalır ve localhost üzerinden iletişim kurar.