Two things make this feel built by someone who has watched agents break browsers. Snapshots hand back revision-scoped cursors, so a follow-up click targets the node that was actually seen rather than a CSS selector that may now match something else — and the cursors expire on navigation, which forces a re-read instead of a silent mis-click. And the risky operations each carry their own gate: arbitrary JavaScript, unusual URL schemes, closing an unmanaged tab. Screenshots go further by refusing caller-chosen output paths entirely.
A local-first browser automation MCP server written in Rust, built on the Chrome DevTools Protocol. It either attaches to a Chrome you already have open on a DevTools port or launches a dedicated session, and exposes high-level tools for navigation, reading, tab management, screenshots and interaction. It is a browser control layer for agents, not an end-to-end test runner.
- Navigation with a scheme gate: `http:`, `https:`, `about:` and same-origin relative paths are allowed by default, anything else needs an explicit unsafe flag — `navigate`, `go_back`, `go_forward`, `wait`
- Bounded interaction rather than arbitrary scripting — `click`, `input`, `select`, `hover`, `press_key`, `scroll`, `set_viewport`
- Tab lifecycle, with destructive operations gated behind a confirmation flag — `new_tab`, `tab_list`, `switch_tab`, `close_tab`, `close`
- Reading a page four ways: a structured snapshot of actionable nodes, focused node inspection, markdown extraction and a link inventory — `snapshot`, `inspect_node`, `get_markdown`, `extract`, `read_links`
- Snapshot modes for how much to re-read: `viewport` for the visible scope, `delta` for what changed since a compatible earlier snapshot, `full` for an exhaustive page-wide read
- Revision-scoped `cursor` handles from a snapshot, used instead of CSS selectors for follow-up actions — targets take a `selector` or a `cursor` object
- Managed PNG capture where the caller does not choose an output path: modes for viewport, full page, element or region, returning artifact metadata with dimensions, device pixel ratio and byte count — `screenshot`
- An escape hatch that has to be asked for: `evaluate` runs JavaScript in the active page and requires `confirm_unsafe = true` on every call
Rust 1.88 or newer to install or build with Cargo — `cargo install chromewright`, a Homebrew formula, or a prebuilt archive from releases. Chrome, Chromium or another CDP-compatible browser. Attach mode expects DevTools at `http://127.0.0.1:9222` by default and can be pointed elsewhere with `--ws-endpoint`; passing any launch flag such as `--headless`, `--user-data-dir` or `--executable-path` starts a browser instead. `chromewright` alone serves MCP over stdio; `chromewright serve` serves streamable HTTP at `http://127.0.0.1:3000/mcp`, with `--port` and `--http-path` to move it. Attach mode can see the tabs, cookies and authenticated state of the profile you connect to — use a dedicated profile for agent work.
One command — cargo install chromewright
