让任何 MCP 客户端驱动你真实的、已登录的 Chrome。在官方 Claude-in-Chrome 集成不可用的环境下,用标准 MCP 提供同等的浏览器自动化能力。
Drive your real, signed-in Chrome from any MCP client. Provides browser automation over standard MCP where the official Claude-in-Chrome integration is unavailable.
MCP client A ─┐
MCP client B ─┼─ HTTP MCP (http://127.0.0.1:8770/mcp) ─▶ RESIDENT chrome-mcp server ─┐
MCP client C ─┘ │
hosts WS bridge (ws://:8765/bridge) │
┌─────────────────────────────────────────────────────────────────────────────────────────┘
▼
Chrome extension (MV3) ──chrome.debugger (CDP)──▶ your real, signed-in Chrome
从任何会说 MCP 的客户端(Claude Code、Cursor 等)驱动你真实的、已登录的 Chrome。
在某些环境下,官方的 Claude-in-Chrome 集成可能不可用;此时 chrome-mcp 用标准 MCP 的方式提供同类的浏览器自动化能力——它只是一个普通的自定义 MCP server。
一个常驻 server,服务多个会话。 server 作为独立守护进程运行,通过 HTTP 同时服务每一个 MCP 会话,同时只维持一条到扩展的 WebSocket bridge。于是多个会话共享同一个浏览器——不会出现每个会话各起一个进程、争抢 bridge 端口的问题(这是 stdio 型 MCP server 的坑)。
因为它驱动的是你真实的 Chrome 配置文件,所有已登录的站点(Gmail、小红书、内部看板)都直接可用——无需重新登录,也不用一次性的临时配置文件。
| 工具 | 作用 |
|---|---|
browser_status |
扩展是否已连接? |
navigate |
打开一个 URL |
click |
按 CSS selector 或 x/y 坐标点击 |
type_text |
输入文本(可选地回车提交) |
read_page |
读取页面文本或 HTML(文本上限 5 万字符,超出时带 truncated 标志) |
screenshot |
PNG 截图(以 MCP image 返回) |
evaluate |
执行一段 JS 表达式并返回其值 |
tabs |
在 Claude Code 标签组里 list / open / close / select 标签页 |
每个驱动页面的工具还接受一个可选的 tab 标签——见并行会话与子代理。
每个受控标签页都带有一个 key,使并发的调用方不会互相覆盖对方的页面:
-
不同的 Claude Code 会话会自动隔离——每条 MCP 连接拿到自己的标签页,key 来自传输层的
mcp-session-id。 -
同一个会话里的并行子代理共享同一条 MCP 连接,因此不会自动隔离——不加处理的话它们会同时驱动同一个标签页。给每个子代理传一个不同的
tab标签,让它们各自拥有独立的标签页:Agent A → navigate(url=…, tab="a") Agent B → navigate(url=…, tab="b") # 独立标签页,并发运行显式的
tab会覆盖按连接派生的 key;不传则保持默认(按连接)的行为。扩展为每个标签页持有独立的chrome.debugger连接,因此多个标签页可以同时运行而不会相互抢占。注意:每个带标签的标签页都在它自己的 "Claude Code" 标签组里,所以
tabs action=list只会显示当前这个标签的页面,而不是所有会话的页面。
cd ~/codes/chrome-mcp
uv sync./run-server.sh # HTTP MCP 在 :8770,WS bridge 在 :8765(幂等)让它一直运行(这是共享的守护进程)。日志:/tmp/chrome-mcp-server.log。
或者自动启动——用 Claude Code 的 SessionStart hook,这样每次开会话时它都已经在跑。ensure-daemon.sh 是幂等的,并以**脱离会话(detached)**的方式启动守护进程(它会比启动它的那个会话活得更久):
// .claude/settings.json
{ "hooks": { "SessionStart": [{ "hooks": [
{ "type": "command", "command": "./ensure-daemon.sh" }
] }] } }Claude Code(user 作用域,HTTP 传输,在 Bedrock 下可用):
claude mcp add --transport http --scope user chrome-mcp http://127.0.0.1:8770/mcp验证:claude mcp list 应显示 chrome-mcp … ✔ Connected。
- 打开
chrome://extensions,启用开发者模式。 - 加载已解压的扩展程序 → 选择
~/codes/chrome-mcp/extension/。 - 点击 Chrome MCP 工具栏图标 → Connect(圆点变绿)。
第一次浏览器操作会弹出 Chrome 的"已开始调试此浏览器"横幅——这是正常的,留着别关。
在 Claude Code 里(Bedrock 认证没问题):
打开 https://news.ycombinator.com,告诉我前 3 条新闻标题。
Claude 会调用 mcp__chrome-mcp__navigate / read_page,在你真实的 Chrome 里、一个专用的蓝色 Claude Code 标签组中执行操作。
| 变量 | 默认值 | 用途 |
|---|---|---|
CHROME_MCP_HOST |
127.0.0.1 |
bridge 绑定的 host |
CHROME_MCP_PORT |
8765 |
bridge 端口(若修改,需同步更新 extension/background.js 里的 WS_URL) |
CHROME_MCP_PATH |
/bridge |
bridge 的 WS 路径 |
- 同一时刻只有一条连接。 扩展只维持一条 WS 链接(新连接获胜)。不要同时跑两个指向同一扩展的 MCP server。
- 安全。 扩展拥有很大的权限,并在已登录站点上以你的身份操作。bridge 只监听 loopback。请审视你让它做的事情;页面有可能尝试提示词注入(prompt injection)。
- MV3 worker 挂起。 重连由
chrome.alarms保活(~24s)驱动,能在 service worker 被挂起后存活——无需手动重连。 - 改完扩展需要重新加载。 Chrome 不会热重载 service worker,重新加载时其内存中的标签映射也会被清空。改完
extension/background.js后,到chrome://extensions点扩展上的 ↻。 - 与 Anthropic 无关联,是独立项目。
Drive your real, signed-in Chrome from any MCP client — Claude Code, Cursor, or anything that speaks MCP. In environments where the official Claude-in-Chrome integration is unavailable, chrome-mcp provides equivalent browser automation over standard MCP — it's just a plain custom MCP server.
One resident server, many sessions. The server runs as a standalone daemon and serves every MCP session over HTTP, while holding a single WebSocket bridge to the extension. So multiple sessions share one browser — no per-session process racing for the bridge port (the trap with stdio MCP servers).
Because it drives your actual Chrome profile, logged-in sites (Gmail, Xiaohongshu, internal dashboards) just work — no re-auth, no throwaway profile.
| Tool | Action |
|---|---|
browser_status |
Is the extension connected? |
navigate |
Open a URL |
click |
Click by CSS selector or x/y |
type_text |
Type text (optionally submit) |
read_page |
Read page text or HTML (text capped at 50k chars, with a truncated flag) |
screenshot |
PNG screenshot (returned as an MCP image) |
evaluate |
Run a JS expression, return its value |
tabs |
list / open / close / select tabs in the Claude Code group |
Every page-driving tool also takes an optional tab label — see Parallel sessions & subagents.
Each controlled tab is keyed so concurrent callers don't clobber each other's page:
-
Separate Claude Code sessions are isolated automatically — each MCP connection gets its own tab, derived from the transport's
mcp-session-id. -
Parallel subagents inside one session share a single MCP connection, so they are not isolated automatically — without help they'd all drive the same tab. Pass a distinct
tablabel per subagent to give each its own tab:Agent A → navigate(url=…, tab="a") Agent B → navigate(url=…, tab="b") # independent tab, runs concurrentlyAn explicit
taboverrides the per-connection key. Omit it for the default (per-connection) behavior. The extension holds an independentchrome.debuggerattachment per tab, so many tabs run at once without thrashing.Note: each labelled tab lives in its own "Claude Code" tab group, so
tabs action=listshows only the calling label's tab — not every session's.
cd ~/codes/chrome-mcp
uv sync./run-server.sh # HTTP MCP on :8770, WS bridge on :8765 (idempotent)Leave it running (it's the shared daemon). Logs: /tmp/chrome-mcp-server.log.
Or auto-start it from a Claude Code SessionStart hook so it's always up when you open a session. ensure-daemon.sh is idempotent and launches the daemon detached (it outlives the session that started it):
// .claude/settings.json
{ "hooks": { "SessionStart": [{ "hooks": [
{ "type": "command", "command": "./ensure-daemon.sh" }
] }] } }Claude Code (user scope, HTTP transport, works under Bedrock):
claude mcp add --transport http --scope user chrome-mcp http://127.0.0.1:8770/mcpVerify: claude mcp list should show chrome-mcp … ✔ Connected.
- Open
chrome://extensions, enable Developer mode. - Load unpacked → select
~/codes/chrome-mcp/extension/. - Click the Chrome MCP toolbar icon → Connect (dot turns green).
The first browser action shows Chrome's "started debugging this browser" banner — that's expected; leave it.
In Claude Code (Bedrock auth is fine):
Open https://news.ycombinator.com and tell me the top 3 story titles.
Claude will call mcp__chrome-mcp__navigate / read_page and act inside your real Chrome, in a dedicated blue Claude Code tab group.
| Var | Default | Purpose |
|---|---|---|
CHROME_MCP_HOST |
127.0.0.1 |
bridge bind host |
CHROME_MCP_PORT |
8765 |
bridge port (also update WS_URL in extension/background.js if you change it) |
CHROME_MCP_PATH |
/bridge |
bridge WS path |
- One connection at a time. The extension holds a single WS link (newest wins). Don't run two MCP servers pointing at the same extension.
- Security. The extension has broad permissions and acts as you on logged-in sites. The bridge listens on loopback only. Review what you ask it to do; pages can attempt prompt injection.
- MV3 worker suspension. Reconnect is driven by a
chrome.alarmskeepalive (~24s), which survives service-worker suspension — no manual reconnect needed. - Editing the extension needs a reload. Chrome does not hot-reload the service worker, and its in-memory tab map is wiped on reload. After changing
extension/background.js, click ↻ on the extension atchrome://extensions. - Not affiliated with Anthropic. Independent project.