chrome-bridge
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@chrome-bridgefetch my recent tasks from Axcess"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
chrome-bridge
Install as a Claude Code plugin
/plugin marketplace add bbauersjt/sjt-chrome-bridge
/plugin install chrome-bridge@sjt-chrome-bridgeThen two manual steps the plugin can't do for you: pip install -r requirements.txt,
and load the extension/ folder as an unpacked extension in Chrome
(chrome://extensions → Developer mode → Load unpacked). Details below.
A direct line from Claude Cowork into your authenticated Chrome session — no linked tab, no file relay, no tab-group sprawl. Cowork calls MCP verbs; a local relay forwards them over a localhost WebSocket to an MV3 extension, which acts inside the live page (reads it, injects JS, calls the backend with the page's own cookies/CSRF) and returns the result.
Cowork ──MCP stdio──► server.py (relay) ──localhost WS (token)──► extension ──► Axcess / Suralink pageThis is the generic transport. Site-specific JS (Axcess, Suralink) lives in the skill, not here.
Related MCP server: Chrome MCP Server
Pieces
File | Role |
| MV3 extension. Holds the outbound WS, runs |
| Local stdio MCP server. Registers the |
| The WebSocket hub (background thread, request/response correlation). |
| Registers |
|
|
| Proves the server half with a mock extension — no Chrome/Claude needed. |
Verbs
chrome_bridge_status()— is the server up and the extension connected? Start here.chrome_list_tabs()— open tabs (id/url/title); use an id astarget.chrome_page_info(target="active")— url/title/readyState.chrome_fetch(url, method, headers, body, target="active")— runsfetch()inside the page, so it carries that page's cookies/auth/CSRF. The backend-call primitive.chrome_eval(code, target="active", world="MAIN")— arbitrary JS, JSON result. MAIN world is subject to the page's CSP (may block eval); preferchrome_fetchfor backend calls.
Setup (Windows)
Install deps —
pip install -r requirements.txtLoad the extension — Chrome →
chrome://extensions→ enable Developer mode → Load unpacked → select theextension/folder. The toolbar badge reads on once it connects to the server (which must be running — see step 4/5).Register the server —
powershell -ExecutionPolicy Bypass -File ".\register_server.ps1"Fully quit and reopen the Claude desktop app (not just close the window) so it loads the new MCP server and launches
server.py.Test — open an Axcess tab and log in, then in Cowork:
chrome_bridge_status→extension_connected: truechrome_list_tabs→ your tabschrome_page_info→ the Axcess page's url/titlechrome_fetchan Axcess backend endpoint → JSON, authenticated.
Verify the server logic anytime without Chrome: python selftest.py → SELFTEST OK.
Security model
Server binds 127.0.0.1 only and requires a shared token (
BRIDGE_TOKEN, must match inbridge_core.pyandextension/background.js).The relay is capability-by-omission: no filesystem/shell/code-exec verbs. Arbitrary JS (
chrome_eval) runs in the browser page, contained by Chrome's sandbox — never on the host.You stay logged in as yourself; the extension reuses your live session (correct for an attest tool).
Known limits / next
DEV token is hardcoded. Before sharing with coworkers, move it to an extension options page (per-user secret), not source.
Multiple instances self-organize. The desktop app and the Cowork runtime each spawn
server.py. The first to bind 8765 is the daemon (owns the extension); any other becomes a controller that proxies its calls through the daemon. So whichever process a call lands on, it reaches the one extension.chrome_bridge_statusshowsroleand (for the daemon) the controller count.MV3 keepalive. While connected, the worker pings every 20s so it isn't suspended (WebSocket activity resets Chrome's idle timer). A 30s alarm + on-demand connect cover cold starts, so a dropped socket self-heals within ~30s.
One extension at a time. The daemon tracks a single extension socket. If the extension is installed in multiple Chrome profiles, disable all but one (the daemon would otherwise bind to whichever connected last). Multi-profile routing is a future enhancement.
chrome_evalvs page CSP. If a page blocks eval, usechrome_fetchorworld="ISOLATED".Distribution. One-click handoff later = publish the extension (Web Store / enterprise CRX) + bundle
server.pyas a Cowork plugin (which registers the MCP server) + freeze Python to an exe so coworkers need no toolchain.Port is
8765(change in bothbridge_core.pyandbackground.jsif it collides).
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/bbauersjt/sjt-chrome-bridge'
If you have feedback or need assistance with the MCP directory API, please join our Discord server