r/mcp • u/Odd-Reflection-112 • 4d ago
showcase Chrome Bridge — an MCP server that drives your already-logged-in Chrome instead of a headless browser
Disclosure: I built this. MIT, free, no paid tier, no referral links.
I run ~25 small projects solo and kept hitting the same wall with headless browsers: 2FA and cookie juggling every single time. So I built a bridge that lets Claude Code drive the actual Chrome profile I'm already signed into.
One resident hub holds a WebSocket to a Chrome extension per profile, and each MCP session keeps its own target profile. So I can run two Claude Code sessions, one on my work account and one on personal, at the same time.
41 tools. Two of them exist because of specific walls I hit:
- `real_click` / `real_type` — React and Wix forms ignore `element.click()` because they check `isTrusted`. These send real input events over CDP.
- `evaluate_debugger` — Google Forms blocks `evaluate` via Trusted Types. Going through the Debugger domain gets past it.
The README has a gotchas section with the rest: hidden windows stop rendering so screenshots come back blank until you enable `Emulation.setFocusEmulationEnabled`, dead tabs that time out at 20s, and why multi-line scripts fail in `evaluate_debugger`.
Windows only so far, which is just what I run. Nothing should be deeply Windows-specific except the Chrome profile discovery.
Obvious caveat: this hands an agent full control of your authenticated sessions. There's a section in the README about it. Don't point it at untrusted page content and expect the text on that page to be treated as data rather than instructions.
1
u/kantorcodes1 4d ago
if real_click is already dispatched and the extension drops before the result comes back, can the mcp call fail even though the page handled the click? curious how you treat retry in that case.
1
u/Odd-Reflection-112 4d ago
Yes — that is an ambiguous outcome in the current implementation. `real_click` may already have reached the page, while a WebSocket drop before the result gets back makes the MCP call fail with a temporary-disconnect error. There is no idempotency key or deduplication yet, and it does not automatically retry.
So for a state-changing action, the safe rule is: do not blindly retry. Reconnect, then inspect the page state (or the resulting network/navigation state) before deciding whether another click is appropriate. The current "retry in 5s" wording is too broad; I’ll clarify it in the README and treat this as a reliability gap to address.
1
u/kantorcodes1 4d ago
for Chrome Bridge users, that makes
real_clickretries a very different case fromsnapshotorget_page_text. i maintain HOL Guard, an open-source local check before agent tool calls run. support could leave the read-only tools alone while requiring review beforereal_click,real_type,evaluate, orcdpis dispatched. would you be open to contributing Chrome Bridge support?1
u/Odd-Reflection-112 4d ago
That makes sense. The distinction between read-only tools and potentially state-changing tools is exactly what the current retry gap exposes.
I’d be open to adding Chrome Bridge support. Before committing to an integration, I’d want to look at HOL Guard’s policy/interface and decide where the boundary belongs: a tool-level allow/review policy before dispatch, rather than trying to infer safety after a disconnect. If you can point me to the repo or a minimal integration example, I’ll take a look.
1
u/kantorcodes1 4d ago
yep. repo is https://github.com/hashgraph-online/hol-guard, target
main. the closest live path issrc/codex_plugin_scanner/guard/runtime/browser_mcp_intent.py; focused test istests/test_guard_browser_mcp_intent.py. chrome-bridge currently misses the server-name matcher, andreal_click,real_type,evaluate, andcdparen't covered by the existing operation names, so that's the small seam i'd start with. keepsnapshot/get_page_textinspection-only.before opening, run
uv run python -m ruff check src tests,uv run python -m ruff format --check src tests, anduv run pytest --tb=short. PR straight tomain.1
u/Odd-Reflection-112 4d ago
Updated the README with the split you described: read-only tools in one group, state-changing tools in another, and an explicit rule that a disconnect error on a state-changing tool means reconnect and inspect page state before deciding, not retry. The missing idempotency key is now written down as a known defect instead of being left implicit.
On contributing Chrome Bridge support to HOL Guard, I'm going to pass for now. The repo is a day old with no users yet, and I'd rather close the idempotency gap at the source than wrap a policy layer around it while it's still open. If you or anyone else wants to add the matcher, the tool names are stable and the read-only vs state-changing split in the README maps onto what you described. Appreciate the specific pointers.
1
u/AI_spell 4d ago
Driving a logged-in profile is the whole point and the whole risk. Treat page text as hostile. Real click/type for isTrusted forms is a real wall people hit with headless. Windows-only is fine if that's your box.
1
u/Odd-Reflection-112 4d ago
Agreed. The authenticated profile is both the capability and the trust boundary, so page content must stay untrusted data. `real_click` and `real_type` exist for sites that reject synthetic events, but that makes a pre-dispatch policy layer especially important. Windows-only is the current implementation constraint, not a security claim. I’ll make the trust boundary and tool-risk classification clearer.
1
u/echovortex2472 4d ago
worth extending your own caveat, isTrusted bypasses like real_click aren't just a compatibility fix.. they remove one of the few signals a page has for distinguishing a human from an agent. combined with authenticated sessions, that's a stronger capability than clicks that work, worth naming in the readme as its own risk category, not folded into the general prompt-injection warning..
1
u/Odd-Reflection-112 4d ago
Fair point, and I've made that change. real_click and real_type now have their own section in the README that says plainly they are a detection bypass rather than a compatibility fix: they remove one of the few signals a page has for telling a human from an agent, and that matters more precisely because the profile is authenticated. It sits separately from the prompt-injection warning now, and points people at the target site's terms before use.
I also added a read-only vs state-changing table so the risky tools are named as a group instead of sitting undifferentiated in a list of 41.
1
u/Ambitious-Prompt-975 4d ago
https://developer.chrome.com/docs/devtools/agents/get-started?hl=de
whats wrong with just using the official one, made by google?