Skip to main content
Glama
thekk1

playwright-mcp-guarded

by thekk1

playwright-mcp-guarded

Ein domänenbegrenzter, nicht benutzergebundener Wrapper um Microsofts playwright-mcp – ein allgemeiner Web-Fetch/Browse-Ersatz für LibreChat-Assistenten (GitHub, Wikipedia, Google, Google Scholar, ...), beschränkt auf eine Whitelist von Domänen, erweiterbar durch Bearbeiten einer Umgebungsvariable. Bereitgestellt als einfacher streamable-HTTP-Docker-Dienst (keine ports: exponiert, kein benutzerspezifisches OAuth) neben Schwesterprojekten time-mcp-http und ews-mcp's Multi-User-Modus, die demselben Muster folgen.

Warum nicht einfach @playwright/mcp direkt ausführen

Es hat bereits --allowed-origins/--blocked-origins genau dafür, und dieses Projekt implementiert diese Durchsetzung nicht neu – es ist immer noch das, was eine nicht erlaubte Navigation tatsächlich blockiert. Zwei Dinge fehlen beim nackten Ausführen:

  1. Die eigene Dokumentation nennt --allowed-origins „keine Sicherheitsgrenze" – eine bekannte Lücke ist, dass Service-Worker- und WebSocket-Datenverkehr die darauf basierende context.route()-Abfangung umgehen. --block-service-workers (auch hier gesetzt, bedingungslos) schließt eine dieser Lücken; für die andere gibt es kein Flag.

  2. Die Whitelist erscheint nirgendwo, wo das aufrufende Modell sie sehen kann – weder in den instructions von initialize noch in der description eines Tools. Ein Modell hat keine Möglichkeit, im Voraus zu wissen, welche Domänen erreichbar sind, also findet es es durch Ausprobieren heraus, einmal pro blockierter Domäne, jedes Mal.

Related MCP server: Airlock

So funktioniert es

Ein Container, ein Prozessbaum, ein Konfigurationswert (ALLOWED_ORIGINS):

LibreChat --(streamable-http, /mcp)--> guardian (Python, PID 1)
                                          |
                                          | spawns as child process,
                                          | on loopback only
                                          v
                                    @playwright/mcp (Node, --allowed-origins)

guardian/app.py startet die echte @playwright/mcp-CLI, unverändert, als Kindprozess, der nur an localhost gebunden ist, verbindet sich als MCP-Client mit ihr und stellt sie als MCP-Server auf dem öffentlichen Port des Containers wieder bereit: tools/list und initialize erhalten die Domänenliste zur Sichtbarkeit angehängt, tools/call wird wörtlich weitergeleitet – keine eigene Tool-Logik, kein verändertes Verhalten außer diesen beiden Textänderungen. ALLOWED_ORIGINS wird einmal beim Start gelesen und an beide übergeben: an den gestarteten Prozess (als --allowed-origins, die eigentliche Durchsetzung) und an die beiden Antwortumschreibungen (nur Sichtbarkeit). Die Liste später zu erweitern ist eine einzeilige Änderung an dieser einen Umgebungsvariable, nicht zwei Konfigurationen, die synchron gehalten werden müssen.

Ausführen

docker build -t playwright-mcp-guarded .
docker run --rm -p 8080:8080 \
  -e ALLOWED_ORIGINS="github.com;raw.githubusercontent.com;wikipedia.org;en.wikipedia.org;google.com;scholar.google.com" \
  playwright-mcp-guarded

ALLOWED_ORIGINS ist semikolongetrennt – dasselbe Format, das @playwright/mcp selbst für PLAYWRIGHT_MCP_ALLOWED_ORIGINS verwendet. Ein leerer Wert blockiert jede Domäne (beim Start als Warnung protokolliert, kein stiller Bypass).

EXTRA_INSTRUCTIONS (optional, Freitext) wird wörtlich an die instructions von initialize angehängt, die das Modell sieht. Die Whitelist sagt nur, welche Domänen erreichbar sind, nicht wie man das verwendet, was dahinter liegt – z. B. die Abfragesyntax einer selbst gehosteten Suchmaschine. Bewusst nicht hier fest codiert: Dieser Wrapper bleibt domänenagnostisch, und der Bereitsteller liefert das nötige Betriebswissen für seine spezifische Whitelist in eigenen Worten:

-e EXTRA_INSTRUCTIONS="Search: http://searxng:8080/search?q=<term> (general), add &categories=science for Google Scholar results."

Kein MCP_API_KEY, kein Auth-Gate an der MCP-Verbindung selbst – bewusst, aus demselben Grund wie bei ews-mcp/time-mcp-http: Ein 401 von einem Gate bringt LibreChats Nicht-OAuth-MCP-Client dazu, OAuth zu versuchen (und dabei hängen zu bleiben). Die Docker-Netzwerkisolation ist die Grenze. Keinerlei Anmeldedaten passieren diesen Server; er liest nur öffentliche Seiten.

Akzeptierter Kompromiss, kein Versehen: Dies hält die Durchsetzung auf der Playwright-Anwendungsebene (jetzt mit --block-service-workers), nicht als unabhängige Grenze auf Netzwerkebene (z. B. ein Egress-Proxy). Das ist eine bewusste Einfachheitsentscheidung – eine bereitstellbare Einheit, ein Konfigurationswert – keine Behauptung, dass dies wasserdicht ist. Ein Backstop auf Netzwerkebene kann später hinzugefügt werden, ohne diese Logik anzufassen.

Überprüfen

curl -s http://127.0.0.1:8080/readyz   # "ok" once the upstream browser is up

Die Logs sollten die eigene Startzeile des Upstreams zeigen (Listening on http://localhost:<internal-port>) gefolgt von playwright-mcp-guarded up, allowed origins=... – diese zweite Zeile ist die tatsächlich durchgesetzte Liste, nicht nur das, was konfiguriert wurde.

Test

pip install -e '.[dev]'
ALLOWED_ORIGINS="github.com;wikipedia.org" pytest

Nur Unit-Tests (Umschreiben von Beschreibung/Anweisungen, Argumentdurchreichung) – sie starten weder Chromium noch Docker. Das Docker-Image wurde manuell Ende-zu-Ende verifiziert: gebaut, ausgeführt, ein echter MCP-Client verbunden und Tools aufgelistet (Whitelist sichtbar sowohl in initialize.instructions als auch in der Beschreibung von browser_navigate), erfolgreich zu einer erlaubten Domäne navigiert (en.wikipedia.org) und net::ERR_BLOCKED_BY_CLIENT bei einer nicht erlaubten erhalten (example.com) – Durchsetzung und Sichtbarkeit beide live bestätigt, nicht nur behauptet.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to search the web, fetch news, and retrieve page content via DuckDuckGo or Brave Search, with domain whitelisting and audit logging.
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables LLM agents to safely search and fetch content from a single configured domain, preventing data exfiltration through deterministic enforcement.
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables AI agents to automate browsers through Playwright behind multi-layer safety guards, restricting navigation to allowed domains, defaulting to read-only actions, and recording all behavior in audit logs.
    7
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Enables AI assistants to fetch and process web content securely, including HTML-to-markdown conversion, reader mode, metadata extraction, RSS/sitemap parsing, and robots.txt-aware requests with SSRF protection.
    15
    805 npm
    2
    MIT