dev-mcps/browser-mcp
Lucio Lelii 0e6b400441 Bring the three MCP servers together as one deployable stack
They were three folders on one laptop: a coding agent with a git history of its
own, and two servers - a development server and a browser - with none at all.
What makes them a stack is what sits between them, and that lived nowhere: the
compose file, the gateway, the egress proxy and the networks that keep the worker
off the internet. So the whole thing is one repository, and the coding agent's
separate history is folded into it rather than kept alongside.

What is deliberately absent: .env, node_modules, and the live service
definitions. The .example files next to them say what belongs there.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 11:45:55 +02:00
..
src Bring the three MCP servers together as one deployable stack 2026-09-22 11:45:55 +02:00
test Bring the three MCP servers together as one deployable stack 2026-09-22 11:45:55 +02:00
.dockerignore Bring the three MCP servers together as one deployable stack 2026-09-22 11:45:55 +02:00
.gitignore Bring the three MCP servers together as one deployable stack 2026-09-22 11:45:55 +02:00
Dockerfile Bring the three MCP servers together as one deployable stack 2026-09-22 11:45:55 +02:00
README.md Bring the three MCP servers together as one deployable stack 2026-09-22 11:45:55 +02:00
package-lock.json Bring the three MCP servers together as one deployable stack 2026-09-22 11:45:55 +02:00
package.json Bring the three MCP servers together as one deployable stack 2026-09-22 11:45:55 +02:00
seccomp_profile.json Bring the three MCP servers together as one deployable stack 2026-09-22 11:45:55 +02:00

README.md

browser-mcp

Playwright browser automation exposed only through MCP Streamable HTTP.

Security properties

  • Exact-origin allowlist for top-level navigation and every intercepted HTTP(S) request.
  • No filesystem/workspace mount.
  • No arbitrary JavaScript evaluation, file upload, download, shell, or CDP tool.
  • One isolated browser context per MCP session, destroyed when the session expires or is deleted.
  • Bounded screenshots, text snapshots, console logs, network errors, request bodies, and session counts.
  • API authentication is mandatory and browser-origin CORS is denied unless explicitly allowlisted.

The container runs as pwuser with the Chromium sandbox enabled. The stack applies Playwrights official default-derived seccomp_profile.json, which permits the user-namespace calls required by the sandbox, and restores only SYS_CHROOT after dropping every capability. Keep the container on an internal network that can reach only the development application. This is a hardened browser worker, not a VM-grade boundary.

Tools

browser_navigate, browser_click, browser_fill, browser_wait, browser_snapshot, browser_screenshot, browser_console_messages, and browser_network_errors.

Configuration

Required environment variables:

  • BROWSER_MCP_API_KEYS: comma-separated SUBJECT=TOKEN values; tokens must contain at least 32 characters.
  • BROWSER_MCP_ALLOWED_ORIGINS: comma-separated exact origins, for example http://dev-server-worker:5173. An entry may carry a port range instead of a port — http://dev-server-worker:5200-5219 — which is how one entry covers every port the dev server may hand to an execution. The host still has to match exactly; only the port varies, and only inside the declared range. An impossible range is refused at startup rather than at the first navigation.

The MCP endpoint is POST /mcp. Initialize first and reuse the returned Mcp-Session-Id. Only Streamable HTTP is implemented; there is no legacy SSE or stdio transport.

Run npm install and npm test for local tests. The provided image already contains the matching Chromium build.