Better Claude in Chrome
July 28, 2026 · View on GitHub
Let Claude Code drive your real, logged-in browser. It sees and claims the tabs you already have open — your cookies, your sessions, your logins — and reads, fills, clicks, and navigates them over the Chrome DevTools Protocol. Owned end to end: no third-party service, no network port, a compact codebase you can read in one sitting.
A fuller, self-hosted take on "Claude in Chrome" — it works with your existing signed-in browser instead of spinning up a fresh sandbox.
Why it's different
- Programmable, not one-op-at-a-time. The
runtool executes a JavaScript automation script in one call, driving a Playwright-shapedpagewith semantic, auto-waiting locators (getByRole/getByText/getByLabel/…) — locate, fill, click, wait, loop, and read a whole flow in a single round trip instead of a tool call per action. This is what makes it feel fast. - Your real session, not a sandbox.
tabs_listshows every tab across every window;tab_claimtakes control of one in place. No re-login, no fresh profile. - Sees inside cross-origin iframes. Stripe card fields, "Sign in with Google" frames, embedded
editors —
read_pagemerges out-of-process frames and clicks land inside them (coordinate-translated). - Signs you in without ever seeing the secret.
credential_requestpops a secure window you type into; the bridge fills the page and returns only a status. The value never reaches the model. - Cheap by design. Every action returns a status header (
{url, title, new console errors}) so the agent usually skips a follow-up read. Screenshots auto-downscale to the model's vision limits. - Private. No TCP port anywhere — a
0600unix socket + Chrome native messaging, with the extension id pinned in the manifest. A small, auditable codebase.
Quickstart
Easiest — install it from tweakcc-fixed. Run
npx -y tweakcc-fixed, pick Better Claude in Chrome, and it fetches this repo, wires up the MCP
server and the /browser skill, walks you through loading the extension once, and verifies the
connection. Reinstall / repair / uninstall live in the same menu. No clone, no manual steps.
Or install directly from a checkout of this repo:
# 1. install the host + skill (global scope shown; --scope project also supported)
node host/setup.mjs install --scope global
# 2. load the extension once
# brave://extensions → Developer mode → Load unpacked → extension/ (then enable it)
# 3. confirm the socket is live
node host/setup.mjs verify
Then just ask Claude to do something in your browser, or run /browser for the full playbook.
node host/setup.mjs status # what's installed
node host/setup.mjs uninstall # reverses everything (re-enables Claude-in-Chrome only if we disabled it)
Installing globally also disables the built-in Claude in Chrome so you have one browser surface;
--scope project scopes that to a single project. Uninstall restores it — but only if we turned
it off. Reload the extension after any code change (a browser restart is not needed).
Requirements: macOS · Node 18+ · any Chromium-family browser on v125+ (for cross-origin-iframe support). The installer detects browsers structurally — every Chromium user-data dir that has actually run (Chrome, Brave, Edge, Chromium, Arc, Aside, Helium, and any future fork) gets the native-messaging manifest; each fork reads manifests only from its own dir, so all of them are registered automatically.
Tools
46 MCP tools. run is the fast path — script a whole flow in one call; the atomic tools below
are for one-off actions. cdp is the escape hatch for anything they don't cover.
| Group | Tools |
|---|---|
| Programmable | run (JS script: Playwright-shaped page/locators — getByRole/Text/Label, click/fill/press/check/selectOption/setInputFiles/dragTo, evaluate, waitForURL, domSnapshot, pdf, screenshot; browser — openTabs/claimTab/newTab/readUrls/history; auto-waiting, pierces frames + shadow DOM) |
| Tabs | tabs_list · tab_claim · tab_create (group by topic) · tab_activate · tab_release · tab_close |
| Navigate | navigate (waits for load) · reload · go_back · go_forward · wait_for |
| Read / observe | read_page (a11y tree + refs, incl. cross-origin frames) · read_text · find_text · dom_query · find · screenshot (element / full-page / marks:true set-of-mark badges, always reports its image↔CSS mapping) · probe_point (what's at {x,y} + a clickable ref; annotate:true draws a crosshair) · read_console · read_network · network_body |
| Act | click (right/double; returns a receipt naming what it hit and flags an intercepting overlay; space:"image"/"page" coords) · fill · type_text · press_key · select_option · scroll · hover · drag · act_batch · upload_file |
| Auth & dialogs | credential_request (secure popup) · dialog_handle |
| Secrets | secret_set / secret_list / secret_clear (fill by name; the literal is auto-redacted from every tool result so a page echo / network body / console line can't leak it) |
| Downloads | download_wait · downloads_list |
| Page API & assets | webmcp_tools / webmcp_call (call the page's own published tools instead of driving its UI) · page_assets / bundle_assets (inventory + download what the page rendered) |
| Clipboard | clipboard_read · clipboard_write |
| Escape hatch | cdp (any raw CDP command) |
Ships with the browser skill — a single self-contained skill/SKILL.md that leads with run
(the scripting playbook: page/locator API + patterns) and covers targeting, the interaction loop,
navigation/tabs, safety, troubleshooting, and the CDP escape hatch. Invoke it as /browser.
(skill/reference/*.md + SKILL.split.md are a dormant fallback of the earlier split version.)
Architecture
Claude Code ──MCP (stdio)──▶ host/bridge.mjs (MCP mode)
│ 0600 unix socket · /tmp/claude-browser-bridge-$USER.sock
▼
host/bridge.mjs (--native-host, launched by the browser)
│ Chrome native messaging · 4-byte LE length + JSON
▼
extension/ (MV3 service worker)
│ chrome.debugger (CDP 1.3) · chrome.tabs · chrome.tabGroups
▼
your real, logged-in tabs ─ incl. out-of-process iframes
One file, two modes: the browser launches bridge.mjs --native-host (bridging native messaging to
the socket); Claude Code launches bridge.mjs in MCP mode (exposing the tools over the socket). The
extension is a thin, generic CDP proxy — all behavior lives in the host and the skill.
Security & trust model
- No network port. The only IPC is a
0600unix socket (owner-only) and Chrome native messaging. - Pinned extension id. The native-messaging manifest's
allowed_originspins the extension's deterministic id (fixed public key), so only this extension can talk to the host. - Secrets stay out of the model.
credential_requestcollects values in the extension's own popup window and fills them via CDP — never logged, never returned, never in the model's context. The agent can'ttab_claimthe popup (extension/browser pages are refused and hidden fromtabs_list). - Tab safety.
tab_closeonly closes tabs the agent opened; your own tabs are protected in code.
Provenance: a clean-room implementation inspired by the shape of mature browser-agent tooling. All its own code.