Browser-MCP-Server

02.05.2026 11:02

Definition

Ein Browser-MCP-Server ist eine Variante eines MCP-Servers, die Tools bereitstellt, die nur im Browser-Kontext Sinn ergeben — Lese-/Schreib-Zugriff auf den DOM, Local-Storage, Geolocation, Clipboard etc. Der LLM-Host kann damit die Seite veraendern, auf der er selbst eingebettet ist, oder andere Browser-spezifische Daten lesen.

Mechanik

Pyground laedt Pyodide in einem WebWorker — Worker haben keinen direkten DOM-Zugriff. Wir bauen daher eine postMessage-Bruecke vom Worker zum Main-Thread:

[runnable-Block]
       |
       v
WebWorker (Pyodide)
+-- Python: pyground.dom.add_class("h2", "highlight")
|        |
|        v  postMessage({type:'dom:add_class', selector, name})
|        |
|        v  await response
|
Main-Thread:
+-- document.querySelectorAll('h2').forEach(el => el.classList.add('highlight'))
    +-- postMessage({type:'dom:result', value: 5})

Aus dem Pyodide-Snippet sind 19 DOM-Tools nutzbar (alle async):

Lesen: read(selector) (Text — bei <input>/<textarea> der .value), html(selector) (innerHTML), attr(selector, name), query_all(selector) (Liste mit text/href/attrs/tag/id), exists(selector)

Schreiben: set_text, set_html, add_class, remove_class, set_style(selector, dict), inject(selector, position, html) (beforebegin/afterbegin/beforeend/afterend), remove

Interaktiv: scroll_to, click, focus

Magic: create_widget(selector, position, code, opts) — fuegt ein neues runnable-Pyodide-Widget direkt in die Seite ein. show_modal(title, code, opts) — oeffnet das gleiche, aber als zentriertes Modal mit Schliessen-Button (genau das, was die Demo unten nutzt). show_fallback_snake_modal(reason) — Hardcoded-Snake im Modal, fuer Faelle wo der LLM-Output nicht parsbar war.

Reset: reset() triggert location.reload() — alle Modifikationen weg.

Hinweis JsProxy: query_all() liefert ein JS-Array von JS-Objekten zurueck. In den Snippets nutze Attribut-Zugriff (link.text, link.href), nicht Item-Zugriff (link['text'] schlaegt fehl mit „JsProxy object is not subscriptable"). Wenn du echte Python-Dicts willst: link.to_py() pro Eintrag.

Magisches Spiel-Modal — LLM-generiert

Tippe einen Spielnamen in das Feld unten, klicke Spiel generieren. Llama-3.1-8B (aus dem MCP-Eintrag, ~5 GB OPFS-Cache) schreibt ein Pygame-aehnliches Snippet, das anschliessend als spielbares Mini-Widget in einem Modal-Fenster ueber dem Content erscheint — der Agent ruft das Tool show_game(name, code) auf, das intern dom.show_modal(...) triggert.

Das ist die magische Verbindung: das LLM erzeugt nicht nur Text, sondern eine Aktion — die Seite veraendert sich live, das Ergebnis ist sofort spielbar, und mit dem ×-Button (oder ESC) ist es genauso schnell wieder weg.

Pyodide laedt… Strg/⌘+Enter zum Ausführen

      
Nach dem Run erscheinen hier die Top-Level-Variablen.

Tipp: Was funktioniert zuverlaessig? Llama-3.1-8B kennt snake, pong, breakout und einfache bouncing ball-Variationen. Komplexere Spiele wie tetris oder pacman klappen mal, mal nicht — dann springt der Fallback-Snake ein.

Sicherheitsmodell

Aktuell loose: jeder Selector ist erlaubt, Schreibzugriff auf das ganze document. Das ist bewusst Tueftler-Default — Pyground ist kein Security-Sandbox-Tool, der User entscheidet ob er Snippets vertraut. Wenn der gleiche Mechanismus in produktiven Apps deployt werden soll, sind drei Stufen denkbar:

  • Loose (was wir haben): voller document-Zugriff. Maximal magisch.
  • Strict-Sandbox: Schreibzugriff nur in einer <div data-mcp-sandbox>-Container, Lesen ueberall.
  • Hybrid: Lesen frei, Schreiben erfordert explizites dom.enable_writes() als User-Gesture.

In Cloud-LLM-Hosts wie Claude oder GPT mit Browser-Tool-Use ist das Sandboxing typischerweise strikter — der LLM sieht eine isolierte Page-Capture, nicht die Live-DOM des Hosts.

In der Praxis

Browser-MCP-Server in der freien Wildbahn:

  • Anthropic Browser-Tool: Claude kann Webseiten via Headless-Browser-Sandbox ansteuern, mit Screenshots + Element-Tree als Input
  • OpenAI Operator: aehnlicher Ansatz, mit eigenem virtuellen Browser
  • browser-use (Open-Source): Library, die einen Playwright-Browser an einen LLM koppelt
  • Pyground.dom (was du gerade siehst): Pyodide-Pyground-spezifisch, aber das gleiche Pattern auf Browser-Worker-Bridge runtergebrochen

Die DOM-Bridge-Architektur ist nicht spezifisch fuer pyground — jeder Pyodide-im-Browser-Stack kann das nachbauen. Was pyground hier zeigt: dass die Komponenten (Pyodide + WebLLM + DOM-Bridge) ohne Cloud-Backend kombinierbar sind.

Quellen