Skip to main content
Glama
thekk1

playwright-mcp-guarded

by thekk1

playwright-mcp-guarded

Microsoft의 playwright-mcp를 도메인 제한 및 비사용자 바인딩 방식으로 감싼 래퍼입니다. LibreChat 어시스턴트(GitHub, Wikipedia, Google, Google Scholar 등)를 위한 일반 웹 가져오기/브라우징 대체 도구로, 도메인 허용 목록(allowlist)으로 범위가 제한되며 환경 변수 하나를 편집하여 확장할 수 있습니다. ports:를 노출하지 않고, 사용자별 OAuth도 없는 일반 streamable-HTTP Docker 서비스로 배포되며, 같은 형태를 따르는 형제 프로젝트인 time-mcp-http 및 ews-mcp의 다중 사용자 모드와 함께 운영됩니다.

왜 @playwright/mcp를 직접 실행하지 않는가

@playwright/mcp에는 이미 정확히 이 목적을 위한 --allowed-origins/--blocked-origins가 있으며, 이 프로젝트는 그 적용을 다시 구현하지 않습니다 — 여전히 허용되지 않은 탐색을 실제로 차단하는 것은 그 기능입니다. 그러나 그대로 실행할 때 빠진 두 가지가 있습니다:

  1. 자체 문서에서 --allowed-origins를 "보안 경계가 아님"이라고 명시합니다. 알려진 허점은 Service Worker 및 WebSocket 트래픽이 기반이 되는 context.route() 가로채기를 우회한다는 것입니다. --block-service-workers(여기서도 무조건 설정됨)는 그 허점 중 하나를 막아주지만, 다른 하나에 대한 플래그는 없습니다.

  2. 허용 목록은 호출 모델이 볼 수 있는 어디에도 나타나지 않습니다. initialize의 instructions에도, 어떤 도구의 description에도 없습니다. 모델은 어떤 도메인에 접근 가능한지 사전에 알 방법이 없으므로, 차단된 도메인마다 매번 시도해보는 방식으로 알아냅니다.

Related MCP server: Airlock

작동 방식

하나의 컨테이너, 하나의 프로세스 트리, 하나의 구성 값(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는 수정되지 않은 실제 @playwright/mcp CLI를 자식 프로세스로 생성하여 localhost에만 바인딩하고, MCP 클라이언트로 연결한 다음, 컨테이너의 공용 포트에서 MCP 서버로 다시 노출합니다. tools/list와 initialize에는 도메인 목록이 가시성을 위해 추가되고, tools/call은 그대로 전달됩니다 — 자체 도구 로직이 없으며, 이 두 텍스트 편집 외에는 동작 변경이 없습니다. ALLOWED_ORIGINS는 시작 시 한 번 읽혀서 두 곳에 전달됩니다: 생성된 프로세스(--allowed-origins로, 실제 적용)와 두 응답 재작성(가시성 전용). 나중에 목록을 확장하려면 해당 단일 환경 변수를 한 줄만 변경하면 되며, 동기화할 두 개의 구성이 아닙니다.

실행

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는 세미콜론으로 구분됩니다 — @playwright/mcp 자체가 PLAYWRIGHT_MCP_ALLOWED_ORIGINS에 사용하는 것과 동일한 형식입니다. 빈 값은 모든 도메인을 차단합니다(시작 시 경고로 기록되며, 조용한 우회가 아님).

EXTRA_INSTRUCTIONS(선택 사항, 자유 텍스트)는 모델이 보는 initialize instructions에 그대로 추가됩니다. 허용 목록은 어떤 도메인에 접근 가능한지만 알려줄 뿐, 그 뒤에 있는 것을 어떻게 사용할지는 알려주지 않습니다 — 예를 들어 자체 호스팅 검색 엔진의 쿼리 구문 같은 것. 여기에 하드코딩하지 않는 것은 의도적입니다: 이 래퍼는 도메인 중립적으로 유지되며, 배포자가 특정 허용 목록에 필요한 운영 지식을 자신의 말로 제공합니다:

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

MCP_API_KEY가 없고, MCP 연결 자체에 인증 게이트가 없습니다 — 의도적으로, ews-mcp/time-mcp-http와 같은 이유입니다: 어떤 게이트에서든 401이 발생하면 LibreChat의 비-OAuth MCP 클라이언트가 OAuth를 시도하다가(그리고 거기에 갇혀) 버립니다. Docker 네트워크 격리가 경계입니다. 이 서버를 통해 어떤 자격 증명도 전달되지 않으며, 공개 페이지만 읽습니다.

수용된 트레이드오프이지, 실수가 아닙니다: 이는 적용을 Playwright 애플리케이션 계층(이제 --block-service-workers 포함)에 유지하며, 독립적인 네트워크 수준 경계(예: 이그레스 프록시)가 아닙니다. 이는 의도적인 단순성 선택입니다 — 하나의 배포 가능한 단위, 하나의 구성 값 — 완벽하게 안전하다는 주장이 아닙니다. 네트워크 수준의 백스톱은 이 로직을 건드리지 않고 나중에 계층화할 수 있습니다.

검증

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

로그에는 업스트림 자체의 시작 줄(Listening on http://localhost:<internal-port>) 다음에 playwright-mcp-guarded up, allowed origins=...가 표시되어야 합니다. 이 두 번째 줄은 구성된 것뿐만 아니라 현재 실제로 적용되는 목록입니다.

테스트

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

단위 테스트만 있습니다(설명/지침 재작성, 인수 전달) — Chromium이나 Docker를 실행하지 않습니다. Docker 이미지는 수동으로 엔드투엔드 검증되었습니다: 빌드, 실행, 실제 MCP 클라이언트가 연결되어 도구를 나열(허용 목록이 initialize.instructions와 browser_navigate의 설명 모두에 표시됨), 허용된 도메인(en.wikipedia.org)으로 성공적으로 탐색, 허용되지 않은 도메인(example.com)에서 net::ERR_BLOCKED_BY_CLIENT 발생 — 적용과 가시성 모두 실제로 확인되었으며, 단지 주장만 한 것이 아닙니다.

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