Skip to main content
Glama
compnew2006

Browser Controller

by compnew2006

Was dieses Projekt löst

Sie liefern einen Fix aus. Ihr Agent sagt „fertig, bitte verifizieren." Sie wechseln per Alt-Tab zu Chrome, navigieren zur Seite, loggen sich ein, klicken herum, finden den Bug.

Ihr Agent hat den Code gerade geschrieben. Er könnte ihn auch verifizieren. Er hat Ihren Browser bereits offen. Er kann ihn nur nicht sehen.

Jetzt kann er es. Browser Controller gibt jedem MCP-kompatiblen KI-Agenten (Cursor, Claude Desktop, Windsurf, …) direkte Kontrolle über den Browser, den Sie bereits geöffnet haben — Ihre echten Sitzungen, Ihre Logins, Ihre Cookies. Kein Headless-Browser, kein frisches Profil, keine erneute Authentifizierung.

Related MCP server: Tabryn

Kernfunktionen

  • Mehrere Agenten gleichzeitig. Cursor kann Tab 10 steuern, während Claude Tab 11 steuert — beide über einen gemeinsamen Daemon, ohne sich gegenseitig zu blockieren.

  • Tab-Zielsteuerung, nicht „der aktive Tab". Jede Aktion benennt eine tabId. Bewegen Sie Ihre Maus, wechseln Sie Tabs, schauen Sie YouTube — der Agent arbeitet weiter auf dem Tab, den Sie ihm zugewiesen haben. Er kapert nie die Seite, die Sie gerade lesen.

  • Isolation pro Tab. Element-Referenzen, Konsolen-Logs und Netzwerk-Puffer sind pro Tab abgegrenzt. Eine Referenz aus Tab 10 kann nie etwas in Tab 20 anklicken.

  • Nebenläufigkeit pro Tab. Zwei Aktionen auf dem selben Tab werden serialisiert (keine Race Conditions); Aktionen auf verschiedenen Tabs laufen parallel.

  • Tab-Sperre. Ein Agent kann einen Tab für sich beanspruchen, sodass andere dahinter in die Warteschlange gehen, statt zu konkurrieren (browser_tabs { action: "lock" }). Sperren überleben das Recycling des Chrome-Service-Workers (chrome.storage.session).

  • Agenten-Steuerungsschild. Während ein Agent an einem Tab arbeitet, sehen Sie einen durchscheinenden blauen Innenrahmen, und Ihre Eingaben auf diesem Tab sind blockiert (Maus, Tastatur, Mausrad) — das Badge zeigt agent <name> controlling the tab und verschwindet, wenn die Aktion endet. Das Sperren eines Tabs hält einen schlichten Rahmen für die Dauer der Sperre.

  • Same-Origin-Iframe-Durchdringung. Legacy-/Enterprise-Oberflächen, die in Iframes leben (z. B. eine ONT-Konsole in iframe#mainFrame), sind erreichbar: Alle Locator-Tools durchsuchen Iframe-Dokumente, und find/click_text durchlaufen jeden Frame.

  • Rettung bei offenen Dialogen. Ein natives alert/confirm/prompt friert den JS-Thread der Seite ein — browser_handle_dialog verwirft ihn out-of-band über CDP, ohne dass Seiten-JS nötig ist, was auch jedes andere Tool auf diesem Tab wieder entsperrt. browser_tabs close/focus funktioniert immer, sogar auf einem eingefrorenen Tab.

  • Authentifizierte lokale Verbindung. Token + einmaliges Enrollment-Secret, sodass kein anderer lokaler Prozess stillschweigend Ihren Browser steuern kann. Alles bleibt auf localhost — keine Cloud, keine Telemetrie.

  • Kein Debugger-Banner. browser_evaluate läuft in der MAIN-World der Seite über chrome.scripting — kein gelbes Banner „dieser Tab wird debuggt", und echte Werte kommen über die MV3-World-Grenze zurück.

  • Ehrliche Fehler. Jeder Tool-Fehler erreicht Ihren Agenten als echtes isError-Ergebnis mit der vollständigen Payload — keine „Erfolg"-Antworten, die Fehler mitten im Workflow verbergen.


So funktioniert es

Drei Komponenten, alle auf Ihrem Rechner. Nichts verlässt localhost.

  Agent (Cursor / Claude / Windsurf)        ── other agents connect too ──┐
                  │ stdio (MCP protocol)                                   │
                  ▼                                                        ▼
  ┌─────────────────────────────┐   ┌─────────────────────────────────────────┐
  │  thin MCP client            │   │  thin MCP client                        │
  │  (node mcp-server/dist/     │   │  (node mcp-server/dist/                 │
  │   index.js)                 │   │   index.js)                             │
  │  - speaks MCP over stdio    │   │  - spawns daemon if not running         │
  │  - forwards calls to daemon │   │  - gets its own sessionId               │
  └──────────────┬──────────────┘   └────────────────────┬───────────────────┘
                 │ local IPC socket (AF_UNIX / named pipe, token-auth)     │
                 ▼                                                          ▼
  ┌──────────────────────────────────────────────────────────────────────────┐
  │  DAEMON (single long-running process, owns port 7225)                     │
  │  - multiplexes N clients → 1 extension                                    │
  │  - tags every call with the client's sessionId                            │
  │  - heartbeat eviction, per-session rate limiting                          │
  └──────────────────────────────┬───────────────────────────────────────────┘
                                 │ WebSocket ws://127.0.0.1:7225 (token-auth)
                                 ▼
  ┌──────────────────────────────────────────────────────────────────────────┐
  │  Chrome Extension (Manifest V3 service worker)                            │
  │  - resolves the target tabId (never "the active tab" implicitly)          │
  │  - serializes same-tab actions, parallelizes cross-tab actions            │
  │  - executes click/type/snapshot/evaluate against the named tab            │
  └──────────────────────────────────────────────────────────────────────────┘

Kernidee: Beim ersten Lauf eines Agenten startet der schlanke Client einen Hintergrund-Daemon, der Port 7225 und die Extension-Verbindung besitzt. Jeder weitere Agent (auch von einem anderen MCP-Client) verbindet sich über einen lokalen IPC-Socket mit demselben Daemon und erhält seine eigene sessionId. Die Extension sieht eine stabile Verbindung und leitet jeden Aufruf an genau den Tab weiter, den der Aufrufer angegeben hat.


Schnellstart

Das Projekt ist nicht im Chrome Web Store oder auf npm — Sie installieren es aus diesem Repository. Zwei Teile: der MCP-Server (läuft auf Ihrem Rechner, spricht mit Ihrem KI-Agenten) und die Chrome-Extension (sitzt in Ihrem Browser und führt Befehle aus).

Voraussetzungen: Node.js ≥ 20 und Chrome/Chromium/Edge.

1. Klonen & bauen

git clone https://github.com/compnew2006/browser-controller.git
cd browser-controller
npm install
npm run build        # compiles TypeScript → mcp-server/dist/

2. Chrome-Extension laden

  1. Öffnen Sie chrome://extensions und aktivieren Sie den Entwicklermodus (Schalter oben rechts)

  2. Klicken Sie auf Entpackte Erweiterung laden und wählen Sie den Ordner extension/ aus dem geklonten Repository

  3. Heften Sie das Browser-Controller-Symbol an Ihre Symbolleiste

Grauer Punkt = wartet auf den Daemon. Grün = verbunden.

3. MCP-Server zu Ihrem Client hinzufügen

Cursor: Einstellungen → MCP → „Neuen MCP-Server hinzufügen". Claude Desktop: claude_desktop_config.json bearbeiten. Windsurf: Einstellungen → MCP. Jeder MCP-kompatible Client funktioniert.

Ersetzen Sie /path/to/browser-controller durch den absoluten Pfad Ihres Klons (Windows: C:\\path\\to\\browser-controller\\mcp-server\\dist\\index.js verwenden):

{
  "mcpServers": {
    "browser-controller": {
      "command": "node",
      "args": ["/path/to/browser-controller/mcp-server/dist/index.js"]
    }
  }
}

Standardmäßig benennt der Daemon jede Verbindung nach ihrer übergeordneten IDE („Cursor", „Claude", …). Zum Überschreiben — z. B. wenn mehrere Agenten eine IDE teilen oder um sie nach Projekt zu kennzeichnen — übergeben Sie --agent <name> in den Argumenten. Es hat Vorrang vor jeder automatischen Erkennung:

{
  "mcpServers": {
    "browser-controller": {
      "command": "node",
      "args": ["/path/to/browser-controller/mcp-server/dist/index.js", "--agent", "My Project Agent"]
    }
  }
}

Der Name erscheint in der Liste Connected Agents des Popups. (Sie können auch die Umgebungsvariable MCP_AGENT_NAME setzen — gleichwertig.) Das erneute Verbinden mit demselben Namen ersetzt den alten Eintrag, sodass IDE-Neustarts keine Duplikate anhäufen.

4. Extension mit dem Daemon koppeln

Der Daemon verwendet zwei Geheimnisse, die beide beim ersten Lauf in ~/.browser-controller/ erzeugt werden (Windows: %USERPROFILE%\.browser-controller\). Starten Sie ihn einmal, indem Sie Ihren Agenten bitten, „meine Browser-Tabs aufzulisten", dann:

  1. Geheimnisse lesen:

    cat ~/.browser-controller/enrollment.json   # one-time pairing secret
    cat ~/.browser-controller/token.json        # WebSocket auth token

    (Das Enrollment-Secret wird beim ersten Lauf auch im Log des MCP-Clients ausgegeben.)

  2. Klicken Sie auf das Extension-Symbol → Tab Einstellungen → fügen Sie das Enrollment-Secret und das Auth-Token ein (lassen Sie den Port bei 7225, sofern Sie WS_PORT nicht geändert haben).

Grüner Punkt = Sie sind verbunden. Ihr Agent kann jetzt Ihren Browser sehen.

Diese Geheimnisse verhindern, dass ein anderer lokaler Prozess einen WebSocket öffnet und Ihre authentifizierten Browser-Sitzungen steuert. Zum Rotieren: Stoppen Sie Ihre MCP-Clients, löschen Sie den Ordner, und der nächste Lauf erzeugt beide Geheimnisse neu. Das vollständige Bedrohungsmodell finden Sie in SECURITY.md.


Verwendung

Das Modell ist tab-first: Der Agent sagt immer, auf welchem Tab er handeln will. Er nimmt nie „den aktiven Tab" an.

Grundlegender Workflow

  1. Tabs auflisten, um eine tabId zu erhalten:

    browser_tabs { action: "list" }
    → [{ id: 15, url: "...", title: "...", active: true, lockedBy: null }, ...]
  2. Snapshot dieses Tabs, um seine Struktur zu sehen und Element-Referenzen zu erhalten:

    browser_snapshot { tabId: 15 }
    → { tree: [ { ref: "e3", role: "button", name: "Sign in" }, ... ] }

    Referenzen gelten nur für diese tabId. Wenn Sie navigieren oder sich das DOM ändert, erstellen Sie einen neuen Snapshot. Neue Elemente seit dem letzten Snapshot sind mit isNew: true markiert — nachdem eine Aktion ein Overlay/Dropdown geöffnet hat, kann sich der Agent auf genau diese konzentrieren, statt den ganzen Baum neu zu lesen.

  3. Interagieren mit der Referenz und derselben tabId:

    browser_click { tabId: 15, ref: "e3" }
    browser_type  { tabId: 15, ref: "e5", text: "hello@example.com" }
    browser_press_key { tabId: 15, key: "Enter" }

    Wenn eine Referenz veraltet ist, das Element aber noch existiert, wird es automatisch über einen robusten Selektor + Text-/Rollen-Scan gefunden (die Antwort trägt via: "fallback"). Wenn das Element vollständig herausgescrollt wurde (virtualisierte Feeds), trägt die Antwort freshRefs: [...] mit einem frischen Snapshot inline — wiederholen Sie den Schritt mit einer dieser neuen Referenzen, ohne separaten Snapshot.

  4. Verifizieren — nach der Aktion erneut einen Snapshot erstellen oder Text lesen.

Multi-Agenten-Koordination (zwei Agenten, zwei Tabs)

  1. Agent A listet Tabs auf, wählt Tab 10, sperrt ihn optional: browser_tabs { action: "lock", tabId: 10 }

  2. Agent B listet Tabs auf, wählt Tab 11, sperrt ihn: browser_tabs { action: "lock", tabId: 11 }

  3. Beide arbeiten parallel. Die Aufrufe jedes Agenten werden gegen seinen eigenen Tab serialisiert; die beiden Tabs stören sich nie.

  4. Wenn fertig: browser_tabs { action: "unlock", tabId: 10 }.

Das Popup ist Ihre Kommandozentrale

Eine Tab-Shell mit fester Höhe (der Body scrollt nie, nur die Listen):

  • Tabs — jeder offene Tab mit seinem Sperr-Besitzer, plus Alle entsperren in der Symbolleiste für die Ein-Klick-Freigabe, falls ein Agent mitten in einer Sperre abgestürzt ist.

  • Agents — jeder verbundene Agent mit Name, Sitzungs-ID, Laufzeit und einem ✕ zum sofortigen Trennen (räumt einen Zombie auf, den der Heartbeat noch nicht abgeräumt hat).

  • Einstellungen — WebSocket-Port, Auth-Token, Enrollment-Secret.

  • Aktivitätsleiste — ein einklappbarer Streifen unten, der die neueste Tool-Aktivität zeigt; aufklappen für das fortlaufende Log.

Wissenswertes

  • tabId vergessen? Sie erhalten eine klare Fehlermeldung: tabId is required. Call browser_tabs list first.

  • Geschützte Seiten (chrome://, der Web Store, DevTools) können nicht skriptgesteuert werden — Sie erhalten Cannot access protected page (chrome://...) statt eines stillen Hängens.

  • browser_navigate ist das einzige Tool, bei dem tabId optional ist (Standard: aktiver Tab) — aber für die Multi-Agenten-Sicherheit übergeben Sie es explizit. Nur-Hash-Änderungen (z. B. /page/page#section) werden aufgelöst, sobald die URL gesetzt ist, ohne auf ein complete-Ereignis zu warten (SPAs laden bei Hash-Änderung nicht neu, daher feuert dieses Ereignis nie).

  • browser_evaluate läuft in der MAIN-World der Seite (kein Debugger-Banner, CSP-sicher) und gibt echte Werte zurück (JSON-serialisiert über die World-Grenze). Es ist mächtig, aber nicht idempotent — es wird bei Timeout nicht automatisch wiederholt.

  • Scrollen in virtualisierten Feeds (Facebook/Instagram/Twitter): browser_scroll gibt refsMayBeStale: true zurück, weil diese Seiten DOM-Knoten recyceln. Erstellen Sie vor Ihrer nächsten Interaktion einen neuen Snapshot.

  • Doppelte Elemente: Wenn mehrere Elemente Text+Rolle teilen (z. B. 3 „Gefällt mir"-Buttons), wählt der Fallback-Auflöser das richtige per Ordnungszahl (nth), nicht nur den ersten Treffer.

  • Ein eingefrorener Tab (nativer Dialog blockiert) führt nicht in eine Sackgasse: browser_handle_dialog verwirft ihn über CDP, und browser_tabs { action: "close" } funktioniert immer als garantierter Ausweg.


🧠 Bringen Sie Ihrem Agenten etwas bei

Der Agent kann alle 22 Tools sofort nutzen, aber er arbeitet besser, wenn er den tab-first-Workflow kennt. Aus dem Repository-Stamm:

npm run setup:cursor   # or: node mcp-server/dist/index.js --setup cursor

Dies installiert:

  • ~/.cursor/rules/browser-controller.mdc — den Tab-Ziel-Workflow, Dropdown-Behandlung, wann Tabs gesperrt werden

  • ~/.cursor/commands/check-browser.md — fügt /check-browser zu Ihrem Cursor-Chat hinzu

Danach tippen Sie /check-browser in einen beliebigen Chat. Oder sagen Sie einfach „prüfe das Ergebnis in meinem Browser", und der Agent weiß, was zu tun ist.

npm run setup:claude

Fügt eine AGENTS.md zu Ihrem Projektstamm hinzu. Claude Code findet sie automatisch.

Siehe agent-config/ für die manuelle Installation oder zum Anpassen der Regeln.


Was es kann

22 Tools. Jedes Seiten-Interaktions-Tool nimmt eine tabId entgegen (die einzige Ausnahme ist browser_navigate, wo sie optional ist).

Sehen

Tool

Was es tut

browser_snapshot

Barrierefreiheitsbaum mit Element-Referenzen. Der Kompaktmodus (Standard) gibt nur interaktive Elemente zurück. Durchläuft Shadow-DOM und iframes.

browser_screenshot

Erfasst einen Tab als Bild (aktiviert den Tab zuerst, um ihn zu erfassen)

browser_text

Extrahiert Rohtext aus Seite oder Element

browser_find

Fragt Elemente per natürlicher Sprache ab – durchläuft auch Same-Origin-iframes

Interagieren

Tool

Was es tut

browser_click

Klicken per Referenz oder CSS-Selektor – durchdringt Same-Origin-iframes

browser_click_text

Klicken per sichtbarem Text. Funktioniert durch React-Portale und Overlays

browser_type

Eingabe in Eingabefelder und contenteditable-Felder

browser_press_key

Tastenkombinationen (Enter, Escape, Strg+A)

browser_scroll

Scrollt Seiten und virtuelle Container

browser_hover

Löst Tooltips und Dropdowns aus

browser_select

Auswahl aus nativen <select>-Dropdowns

browser_wait

Wartet auf das Erscheinen oder Verschwinden von Elementen

browser_fill_form

Füllt mehrere Formularfelder in einem Aufruf (React/Vue-sichere Setter)

browser_drag

Ziehen von Element zu Element (nutzt CDP für Zuverlässigkeit)

browser_upload_file

Lädt Dateien über <input type="file"> hoch (nutzt CDP, strict-CSP-sicher)

browser_upload_file injiziert lokale Dateien in ein <input type="file">, als ob der Benutzer sie ausgewählt hätte: Der native Dialog öffnet sich nie, und input/change-Events werden danach ausgelöst, sodass React/Vue-Formulare reagieren.

browser_upload_file { tabId: 15, selector: "#resume", filePath: "/Users/me/resume.pdf" }
browser_upload_file { tabId: 15, ref: "e12", files: ["/tmp/a.png", "/tmp/b.png"] }

Pfade sind absolut und lokal auf der Maschine, die den Browser ausführt. Lassen Sie ref/selector weg, um automatisch das erste Datei-Eingabefeld auf der Seite anzusteuern; mehrere Dateien gleichzeitig erfordern ein Eingabefeld mit multiple.

Navigieren

Tool

Was es tut

browser_navigate

Zu einer URL in einem Tab wechseln (tabId optional, Standard ist der aktive Tab)

browser_tabs

Tabs auflisten / erstellen / schließen / fokussieren / sperren / entsperren

Debug & Erweitert

Tool

Was es tut

browser_console

Konsolenausgabe (log, warn, error) – pro Tab, auf 200 Einträge begrenzt

browser_network

XHR/fetch-Anfragen mit Statuscodes – pro Tab, optionales limit

browser_evaluate

JavaScript in der MAIN-Welt der Seite ausführen (kein Banner, CSP-sicher)

browser_handle_dialog

Ein offenes alert/confirm/prompt über CDP schließen/akzeptieren (funktioniert auf eingefrorenen Seiten)

browser_run_action

Ein eigenständiges JS-Aktionsobjekt über CDP ausführen


Vergleich mit anderen

Browser Controller

Playwright MCP

Chrome DevTools MCP

Verwendet Ihren vorhandenen Browser

Ja

Nein, startet neu

Teilweise, benötigt Debug-Port

Sitzungen und Cookies

Bereits vorhanden

Neues Profil

Manuelle Einrichtung

Funktioniert hinter Corporate-SSO

Ja

Nein

Kommt darauf an

Mehrere Agenten, mehrere Tabs

Ja

Nein

Nein

Tab-Ausrichtung (übernimmt nicht den aktiven Tab)

Ja

N/A

Nein

Authentifizierte lokale Verbindung

Ja

N/A

Nein

Einrichtung

Aus Quellcode + Erweiterung erstellen

Headless-Browser

Chrome mit --remote-debugging-port


Konfiguration

Env var

Standard

Was es tut

WS_PORT

7225

WebSocket-Port, den der Daemon für die Erweiterungsverbindung verwendet

BROWSER_CONTROLLER_PROGRESSIVE

(nicht gesetzt)

Auf 1 setzen, um die progressive Offenlegung von Tools zu aktivieren: Nur das Meta-Tool browser_tools ist beim Start sichtbar (~150 Tokens statt ~4200 für alle 22 Definitionen). Der Agent entdeckt Tools über browser_tools {action:"list"/"search"} und aktiviert sie mit {action:"details", tool:"…"}. Standard (nicht gesetzt) zeigt alle Tools im Voraus – sicher für Agenten, deren Anweisungen Tools direkt aufrufen.

MCP_AGENT_NAME

(auto: IDE-Name)

Überschreibt den im Popup angezeigten Agentennamen (wie --agent)

Daemon-Zustandsdateien

Der Daemon speichert alles in ~/.browser-controller/ (Windows: %USERPROFILE%\.browser-controller\):

Datei

Zweck

enrollment.json

Einmaliges Pairing-Geheimnis für die Erweiterung (Modus 0600)

token.json

Auth-Token, den die Erweiterung bei jeder WebSocket-Verbindung vorweisen muss (Modus 0600)

daemon.sock

Der IPC-Socket, mit dem sich Thin Clients verbinden (AF_UNIX auf Mac/Linux; Named Pipe auf Windows)

daemon.json

Daemon-Metadaten (pid, Port, Startzeit) – zur Erkennung eines laufenden Daemons

daemon.log

Daemon stdout/stderr, wenn von einem Client gestartet

Für einen vollständigen Reset: Stoppen Sie Ihre MCP-Clients, löschen Sie den Ordner, und der nächste Lauf erstellt ihn mit neuen Geheimnissen neu.

Zuverlässigkeit

  • Der Daemon wird beim ersten Lauf eines Clients automatisch gestartet und läuft dann unabhängig weiter.

  • Verbindungsabbrüche verwenden exponentielles Backoff (1s → 30s), Ping/Pong-Health-Checks alle 10s; ein Client, der 3 Pongs verpasst, wird entfernt.

  • Ein Ratenlimit von 120 Aufrufen pro Minute pro Sitzung schützt den Daemon vor einer außer Kontrolle geratenen Agentenschleife.

  • Zeitlimits pro Tool (5–15s für die meisten Aktionen, 60s für Navigation), zusammen mit der Definition jedes Tools, damit sie nicht von der Registrierung abweichen.

  • Idempotente Lesetools (snapshot, screenshot, text, find) werden bei Zeitüberschreitung erneut versucht; Tools mit Seiteneffekten (click, type, navigate, evaluate) – sowie console/network (die bei clear:true mutieren) – werden nie erneut versucht, sodass ein Klick nicht zweimal ausgelöst werden kann.

  • Wenn ein anderer Prozess bereits Port 7225 belegt, weigert sich der Daemon zu starten, anstatt einen Prozess zu beenden, den er nicht gestartet hat – er meldet den Konflikt, damit Sie ihn bewusst lösen können.

Führen Sie zwei Daemons auf verschiedenen Ports aus, indem Sie WS_PORT pro Client setzen:

{
  "mcpServers": {
    "browser-work": {
      "command": "node",
      "args": ["/path/to/browser-controller/mcp-server/dist/index.js"]
    },
    "browser-personal": {
      "command": "node",
      "args": ["/path/to/browser-controller/mcp-server/dist/index.js"],
      "env": { "WS_PORT": "9333" }
    }
  }
}

Aktualisieren Sie den Port in jedem Erweiterungs-Popup entsprechend.


Architektur

Alles bleibt auf Ihrer Maschine. Die Erweiterung verbindet sich über ein authentifiziertes WebSocket auf localhost mit dem Daemon; MCP-Clients verbinden sich über einen lokalen IPC-Socket mit dem Daemon. Keine Cloud, kein Proxy, nichts verlässt Ihren Browser.

browser-controller/
├── mcp-server/          MCP server (TypeScript)
│   └── src/
│       ├── daemon.ts        Single multi-client daemon (owns WS :7225)
│       ├── daemon-config.ts IPC protocol, paths, auth/enrollment tokens
│       ├── index.ts         Thin stdio MCP client (spawns daemon, multiplexes)
│       ├── bridge.ts        Extension WS server + cross-platform port probe
│       ├── register-tools.ts Progressive-disclosure wiring
│       └── tools/           One file per tool (22), registry pattern
├── extension/           Chrome extension (Manifest V3, plain JS, ES modules)
│   ├── background.js        Wiring only (~30 lines): inject router, register events, connect
│   ├── lib/                 state (buffers/locks/persistence), connection (WS lifecycle),
│   │                        router (dispatch + mutex/locks + control shield), page-exec,
│   │                        overlay, lock-ops, tab-concurrency (pure, unit-tested)
│   ├── handlers/            Tool implementations: navigation, interaction, inspection, tabs, cdp
│   ├── utils/               navigation + smart-selector fallback resolution
│   ├── events.js            chrome.* listeners (console capture, popup, webRequest, lifecycle)
│   ├── content.js           Console capture
│   └── popup/               Fixed tabbed shell (Tabs · Agents · Settings) + collapsible activity bar
├── agent-config/        Pre-built configs for Cursor + Claude Code
│   ├── cursor/              Rules and commands
│   ├── skills/              Browser automation skill
│   └── setup.mjs            One-command installer
└── tests/               15 suites / 215 tests

Stack: TypeScript (strict) · MCP SDK · WebSocket · Chrome Extension Manifest V3 · Vitest

Entwicklung

git clone https://github.com/compnew2006/browser-controller.git
cd browser-controller
npm install
npm run build
npm test

Befehl

Was es tut

npm run build

Kompiliert TypeScript → mcp-server/dist/

npm run dev

Watch-Modus

npm test

Führt die vollständige Testsuite aus (215 Tests)

npm run typecheck

Typprüfung ohne Ausgabe

npm run setup:cursor

Installiert Cursor-Regel + Befehl

npm run setup:claude

Installiert Claude Code AGENTS.md

Die Suite deckt die WebSocket-Brücke ab (einschließlich Token-Auth-Ablehnung und des einheitlichen Fehlerkanals), die Tool-Registrierung, den Daemon-Lebenszyklus (Heartbeat-Entfernung, Ratenbegrenzung, IPC-Auth), die Parallelität pro Tab (Serialisierung innerhalb desselben Tabs + Parallelität über Tabs hinweg) und das Erweiterungsverhalten über eine gemockte chrome-API (Router-Dispatch, Shield-Semantik, Evaluate-Roundtrip, iframe-Durchdringung, Dialog-Rettung). CI führt die Suite auf Node 20 und 22 aus, plus CodeQL- und Scorecard-Scans.

Aktualisieren einer vorhandenen Installation

git pull
npm install
npm run build

Dann zwei manuelle Schritte: Erweiterung neu laden in chrome://extensions (ein laufender Service Worker nimmt Dateiänderungen nie von selbst auf) und Daemon neu starten – er ist langlebig und lädt dist/ ebenfalls nicht neu (beenden Sie ihn oder starten Sie einfach Ihren MCP-Client neu, und der nächste Lauf startet ihn mit dem neuen Build neu).


FAQ

Genau darum geht es. Die Erweiterung läuft in Ihrem tatsächlichen Chrome – gleiche Cookies, gleiche Sitzungen, gleicher lokaler Speicher. Keine erneute Authentifizierung erforderlich.

Nein. Die MCP-Clients, der Daemon und die Erweiterung kommunizieren alle über localhost (IPC-Socket + WebSocket). Nichts verlässt Ihre Maschine. Es gibt keine Analysen, keine Telemetrie, keine Cloud-Komponente. Siehe SECURITY.md für das Bedrohungsmodell, das Auth-Design und das TOFU-Fenster beim ersten Kontakt.

Jeder MCP-kompatible Client. Cursor, Claude Desktop, Claude Code, Windsurf, Cline und alles andere, was das MCP-Protokoll spricht. Mehrere davon können gleichzeitig gegen denselben Daemon laufen.

Ja. Jeder Agent verbindet sich mit dem gemeinsamen Daemon, erhält seine eigene sessionId und zielt auf eine bestimmte tabId. Aktionen auf demselben Tab werden über einen Pro-Tab-Mutex serialisiert; Aktionen auf verschiedenen Tabs laufen parallel. Optional kann ein Agent einen Tab locken, um exklusiven Zugriff zu beanspruchen; andere Agenten stellen sich hinter der Sperre in die Warteschlange, anstatt zu scheitern.

Das kann es nicht – nicht stillschweigend. Jedes Seiteninteraktions-Tool erfordert eine tabId, und wenn sie fehlt, erhalten Sie einen klaren Fehler tabId is required. Der Agent kann niemals versehentlich auf dem Tab handeln, den Sie gerade ansehen. (Die eine Ausnahme ist browser_navigate ohne tabId, das den aktiven Tab verwendet – aber für die Nutzung mit mehreren Agenten sollten Sie immer tabId übergeben.)

Ohne sie könnte jeder lokale Prozess auf Ihrem Rechner ein WebSocket zu Port 7225 öffnen und Ihre authentifizierten Browsersitzungen steuern (Ihre Bank, Ihre E-Mail, Ihr Unternehmens-SSO). Das Enrollment-Geheimnis koppelt die Erweiterung genau einmal mit dem Daemon (out-of-band, bevor ein WebSocket existiert); das Auth-Token authentifiziert dann jede Verbindung. Beide liegen in ~/.browser-controller/ mit Modus 0600.

Sie starten eine neue Browserinstanz von Grund auf – kein Zustand, keine Cookies, keine Sitzungen. Sie müssen jedes Mal den gesamten Anmeldevorgang erneut durchspielen. Dieses verbindet sich mit dem Browser, den Sie bereits geöffnet haben, mit allem, was bereits geladen ist.


Mitwirken

Fehlerberichte, Feature-Anfragen und PRs sind im Issue-Tracker willkommen. Öffnen Sie für größere Änderungen zuerst ein Issue.

Sicherheit

Siehe SECURITY.md – Nur-Localhost-Architektur, Token- und Enrollment-Design, Bedrohungsmodell und Hinweise zur Meldung.

Lizenz

MIT

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

No tool schema history has been recorded yet.

Maintenance

ActivityActive
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables CLI coding agents to interact with your live browser tabs via MCP, using your real sessions and cookies without a sandbox.
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Connects AI agents to your Chrome browser via MCP, enabling real-time control of existing tabs, sessions, and application state for development workflows.
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI to control a real browser through MCP tools for clicking, typing, navigation, screenshots, and more. It supports a follow mode that tracks the active tab, plus fixed mode for controlling specific tabs.
    18
    MIT

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/compnew2006/browser-controller'

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