连接方式 / Connecting
驱动真实 Chrome(扩展)
需要此类任务的 CLI 细节时,按需加载 chrome-use skills get core/connection。普通点击和表单操作已包含在 core 中。
当任务需要用户此刻正看着的那个窗口——他们真实的、已登录的 会话,而不是一个全新的空白浏览器时,走扩展连接(extension connect)。它接管用户真实的 Chrome: 零确认、零 token、无 headless 痕迹,是所有连接方式里反检测等级最高的一档。
连接链路只有四站:chrome-use CLI → 每会话一个的守护进程 → Chrome 为扩展拉起的中继(relay)
→ 浏览器里的 ab-connect 扩展。扩展用 Chrome 自带的调试协议驱动页面,所以不必开远程调试端口。
每一站说什么协议、状态放在谁手上,见 它怎么工作。
本机 agent 侧栏
在扩展侧栏中选择本机 Codex、Claude Code、OpenCode 或 Pi,沿用已安装 CLI 的登录。完整使用说明已独立成章:插件对话。
一次性安装
扩展连接只需配置一次。先注册原生消息宿主(native-messaging host),再装上 chrome-use 扩展。
# 1. 注册原生消息宿主
$ chrome-use extension install
2. 安装 chrome-use 扩展。 最省事、且重启后依然稳定的方式是从 Chrome Web Store 一键 Add to Chrome:
com.leeguoo.chrome-use.connect)。
它会让 Chrome 进入「由贵单位管理」状态:「使用安全 DNS (DoH)」被停用并锁死
(#187),扩展也会标成「由管理员安装」、
没有手动更新/删除按钮(#186)。
商店安装完全不需要它——加 --no-profile 即可跳过;已经批准过的用
profiles remove -identifier com.leeguoo.chrome-use.connect 退出(Chrome 会一并卸载它装的扩展,
再从商店装回来即可)。
chrome://extensions → 打开 Developer mode → Load unpacked →
选 extensions/ab-connect。注意:Load-unpacked 装的扩展在 Chrome 重启后可能被禁用,
所以无人值守的场景优先用商店版。
自动连接:open 即接管
装好扩展后,普通的 chrome-use open <url> 会自动通过扩展 relay 连接。
auto_connect_cdp 优先选用 live relay,而不是裸的
--remote-debugging-port,所以 Chrome 136+ 那个「是否允许远程调试?」的授权弹窗
永远不会出现。chrome-use extension connect 是同一条路径的显式写法。
# 装好扩展后,open 自动走 relay 接管真实 Chrome
$ chrome-use open "https://example.com"
# 同一条路径的显式写法
$ chrome-use extension connect
--launch 即可,见下文。
profile 里要开着窗口
chrome-use 要求 profile 已经开着窗口,自动化时所有 AI 会话共用一个后台专用窗口,人使用自己的窗口。没有窗口时它会停下并报
profile not open(错误码 profile_not_open):先在那个 profile 里打开一个窗口,再重跑。
判断不了有没有窗口时报 profile window unavailable(profile_window_unavailable)。
判断不了就什么都不创建,这两个错误都不会自动重试。第一个标签页清理相关的错误码见故障排查。
多个 Chrome profile:看清是哪一个,然后选它
relay 绑定的是当前正在和原生宿主通信的那个 profile 的扩展 worker。 如果某个站点回来显示未登录,先确认接管的是不是对的 profile,再下结论说登录丢了。
# 列出所有已连接的 profile(有 identity 权限则显示邮箱,否则显示稳定 id,标注默认项)
$ chrome-use browsers
# 把「本次 session」钉到指定 profile —— 按 session 粘滞,不同 agent 互不干扰
$ chrome-use --browser "me@example.com" snapshot
# 查看当前正在驱动的 profile
$ chrome-use extension status
$ chrome-use doctor
status、extension status 和 doctor 的中继检查使用一个诊断连接读取 ABExt.state,总预算为 10 秒;收到错误回复时,在同一连接上回退到 ABExt.inspectTab,不发送 debugger 命令。debugger 摘要被动统计最近十分钟的已回答命令(包括非超时错误)和超时次数;完整窗口显示“in the last 10 min”,否则显示“since the extension worker started <age> ago”;不足 120 秒使用整数秒(如“45s”),否则使用整数分钟(如“3 min”)。没有样本时显示“not exercised”,旧扩展没有健康数据时明确说明。计数使用有界的一秒桶,service worker 重启后清空。命令持续失败时,在 chrome://extensions 重新加载 chrome-use 扩展或重启 Chrome。
新原生主机会确认诊断连接并跳过 attachAll。仍在运行的旧主机会像以前一样执行一次 attachAll;诊断提示会建议升级后重新加载扩展以启动新主机。疑似重复扩展检测读取 sidecar 身份,并发执行最多一秒的 TCP 存活检查,不进行 WebSocket 握手。同账号、同浏览器且扩展 id 不同不能证明属于同一 Chrome profile;只有确认同一 profile 安装了两份时才禁用其中一份。
JSON 健康摘要只包含 transportResponsive、hostDiagnostic、debugger 和 extensionHealth(windowMs、workerAgeMs、answered、timedOut、lastTimeout,或 null),保留 connectedProfiles 和 warnings。extension status --json 的 relayUp 仍表示存在中继地址,status --json 则表示收到扩展传输回复。旧扩展在有已发布新版时更新扩展;当前扩展比 CLI 预期更新时运行 chrome-use upgrade。仅 installType: development 表示开发版。macOS/Linux 上 doctor 显示一分钟负载和 CPU 数;负载超过 CPU 数两倍时警告,并在 relay/CDP 超时错误中附带负载提示。
--browser <id|email> 把本次 session 钉到某个 profile:session 的 daemon
在首次连接时绑定,每个 session 可以选不同的 profile,所以并发的多个 agent 不会互相抢。
错的 profile 上显示未登录 ≠ 登录丢失——先跑 browsers,再带上正确的 --browser 重跑。
让规则替你选:ChooseBrowser
「哪个站点用哪个账号」这件事,你心里本来就有数,只是每次都要用
--browser 再说一遍。
ChooseBrowser 是一个 macOS 链接路由工具,
它把这份映射存了下来;装了它之后,open 在你没显式指定
--browser 时会按你写的规则选 profile,并说明来源。
$ chrome-use open https://github.com/my-org/repo
profile: Davian (Profile 14, …) — a ChooseBrowser rule routes this site there
(github.com|/my-org*). Override with --browser <id|email>, or skip with --no-choosebrowser.
只读,没装的话完全无感——没有规则文件就不改变任何行为、也不打提示。
规则是硬约束,chrome-use 不会把站点开到别的 profile 里。规则指向的 profile 没连上时,
命令直接失败,并给出 chrome-use connect --browser <profile>(会在那个 profile
里开一个窗口,先问用户)。当前 session 已经绑定在另一个 profile 上时,命令同样失败:
换一个新的 --session(它会选规则指定的 profile),或者加
--no-choosebrowser 在已绑定的 profile 里打开。显式 --browser
和配置文件里的路由仍然优先。这条检查同样覆盖 batch 的每一步(一个 batch 需要两个 profile 时,任何一步都不会执行)、MCP 工具调用和 script 步骤。
规则的 key 同时对上几个 profile 时拒绝执行;规则指向的 profile 在本机已不存在时只给警告。
chrome-use doctor 会逐条列出规则,以及它指向的 profile 是否已连接。
规则排在「猜最近聚焦的窗口」之前——规则是你写下的意图,比从你正看着哪个窗口做的推断可信。
只有 open / goto / navigate / tab new <url> 这类会导航的命令才查它;
snapshot、click 作用在会话已经打开的东西上,不查。
反过来也可以:在显式 --browser 后面加 --remember,
导航成功之后它会请求 ChooseBrowser 把这个域名长期指向那个 profile,
下次就不用再传 --browser 了。
$ chrome-use open https://github.com/my-org/repo --browser work@example.com --remember
· asked ChooseBrowser to route github.com to work@example.com from now on — confirm in
its dialog. Nothing is saved unless you do.
这是一次提议,不是一次保存。 ChooseBrowser 每次写入都会弹窗让你确认,并且刻意不给成功回调—— 任何进程都能打开 URL scheme,静默写入意味着别的工具可以悄悄把你的 银行域名指到一个你不看的浏览器上。所以 chrome-use 只能说「已请求」, 结果以那个弹窗为准。取消了就什么都不会发生。
只写域名、不写路径:规则如果绑在这条命令碰巧打开的那个路径上,翻到站内下一页就不生效了。
只在你显式传了 --browser 时才提议——
把我们自己猜出来的 profile 写成永久规则,等于把一次推断变成你从没说过的长期决定。
请求要是构造不出来(命令不导航、profile 没有登录账号、账号不在 Chrome 注册表里……),
它会在导航之前就退出并说明原因,而不是发一个会被静默丢弃的请求。
需要 ChooseBrowser ≥ 0.2.1(注册了 choosebrowser:// 的版本,chrome-use doctor 会报装的是哪个);旧版本上没有程序处理这个链接,
chrome-use 会明说没有提议成功,而不是当作发出去了。
macOS 链接路由器,chrome-use 作者出品。⌘1–⌘9 选浏览器,⌥↵ 记住一次,它还会学你的偏好。无账号、无跟踪。7 天免费试用,US$4.99 买断,3 台 Mac。
公证过的 .dmg,需要 macOS 26 或更高。chrome-use 不依赖它,不装一切照常。
--launch vs --profile auto
--launch 会开一个隔离的空白测试 profile——没有 cookie、没有登录、没有扩展
(所以扩展 relay 路径是关闭的)。它的窗口在 Chrome 的 profile 菜单里标为
chrome-use (<session>),让盯着桌面的人一眼看出这个窗口属于哪个 session。
如果一个 launched session 需要更多东西:
去掉 --launch,改用 --profile auto(复用用户的真实 Chrome profile),
或一次性设置 AGENT_BROWSER_PROFILE=auto 让之后每次调用都默认这么做。
--launch --args "--load-extension=<dir>"。
万一真弹出「是否允许远程调试?」
不要反复重试——每次重试都会再弹一次。此时只有两种可能:
-
你在用旧版。 避免这个弹窗的 relay 优先逻辑早已发布很多个版本了;如果还撞得到,
说明你的
chrome-use太老,升级后重试:
$ curl -fsSL https://raw.githubusercontent.com/leeguooooo/chrome-use/main/install.sh | sh
# 若 which 显示多份安装,旧的 npm/pnpm 副本可能在遮挡新版
$ which -a chrome-use
$ npm rm -g chrome-use # 或 pnpm rm -g chrome-use,让 install.sh 版本胜出
- 扩展 / relay 没起来。 让用户装商店版扩展(上面那个一键链接);装好后 relay 会持续在线, 这个弹窗再也不会回来。
relay 掉线:CLI 会自愈
如果某条命令突然报「couldn't reach your Chrome」/「relay … failed」——通常是 MV3 service worker 被挂起, 或两个 agent 在共用一个 relay——CLI 现在会自愈:它会等 worker 的 keepalive 把 relay 拉活 (约 25 秒)并重试一次,所以大多数掉线你根本感知不到。如果某条命令确实把错误抛出来了:
- 直接重跑这条命令——到那会儿 relay 通常已经重连好了。
- 还不行:
chrome-use status(无需 daemon 的 CLI、扩展、中继、profile 与会话总览)→chrome-use extension connect(重新 attach)→ 再重试。 CLI 会自动注册原生宿主,如果扩展从没装过还会自己打开商店页面——你不用手动跑extension install。 - 绝不要让用户用
--remote-debugging-port退出/重启 Chrome 来恢复掉线的 relay—— 那会丢掉他们的所有标签页,也彻底破坏了扩展路径。 chrome-use reconnect是extension connect的友好别名——无需任何重装, 就把 session 重新绑定到运行中的 Chrome。- 浏览器完全恢复不了? 不要干等一张截图——退回到非视觉的验证方式:
get text/eval,或用curl/WebFetch读已部署的页面。 通过 DOM/HTML 或 live URL 确认一个改动是正确的结果,不是失败。截图留给你真正要报告给用户的视觉检查。
--session 有自己的标签组、只驱动自己的标签页。
给每个 agent 一个不同的 --session 让它们并行跑,不用一个个来。
OAuth / SSO 跳转现在直接就能过
一次登录 handoff(GitHub/Google OAuth、SSO)会把标签页跨进程导航,这过去会遗弃旧 session、
让下一次读取报「stale sessionId」失败。relay 现在会跨这次跨进程导航自动重新 attach opener,
并在新进程稳定期间短暂重试读取,所以 snapshot/screenshot/eval/get
在整个 handoff 期间都能正常工作,「Sign in with Google」/ OAuth 弹窗登录能端到端走完。
严格的多 agent 隔离
每个连接的 --session 都会拿到自己的一个彩色 Chrome 标签组(以 session 命名),
并只驱动它自己的标签页——多个 agent 共享同一个真实浏览器而不串话,用户自己的标签页永远不会被编组。
CDP 驱动页面时不会移动用户的鼠标/键盘,所以不会跟他们抢控制权。
--session / AGENT_BROWSER_SESSION 时,chrome-use 会自动派生一个按 agent 区分的默认值——
cu-<repo>-<id>,其中 <id> 是稳定的、按 agent 区分的终端/agent 环境 id
(CMUX_SURFACE_ID、TERM_SESSION_ID、ITERM_SESSION_ID、TMUX_PANE …)的短哈希。
所以同一个 repo 里的两个 agent 默认拿到不同的标签组,不再互踩活动标签页。纯 shell 里没有这些环境变量时,
回退到共享的 default。随时可覆盖:传 --session <name>,或把它设成相同的值让多个 agent 刻意共享一个标签组。
(AGENT_BROWSER_* 这套前缀沿用自上游项目,来历见 血统与上游。)
一个 session(走 relay)只驱动它自己创建或显式 adopt 的标签页。你自己的动作打开的弹窗——
比如点「Sign in with Google」弹出的 OAuth 账号选择窗口——会被跟随、可作为你 session 的一部分来驱动
(切过去驱动那个选择器)。但它不会收编用户已有的标签页、其他 agent 的标签页,或无关的弹窗
(用户自己开的登录窗口是用户的)。tab list 可能为恢复目的显示其他标签,但会将它们标记为
foreign,不能直接切换或关闭。要驱动既存标签必须先显式 adopt;adopted 标签仍属于用户,
当前 session 不能关闭。同名 session 连接同一浏览器端点重启后仍会恢复 created 所有权,因此中断的清理可以安全继续。
用户页面上不会出现调试横幅
adopt 的)attach Chrome 调试器,
绝不对用户自己的标签页 attach——所以 Chrome 那条「chrome-use started debugging this browser」的横幅
永远不会盖住用户正在用的页面(它只出现在被 attach 的标签页上,而 agent 的都是后台标签页)。
无需重启 Chrome,完全无缝。扩展 0.5.19 起,agent 标签页可以在空闲一段时间后自动释放调试器、横幅消失,
下一条命令再透明地重新 attach。默认关闭(0 = 从不释放),在扩展选项页的「Release idle tabs after」里设置时长即可开启。
session daemon 更长周期的空闲回收也会保留真实 Chrome 中由 agent 创建的标签页,包括当前 URL 和页内状态;
显式执行 close 或 session stop 仍会正常清理这些标签页。
空闲退出后,stop 会重新发现原浏览器并校验所有权;无法匹配时保留记录并报错,需用原连接选项重连后执行 close。
relay 的顶层导航现在优先走 Chrome 浏览器级标签页 API,更接近普通手动导航,而不是先用 CDP
Page.navigate。如果站点仍在八秒内向同一 URL 连续提交四次,下一条命令会明确报告重载环并给出恢复建议。
可改用稳定的深链接,或用 tab adopt 接管一个已经渲染好的标签页来保留现场。
读取用户已经打开的标签页:adopt
需要读一个用户已经开着的标签页?用 chrome-use adopt <url-substring|targetId>——
它会跨标签组找到那个已存在的标签页(用户自己的,或另一个 session 的)并驱动它,不会新开标签页。
没匹配上时它会报错并列出它能看到的标签页。这是穿过上面那层隔离的显式、opt-in 方式(它会把被收编的标签页打上你 session 的标签组)。
# 收编用户正看着的那个标签页,再对它做只读提取
$ chrome-use adopt "claude.ai/design"
$ chrome-use snapshot
$ chrome-use get text
反检测等级排名
这个真实的、已登录的 Chrome(扩展连接) > 一个有头的 launched 浏览器 > headless(禁止)。 一个真正的人类浏览器完全没有 headless / 自动化的破绽,所以任何对反-bot 敏感的任务都优先用它。
默认静默运行
驱动用户的真实 Chrome 时,agent 完全在后台工作——新标签页开出来时不聚焦,agent 从不强制把某个标签页顶到前台。 焦点是模拟的,所以页面照常渲染、计时器照常跑,不会被后台节流。你什么都不用做;只是别指望用户的视图跟着你跑。
document.visibilityState 始终是 'hidden'——焦点模拟改不了它,CDP 也没有能改它的开关。
绝大多数页面不在乎。例外是那些刻意按可见性决定要不要工作的页面(不让后台标签页续着设备租约、视频播放器、
会暂停的游戏):它们渲染的是「后台分支」,于是 snapshot 可能是空的,你以为会有的控件不在或用不了。
现在树接近为空且标签页隐藏时,snapshot 会把这件事说出来。遇到时用
chrome-use bringToFront 刻意把它顶到前台再读一次——这也是唯一会让用户视图跟着你跑的操作,
所以要刻意用,不要顺手用。
行为层反-bot:拟人化输入
--humanize off|fast|human(或 AGENT_BROWSER_HUMANIZE)给点击、打字、滚动加上拟人节奏;默认 off,
一个每次导航都会跑的检测器会把被 Akamai/PerimeterX/DataDome 守卫的页面自动升到 human。
轨迹参数、节奏与调优见 反检测与隐身。
Cloudflare 通关:solve 一次,复用
通过一次 Cloudflare 挑战会铸出一个绑定 IP + User-Agent 的 cf_clearance cookie,复用同一出口 IP 和 UA
就能在过期前跳过挑战;驱动用户真实 Chrome(relay)会原生持久化它。解之前先跑 chrome-use cf-status
(别名 cf、clearance)做预检,避免重复解已经过了的挑战。完整流程、reissue 判定与 cookie 读取见
反检测与隐身。
密码管理器的内联菜单锁住标签页
聚焦登录框或卡号框时,Bitwarden、1Password 这类密码管理器会在旁边弹出内联填充菜单。这个菜单是它们自己扩展的 frame,只要它还在,Chrome 就拒绝这个标签页上的所有调试器命令(debugger_access_denied)。报错会点名本机 Chrome 里装了哪个密码管理器。
标签页一被隐藏,菜单就会关掉。对 session 自己开的标签页,chrome-use 会自己处理,不需要调试器命令:它短暂显示一个自己的空白页(后台标签页会先显示一下再隐藏),结束后原来在前台的标签页回到前台。如果它是你自己窗口里的后台标签页(agent 标签页默认开在这里),chrome-use 不动你的窗口,而是在它的 agent 窗口里激活一个空白页:Bitwarden 每次有标签页被激活时,都会关掉不在前台的标签页上的菜单。这个 agent 窗口在本次 session 里一直最小化:第一次最小化时会出现约一秒,之后不再出现。你正在看的那个标签页留给你自己处理(在里面按 Esc);密码库锁着、或是别的密码管理器时可能不会这样关,报错会说明。之后在安全的前提下自动重试(读取、fill、select 等;如果 fill 的值已经在字段里,就直接确认,不再重填)。点击、按键这类不能重试的命令,chrome-use 会在执行前先检查,发现被挡就先把菜单关掉再执行。实在关不掉时,报错会说明原因和下一步;标签页和已填内容都还在,不要因此关闭标签页或重启 Chrome。想避免它:这类字段用 fill 而不是 type --key-events,或者在密码管理器里对该网站关闭内联菜单。
相关页面
--session、标签组、按 agent 默认与并发。
OAuth/SSO handoff、复用真实登录会话。
扩展连接 vs 其他浏览器自动化方案的取舍。
relay 掉线、授权弹窗、profile 选错的自查。
原生会话服务
原生服务独立于扩展连接,保留 Codex、Claude Code、OpenCode 或 Pi 的 CLI 会话。断线后只读取新增事件,不重发旧消息;失败或停止后暂停消息队列。浏览器工具绑定 profile 和会话,沿用现有 chrome-use 链路,不为显示进度启用另一条浏览器控制通道。恢复中的任务结果未确认时需先检查。合成协议测试不代表真实账号、页面和隐身检测已通过。