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> |
||
|---|---|---|
| .. | ||
| src | ||
| test | ||
| .dockerignore | ||
| .gitignore | ||
| Dockerfile | ||
| README.md | ||
| package-lock.json | ||
| package.json | ||
| seccomp_profile.json | ||
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 Playwright’s 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-separatedSUBJECT=TOKENvalues; tokens must contain at least 32 characters.BROWSER_MCP_ALLOWED_ORIGINS: comma-separated exact origins, for examplehttp://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.