Skip to main content
Glama
mouse9527

chrome-devtools-mcp

by mouse9527

browser-mcp-image

Container image for ChromeDevTools/chrome-devtools-mcp served over MCP Streamable HTTP by punkpeye/mcp-proxy. It attaches to a Chrome / Chromium that is already running (for example a sidecar with a persistent profile) over the DevTools protocol; the image contains no browser.

  • Unmodified upstream: chrome-devtools-mcp and mcp-proxy from npm, every dependency pinned by package-lock.json (version + sha512); install scripts are not run. This repo only adds an entrypoint.

  • One upstream process for all sessions: mcp-proxy starts a single chrome-devtools-mcp child and every MCP session talks to it. With --page-id-routing every page-scoped tool requires a pageId, so several clients can drive their own tabs in the same browser at the same time without touching each other's (or the user's) tabs.

  • Runtime: gcr.io/distroless/nodejs22-debian13 — no shell, no package manager; runs as uid 1000.

  • Image: ghcr.io/mouse9527/browser-mcp-image:sha-<short commit> (linux/amd64; built only from main; no latest).

Component

Version

chrome-devtools-mcp

1.12.0

mcp-proxy

6.7.21

Node.js

22 (distroless, Debian 13)

What the entrypoint does

Starts mcp-proxy in the same process, listening on MCP_HOST:MCP_PORT at /mcp (Streamable HTTP only; /sse is off), with this child:

chrome-devtools-mcp --browserUrl=$BROWSER_URL --page-id-routing --experimental-vision
                    --no-usage-statistics --no-performance-crux --no-file-navigations
  • --experimental-vision adds coordinate tools (click_at) for things without an accessibility node (canvas etc.).

  • Outbound calls of the MCP server itself are off: npm update check, usage statistics, CrUX lookups and config file discovery (CHROME_DEVTOOLS_MCP_NO_UPDATE_CHECKS / _NO_USAGE_STATISTICS / _NO_CONFIG_DISCOVERY = 1).

  • file: URLs cannot be opened with new_page / navigate_page.

  • If chrome-devtools-mcp exits, mcp-proxy exits too (non-zero), so the container runtime restarts it.

  • If the browser restarts, the next tool call reconnects by itself; its reply starts with Note: the browser was restarted or reconnected since the last call. Page ids have changed. Clients must then find their pages again (list_pages); old page ids may point at other tabs.

Related MCP server: chrome-pilot-mcp

Environment

Variable

Default

Meaning

BROWSER_URL

http://127.0.0.1:9222

DevTools HTTP endpoint of the running browser

MCP_HOST

0.0.0.0

Listen address

MCP_PORT

8931

Listen port (/mcp)

MCP_REQUEST_TIMEOUT_MS

900000

Per-request limit inside mcp-proxy (long wait_for / scripted waits)

MCP_PROXY_API_KEY

unset

mcp-proxy option: when set, clients must send X-API-Key

HOME

/tmp/home

Must be writable

Writable paths needed with a read-only root filesystem: /tmp — mount an emptyDir / tmpfs there.

Run

# a browser with remote debugging on 127.0.0.1:9222 in the same network namespace (Pod / --network host)
docker run --rm --network host ghcr.io/mouse9527/browser-mcp-image:sha-<short commit>

Kubernetes: run it as a second container in the browser's Pod; keep the browser's DevTools port on 127.0.0.1.

Security notes

  • No authentication by default, like most stdio-to-HTTP bridges: anyone who can reach the port can fully drive the browser, including its logged-in sessions and arbitrary JavaScript in pages (evaluate_script). Restrict who can reach it (NetworkPolicy / private network), or set MCP_PROXY_API_KEY.

  • Never expose the browser's DevTools port itself.

Upgrading

  • chrome-devtools-mcp / mcp-proxy: change the versions in package.json, then regenerate the lockfile from the public npm registry: npm install --package-lock-only --ignore-scripts --omit=dev --registry https://registry.npmjs.org. Check the upstream changelogs for new tools / changed flags and update the expected tool count in smoke.sh.

  • Base images: update the digests in NODE_IMAGE / RUNTIME_IMAGE; keep both on the same Debian release.

CI

.github/workflows/image.yml: build linux/amd64 → audit.sh (no credentials or .git in the image, no browser downloaded, installed versions = package.json; file list and hashes uploaded as an artifact) → smoke.sh against the runner's headless Chrome (33 tools, /sse off, uid 1000, no shell, telemetry off, two interleaved tasks each on its own pageId with a fresh MCP session per call — smoke/isolation.py, file: refused, reconnect after a browser restart) → push to ghcr from main only.

License

MIT for the files in this repository (LICENSE). The image also contains third-party software under its own licenses; see NOTICE.md.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables reading browser DevTools data (tabs, console errors, network requests, screenshots, DOM, CSS, JS execution) via Chrome DevTools Protocol.
    3,154 npm
    MIT
  • A
    license
    B
    quality
    C
    maintenance
    Enables MCP clients to drive a real Chromium browser for automation, including navigation, JavaScript execution, CDP commands, network capture, and multi-tab control.
    7
    GPL 3.0