Skip to main content
Glama

browserd

Ein kontinuierlich aufzeichnender Chromium mit programmierbaren DevTools, über MCP für KI bereitgestellt.

Kein „Playwright, das von einem LLM gesteuert wird“ — sondern ein Browser-Daemon, der alles aufzeichnet, was er sieht, damit dein Agent nach Traffic fragen kann, der passiert ist, bevor du überhaupt daran gedacht hast zu fragen.

Node TypeScript MCP Tools Tests


Was das eigentlich ist

Die meisten Browser-MCP-Server kapseln Playwright und lassen ein Modell Dinge anklicken. Das ist ein kleiner Teil dessen, was ein Entwickler mit einem geöffneten Browser tut.

browserd betreibt einen echten, sichtbaren Chromium, den du selbst nutzen kannst, während ein Agent ihm über die Schulter schaut. Er hält eine persistente CDP-Verbindung, zeichnet Netzwerk, Konsole, Ausnahmen und Navigationen kontinuierlich auf und speichert sie in SQLite. Wenn das Modell schließlich eine Frage stellt, fragt es eine Datenbank ab — nicht den Browser.

   AI ──MCP──> browserd ──CDP──> Chromium (headed, yours to use)
                  │
                  ├── network recorder ──┐
                  ├── console recorder ──┼──> SQLite + content-addressed blobs
                  ├── page recorder ─────┤
                  └── target manager ────┘        (bodies, traces, heap snapshots)

Der Unterschied ist entscheidend. Frag einen normalen Browser-Automation-MCP „Warum ist der Checkout fehlgeschlagen?“ und er hat nichts — die Anfrage ist weg. Frag browserd und er hat die Payload, den Antworttext, den Konsolenfehler, den Stack-Trace und die genaue Quelltextzeile.


Was dein Agent tun kann

Sehen

Screenshots (Viewport / ganze Seite / Element), die als echte Bildblöcke zurückgegeben werden. Accessibility-Snapshots mit stabilen eNN-Referenzen — günstiger und zuverlässiger als Vision, um zu entscheiden, worauf man klickt.

Handeln

Klicken, Hover, Tippen, Tastenkombinationen, Scrollen, Auswählen, Hochladen, Dialoge behandeln. Fällt unter Geräteemulation auf Touch-Dispatch zurück.

Netzwerk

Jede Anfrage mit allen Headern (einschließlich dessen, was tatsächlich über die Leitung ging), Anfrage-Payloads, Antworttexte, Verursacher, Timings, Redirect-Ketten, WebSocket-Frames. Die Aufzeichnung wird aktiviert, bevor das erste Seiten-Skript läuft.

Konsole

console.*-Ausgabe und unbehandelte Ausnahmen mit Stacks, über Navigationen hinweg beibehalten. Dazu Runtime.evaluate mit der DevTools-Kommandozeilen-API ($, $$, $x).

DOM / CSS

Strukturelle Übersichten, die vollständige Kaskade, wie DevTools sie anzeigt, und css.explain_visibility — das die Regel benennt, die dein Element versteckt hat, statt ein Stylesheet zu übergeben.

Debugger

Echte Breakpoints mit Bedingungen, Step-by-Step-Ausführung, Aufruf-Frames, Scope-Ketten, Evaluate-on-Frame. Lies eine lokale Variable von einem pausierten Stack.

Speicher

localStorage, sessionStorage, Cookies, IndexedDB (lesen und schreiben), Cache Storage, Kontingente.

Profiling

CPU-Sampling, JS-Coverage, auf die Festplatte gestreamte Traces, Heap-Snapshots mit Diffing auf Konstruktor-Ebene für die Suche nach Lecks, Prozess-/CPU-Informationen.

Simulation

Eine gesteuerte Uhr, Zeitzone, CPU-Throttling, Netzwerkbedingungen, Geräteemulation, Geolokalisierung, Sehschwächen und Fehlerinjektion.

Die Dinge, die man nicht erwartet

Zeitreise. time.run("30m") stellt die Uhr vor und feuert jeden Timer, der fällig wird — ein 60-Sekunden-Intervall feuert 30-mal, sofort. time.jump("30m") springt vorwärts und feuert jeden Timer einmal — der Fall „Laptop für drei Stunden zugeklappt“. Verschiedene Fehlerklassen, verschiedene Werkzeuge.

time.install({ time: "2030-01-01T00:00:00Z" })   # page now believes it is 2030
time.run({ duration: "30m" })                     # 30 interval ticks, no waiting
time.freeze()                                     # pin it and inspect

Fehlerinjektion. Frag: „Was macht die UI, wenn Speichern 20 Sekunden dauert?“ und finde es dann tatsächlich heraus.

fault.delay({ url: "**/api/save", delay: "20s" })
fault.replace_response({ url: "**/api/user", status: 500, body: {...} })
fault.drop_next({ url: "**/api/payment", count: 1 })

Leck-Suche. Zwei Heap-Snapshots und ein Diff, nach Konstruktor aufgeschlüsselt, mit abgetrennten DOM-Knoten — die klassische Leck-Signatur.

Mensch-↔-KI-Übergabe. inspector.pick aktiviert die echte DevTools-Elementauswahl, sodass du auf das kaputte Ding klickst; der Agent liest einen Node-Handle zurück. page.highlight funktioniert in die andere Richtung.


Installation

Erfordert Node ≥ 20.11. Chromium wird aus Playwrights gebündeltem Build aufgelöst, falls vorhanden (branded Chrome 137+ hat --load-extension entfernt; der gebündelte Build hat es noch), andernfalls aus einer Systeminstallation.

git clone <your-remote> browserd && cd browserd
npm install
npm run build

Bei deinem MCP-Client registrieren

node scripts/install-mcp.mjs

Dies erkennt Claude Desktop, Claude Code, Codex CLI, Cursor, Windsurf und VS Code, fügt sich in deren bestehende Konfiguration ein (wobei zuerst eine .bak geschrieben wird) und überschreibt niemals andere Server.

node scripts/install-mcp.mjs --print            # show the JSON, change nothing
node scripts/install-mcp.mjs --client codex     # just one client
node scripts/install-mcp.mjs --headless         # auto-launch headless
node scripts/install-mcp.mjs --http --port 7331 # register the HTTP endpoint instead

Unterstützte Clients: Claude Desktop, Claude Code, Codex CLI, Cursor, Windsurf, VS Code. Codex verwendet [mcp_servers.browserd]-TOML-Abschnitte anstelle von JSON; der Installer bearbeitet diese Datei chirurgisch, sodass Kommentare und deine anderen Einstellungen erhalten bleiben.

Dann bestätige, dass jeder Client es tatsächlich starten kann:

npm run verify-mcp
  OK    Claude Code      174 tools advertised
  OK    Codex CLI        174 tools advertised
  OK    VS Code          174 tools advertised

Dies liest die echten Konfigurationsdateien und führt einen MCP-Handshake mit dem durch, was sie angeben, sodass ein veralteter Pfad oder ein handschriftlich bearbeiteter Eintrag erkannt wird, statt als funktionierend angenommen zu werden.

Oder füge es von Hand hinzu:

{
  "mcpServers": {
    "browserd": {
      "command": "node",
      "args": ["/absolute/path/to/browserd/dist/cli.js"]
    }
  }
}

Starte deinen Client neu. Es muss kein Browser geöffnet sein — der erste Tool-Aufruf, der einen benötigt, startet ihn.

Ausprobieren

Frag deinen Agenten:

Öffne news.ycombinator.com, zeig mir einen Screenshot, und sag mir dann jede Anfrage, die länger als 500ms gedauert hat, und was die langsamste zurückgegeben hat.

Oder, für die vollständige Vorstellung:

Geh zu meiner App auf localhost:3000, klicke auf Checkout, und sag mir, warum sie fehlschlägt.

Es wird den Fehler per Screenshot festhalten, den Konsolenfehler lesen, die fehlgeschlagene Anfrage finden, dir die Payload und den 400-Antworttext zeigen, die geladenen Quellen nach der aufrufenden Funktion durchsuchen und dir die Datei und Zeile übergeben.


Den Daemon direkt ausführen

node dist/cli.js                 # MCP over stdio (default)
node dist/cli.js --http          # Streamable HTTP on 127.0.0.1:7331/mcp
node dist/cli.js --tools         # print the tool surface and exit
node dist/cli.js --help

Flag

Bedeutung

--port N

HTTP-Port (Standard 7331; 0 wählt einen freien)

--host HOST

HTTP-Bind-Adresse (Standard 127.0.0.1nicht öffentlich freigeben)

--profile NAME

Profil, das von automatisch gestarteten Browsern verwendet wird

--headless

Automatisch headless starten. Standard ist ein sichtbares Fenster, das du ebenfalls nutzen kannst

--no-auto-launch

Nie implizit starten; browser.launch erforderlich

--log-level LEVEL

trace | debug | info | warn | error

Env: AGENTBROWSER_HOME, AGENTBROWSER_PORT, AGENTBROWSER_LOG_LEVEL, AGENTBROWSER_HEADLESS.

Der HTTP-Modus bindet nur an Loopback und validiert Origin — dieser Endpunkt ist vollständige Browserkontrolle, und eine Seite im offenen Web darf ihn nicht erreichen können.


Zwei Designregeln

1. Erst aufzeichnen, dann abfragen

Chromium pusht Ereignisse; der Daemon persistiert sie. Es muss nichts im Voraus aktiviert werden, und kein Ereignis wird verpasst, während das Modell nachdenkt. Der Verlauf übersteht Navigation, Schließen des Tabs und Neustart des Daemons.

Das ist tragend: Kollektoren abonnieren CDP-Ereignisse, bevor sie die Domain aktivieren, und der Ziel-Manager hält neue Ziele bei waitForDebuggerOnStart zurück, bis die Instrumentierung live ist. Das macht „wir haben die Anfrage nicht verpasst“ wahr statt nur wahrscheinlich.

2. Große Payloads gelangen nie in den Kontext

Eine 200-MB-Antwort wird als content-addressed Blob gespeichert und als Artefakt-Handle zurückgegeben. Der Agent liest sie mit artifact.search, artifact.read_lines oder artifact.json_query (einer JSONPath-Teilmenge). Gleiches gilt für Traces, Heap-Snapshots, DOM-Dumps und Konsolenexporte.

Werkzeuge sind von Natur aus query-first: dom.summary vor dom.get_html, network.summarize vor network.list_requests, js.search_source vor js.get_source.


Mensch und KI in einem Browser

Der Browser ist sichtbar und gehört dir. browser.set_control_mode legt fest:

mode

Bedeutung

observe

KI liest alles, ändert nichts

shared

beide steuern (Standard)

agent

KI besitzt die Eingabe

paused

KI eingefroren; Lesen funktioniert weiterhin

Jedes mutierende Werkzeug prüft dies — einschließlich der rohen cdp.send-Notluke.


Die Tool-Oberfläche

174 Tools. node dist/cli.js --tools listet alle auf.

browser.*      list, launch, connect, status, list_targets, set_control_mode, close
page.*         navigate, screenshot, snapshot, click, type, press, scroll, extract_text,
               wait_for, highlight, dialogs, viewport, frames, tabs
dom.*          summary, query, inspect, get_html, set_html, set_attribute, remove, export
css.*          computed, matched_rules, set_style, stylesheets, explain_visibility
js.*           evaluate, list_scripts, get_source, search_source
console.*      query, exceptions, export, clear
network.*      list_requests, get_request, get_body, summarize, search_bodies,
               list_websockets, ws_messages, export_har, simulate, clear
storage.*      local/session, cookies, indexeddb, caches, usage, export
debugger.*     enable, breakpoints, pause, resume, step, call_frames,
               evaluate_on_frame, inspect_object, wait_for_pause
inspector.*    pick, picked, element, parents, children, snapshot, accessibility_tree
profile.*      start/stop/status (presets: cpu, slow-page, hang, memory-leak, full)
profiler.*     cpu, coverage, trace, long_tasks
memory.*       heap.snapshot, heap.compare, gc, usage
time.*         install, freeze, run, jump, resume, set_fixed_date, set_wall_clock, virtual
device.*       preset, viewport, orientation, reset
environment.*  timezone, locale, color_scheme, reduced_motion, vision, status, reset
fault.*        abort, delay, replace_response, drop_next, modify_headers, list, clear
artifact.*     list, stat, read, read_lines, search, json_query, export
cdp.send       escape hatch to any raw CDP method

Testen

npm test                      # build + live MCP suite + HTTP suite
npm run test:live             # 117 checks: real MCP client, real Chromium, local fixture
npm run test:live:headed      # same, with a visible window
npm run test:deep             # 35 checks against a real public site
npm run test:http             # Streamable HTTP transport + origin guard
npm run test:real             # headed narrated walkthrough on live sites

Jede Suite startet den tatsächlichen Server und verbindet einen echten MCP-Client — Assertions laufen über tools/call, sodass Schema-Validierung, Handler-Verdrahtung und Operationen gemeinsam abgedeckt sind.

Sie prüfen Verhalten, nicht dass ein Aufruf zurückgekehrt ist:

  • die Anfrage-Payload und der Antworttext einer 400er-Antwort sind beide lesbar

  • eine 700-KB-Antwort kommt als Artefakt mit ~500 Zeichen inline zurück

  • time.run("30m") feuert ein 60-Sekunden-Intervall exakt 30-mal; time.jump feuert es einmal

  • eine lokale Variable wird von einem pausierten Aufruf-Frame gelesen (total=75, tax=15)

  • Der observe-Modus verweigert 3/3 Mutationen, erlaubt aber Lesezugriffe

  • ein exportiertes HAR lässt sich wieder als gültiges HAR 1.2 parsen

  • ein Heap-Snapshot lädt als echte .heapsnapshot

tests/deep-dive.mjs läuft gegen das Live-Hacker-News: 14 echte Anfragen mit h2/nginx/Remote-IP-Detail aufgezeichnet, ein 34-KB-Antworttext von der Leitung gelesen, 1285-Knoten-DOMSnapshot, 1603-Knoten-Accessibility-Baum und ein erkanntes 8-MB-Heap-Delta.


Aufbau

src/
  cdp/        persistent WebSocket, flat-session multiplexing
  browser/    launcher, target manager (auto-attach + debugger hold), registry, faults
  collect/    network, console, page and execution-context recorders
  store/      SQLite schema, blob store, artifact store
  ops/        the actual capabilities, independent of MCP
  mcp/        tool definitions and server wiring
  cli.ts      stdio / HTTP entry point
tests/        live MCP suites
scripts/      install-mcp.mjs

MCP ist eine Schnittstelle zum Daemon, nicht der Daemon selbst. src/index.ts exportiert den Kern, sodass eine CLI, eine REST-Ebene oder eine Test-Harness ihn direkt steuern können.

Daten liegen in ~/.agent-browser (AGENTBROWSER_HOME zum Verschieben): browserd.db, blobs/, artifacts/, profiles/, logs/.


Sicherheitshinweise

  • Nur an Loopback binden. Dieser Endpunkt ist vollständige Kontrolle über einen Browser, der deine angemeldeten Sitzungen enthält.

  • Browser-Profile unter ~/.agent-browser/profiles enthalten Cookies und Session-Tokens. Aufgezeichnete Bodies enthalten das, was die von dir besuchten Seiten zurückgegeben haben. Beides ist gitignored; belass es dabei.

  • --net-log-capture-mode=Everything kann Rohbytes von der Leitung enthalten. Verwende es nur bei Datenverkehr, der dir gehört.

  • cdp.send ist uneingeschränktes CDP, nur durch den Kontrollmodus abgesichert.


Bekannte Grenzen

  • Die Live-Bearbeitung per Debugger.setScriptSource ist aus dem aktuellen Chromium entfernt — Quelle bearbeiten und neu laden.

  • Network.getRequestPostData kann Dateien aus Multipart-Uploads auslassen, daher ist "jedes Byte jedes Uploads" allein über diesen Pfad nicht garantiert. Starten Sie mit capture_netlog für Details auf Stack-Ebene (DNS, Sockets, TLS).

  • Die gesteuerte Uhr ist ein Fake-Timer-Shim, der über addScriptToEvaluateOnNewDocument installiert wird, nicht über die Clock-API von Playwright, da der Daemon rohes CDP spricht. time.virtual legt Chromiums eigene Virtual-Time-Richtlinie offen; die beiden können nicht auf einem Ziel kombiniert werden, und der Daemon weigert sich, sie zu stapeln.

  • Die Touch-Emulation setzt Emulation.setEmitTouchEventsForMouse bewusst nicht: dieses Flag bewirkt, dass Chromium dauerhaft aufhört, Input.dispatchMouseEvent zu bestätigen. page.click erzeugt stattdessen Taps.

  • ontouchstart in window wird bei der Dokumenterstellung entschieden, erscheint also nach einem Neuladen. navigator.maxTouchPoints ist sofort live.

  • Target.openDevTools (devtools.open) ist experimentell und einige Builds lehnen es ab.

  • Sensor-Emulation ist nicht implementiert. Rohes Lesen/Schreiben von Prozessspeicher liegt außerhalb des Rahmens — das erfordert einen separaten Debugger-Adapter.


Lizenz

MIT

-
license - not tested
-
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.

Related MCP Connectors

  • Live browser debugging for AI assistants — DOM, console, network via MCP.

  • A paid remote MCP for AI agent browser DevTools MCP, built to return verdicts, receipts, usage logs,

  • A paid remote MCP for AI agent browser MCP session, built to return verdicts, receipts, usage logs,

View all MCP Connectors

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/Kawai-Senpai/Browsered'

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