Own Your Stack/The Instruments/browser-bridge
Own your browser
browser-bridge
Stealth headless Chromium in a container, CDP on your own endpoint — Playwright, Puppeteer, or any MCP tool plugs in.
Every agent, scraper, and test runner that needs a browser ends up bundling one. That means image bloat, OS dependencies, font rendering, and fingerprint maintenance repeated in every container — and a headless browser that fails bot checks because it ships without realistic defaults.
browser-bridge centralizes one browser instead. It runs hardened, stealth headless Chromium in a Docker container and exposes a Chrome DevTools Protocol endpoint on port 9222 — a CDP endpoint you own, on your own infrastructure. Any number of clients connect over it: Playwright, Puppeteer, or any MCP browser tool that speaks CDP. It runs as a non-root user, carries a Docker healthcheck, and isolates each client's work through standard browser contexts.
# one browser container you own docker run --rm -p 9222:9222 \ --shm-size=512m \ ghcr.io/askalf/browser-bridge:latest # connect from anywhere on the host chromium.connectOverCDP('http://localhost:9222')
A CDP endpoint you own
Chromium binds to the wildcard on 0.0.0.0:9222, so other containers or your dev machine can reach it. The endpoints are standard — /json/version over HTTP, ws://…/devtools/… over WebSocket — which is exactly what any CDP client expects. No browser bundled into the client; it just connects.
Stealth by default
It ships the full puppeteer-extra evasion set — navigator.webdriver, plugins, languages, the WebGL vendor, the Chrome runtime, iframe quirks — and drops --enable-automation from the launch args. A realistic 1920×1080 viewport, en-US language, and font-render hinting come configured, so it passes the common bot-detection checks that bare headless containers fail.
Plugs into Playwright, Puppeteer, or MCP
Point Playwright at connectOverCDP, Puppeteer at the browserWSEndpoint, or an MCP browser server at its browserURL option. They share one Chromium instance; for session isolation each client uses its own browser context. One browser, many clients.
Non-root, healthchecked, observable
It runs as the browser user rather than root, so a CDP escape doesn't inherit privilege. A Docker healthcheck hits /json/version every 15 seconds, and a heartbeat log line each minute confirms the browser is still connected — pair it with a restart policy for self-recovery.
Routes through a VPN when you want
Set HTTPS_PROXY or HTTP_PROXY and Chromium's traffic flows through a VPN sidecar — Gluetun and friends are supported out of the box. CDP is unauthenticated by design, so it's meant to live on a private network: bind it to your compose network or VPN, never the public internet.
Part of The Instruments.
browser-bridge gives the fleet a browser. The Instruments are the agents that do real work with real tools — research, computer use, fleet nodes, and a browser — not just chat completions.
Run the browser on your own box.
browser-bridge is open source and MIT-licensed. Read the code, pull the image, point your tools at a CDP endpoint you own.
View browser-bridge on GitHub →