mcpField
C
cdpilot

cdpilot

本地服务
cdpilot.ndr.ist浏览器自动化322 周前更新

关于 cdpilot

cdpilot 是一个零依赖的命令行浏览器自动化工具,直接通过原始 CDP 控制浏览器,无需 Puppeteer、Playwright 或 Selenium。适合 AI 代理与开发者在本地执行浏览器操作。

主要功能

  1. 01零依赖,基于 CDP over HTTP 实现
  2. 02提供 70 余条命令,覆盖导航、交互与截图
  3. 03每个项目使用独立的浏览器实例与端口
  4. 04支持 iframe 内元素的定位
  5. 05支持扩展开发所用的 Chrome for Testing

适用场景

  1. 01通过命令行快速打开页面并截图
  2. 02在隔离的浏览器配置中执行自动化脚本
  3. 03为 Claude Code 等工具提供浏览器操作能力

MCP 相关

该项目提供 MCP 服务(npx cdpilot mcp),向 MCP 客户端暴露其浏览器命令,供 AI 代理调用。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"mehmetnadir-cdpilot": {
"command": "npx",
"args": [
"-y",
"cdpilot"
]
}
}
}
启动命令npx -y cdpilot

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmcdpilot0.9.4

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

cdpilot

从终端实现零依赖的浏览器自动化。一条命令,全面掌控。

npm version npm downloads License: MIT Node.js MCP Compatible cdpilot MCP server

cdpilot 演示

快速开始

npx cdpilot launch    # Start browser with CDP
npx cdpilot go https://example.com
npx cdpilot shot      # Take screenshot

无需配置文件,无需样板代码。只需运行 npx 即可开始。

为什么选择 cdpilot?

AI Agent 和开发者需要一种开箱即用的浏览器控制方式:

  • 零配置 — npx cdpilot launch 即可启动隔离的浏览器会话
  • 零依赖 — 无需 Puppeteer、Playwright 或 Selenium。通过 HTTP 使用纯 CDP
  • 70 多条命令 — 支持导航、点击、输入、截图、网络、控制台、无障碍、视频理解、渐进式反机器人韧性等
  • 适合 AI Agent — 专为 Claude、GPT、Gemini 及任何大模型工具调用工作流设计
  • 隔离会话 — 不会影响你的个人浏览器。cdpilot 使用独立配置运行
  • 可视化反馈 — 绿色发光叠加层、光标可视化、点击涟漪和按键显示,让你随时了解自动化进度
  • 多项目隔离 — 每个项目都会自动获得独立的浏览器实例和端口,互不冲突
  • AI 控制警告 — 自动化运行期间,将鼠标悬停时会出现红色提示通知
  • 隐私优先 — 所有操作均在本地运行。数据不会离开你的设备
浏览器选择(根据工作负载自动选择)

cdpilot 会根据你的操作选择合适的浏览器。auto(默认)采用双轴策略 — 扩展工作负载 × 平台稳定性:

你的工作负载自动选择顺序
已注册扩展(ext-install)vivaldi → brave → edge → chromium → chrome(→ Chrome for Testing,如果已安装)
无扩展(纯自动化)chrome → vivaldi → edge → chromium → brave

可随时覆盖:

cdpilot browser            # show current pick + reason
cdpilot browser vivaldi    # pin to Vivaldi
cdpilot browser chrome-for-testing   # pin to Chrome for Testing (after installing it, below)
cdpilot browser auto       # restore smart default

为什么要区分?

  • Chrome 137+ 会静默忽略非打包扩展的 --load-extension(无错误、无警告)——Google 已从品牌版 Chrome 构建中移除此功能 (说明)。 已验证 — chrome://extensions 显示 0 个项目。
  • Vivaldi、Brave、Edge、Chromium 和 Chrome for Testing 均支持 --load-extension(已测试)。
  • 在 macOS 26 (Tahoe) 上,Brave 1.89 会在运行约 7 分钟后稳定崩溃 (ThreadPoolForegroundWorker 中出现 SIGTRAP)。在修复版 Brave 发布前,cdpilot 会检测操作系统并自动降低 Brave 的优先级。

每个浏览器都有独立的配置文件(如 ~/.cdpilot/.../profile-vivaldi), 因此切换浏览器不会导致偏好设置损坏。

扩展开发:Chrome for Testing

如果你直接针对 Chrome 开发扩展,请安装 Chrome for Testing(CfT)—— Chrome 团队提供的带版本号、不会自动更新的 Chrome 构建版本,专为自动化设计, 同时仍支持加载未打包的扩展:

cdpilot browser install chrome-for-testing                    # latest Stable
cdpilot browser install chrome-for-testing --channel beta     # stable | beta | dev | canary
cdpilot browser install chrome-for-testing --version 154      # a milestone, or a full version (154.0.8037.57)
cdpilot ext-install ./my-extension/                           # register your unpacked extension
cdpilot browser status                                        # shows the CfT version and path
  • 仅在执行该命令时下载。 这是一次性下载的约 150–190 MB zip 文件(mac-arm64 版本 154.0.8037.57:191,429,663 字节);cdpilot 不会自行获取该文件。此构建版本来自官方 CfT JSON 端点 (last-known-good-versions-with-downloads.json、按版本和里程碑划分的文件)。 这些文件仅列出 URL,不含哈希值,因此下载内容会根据服务器的 Content-Length 和 x-goog-hash md5 进行校验;zip 文件的 SHA-256 会被记录。
  • 文件会解压到 $CDPILOT_HOME/browsers/chrome-for-testing/<version>/(在 macOS 上, 只会清除该目录的隔离属性),并记录在 installed.json 中。
  • 自动用于扩展开发: 注册了开发扩展期间,选择品牌 Chrome(cdpilot browser chrome, 或者在 Chrome 是唯一支持扩展的选项时选择 auto)会使用 Chrome for Testing,并在 stderr 输出一行说明。若尚未安装 CfT,在 Chrome 上执行 ext-install 会打印安装命令, 并继续提供 Vivaldi/Brave 作为替代选项。cdpilot browser chrome-for-testing 始终会选择它。 不会替换显式设置的 CHROME_BIN。
  • 它使用 cdpilot 常用的按项目隔离配置文件(profile-cft)。
  • 它用于扩展开发和测试,不是隐身浏览器。 cdpilot 不会声称它能规避反机器人检测; 如需此类用途,请使用你常规的浏览器设置。
  • Linux(Ubuntu 23.10+): AppArmor 会阻止非特权用户命名空间,而 CfT(与发行版的 Chrome 软件包不同)没有允许使用这些命名空间的配置文件,因此会在启动时退出。cdpilot 会打印此提示;运行 sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 即可允许使用。

安装

# Use directly (no install needed)
npx cdpilot <command>

# Or install globally
npm i -g cdpilot

要求: Node.js 18+、Python 3.10+,以及以下浏览器之一:Brave Browser、Google Chrome 或 Chromium。(首次启动时,预检向导会自动安装 Python websockets 模块。)

首次设置
npx cdpilot setup     # Auto-detect browser, create isolated profile
npx cdpilot launch    # Start browser with CDP enabled
npx cdpilot status    # Check connection
Claude Code 插件市场

将 cdpilot 的 MCP 服务及其技能直接安装到 Claude Code 中,无需编辑 .mcp.json:

/plugin marketplace add mehmetnadir/cdpilot
/plugin install cdpilot@cdpilot

这会注册 cdpilot MCP 服务(npx cdpilot mcp)以及一项简短技能,指导 Claude Code 何时以及如何使用 cdpilot 的命令。请参阅 .claude-plugin/marketplace.json 和 plugins/cdpilot/。

MCP Bundle(.mcpb)

对于支持一键安装本地服务的 MCP 客户端(Claude Desktop 等),请下载附在 最新版本中的 .mcpb 文件并 打开,或自行构建:

npm run build:mcpb   # writes cdpilot.mcpb at the repo root

此 Bundle 仍需要在运行它的机器上安装相同的运行环境:Node.js 18+、Python 3.10+,以及 Brave/Chrome/Chromium。请参阅 manifest.json 了解 Bundle 的 MCP Bundle 清单 (规范)。

从 0.4.x 升级到 0.5.0 — 请先阅读

有一项不兼容变更,其余都是新增内容。

不兼容变更 — 视觉反馈默认关闭。 绿色发光边框、动画假光标、点击波纹和按键显示,让 cdpilot 在每个页面上的表现都像个生手。现在这些功能改为选择启用:

cdpilot show on     # restore the old visual feedback layer
cdpilot show off    # default since 0.5.0

MCP 服务的持久发光流程(CDPILOT_MCP_SESSION=1)保持不变 ——依赖会话期间可见反馈的 AI Agent 仍会自动看到这些反馈。只有直接使用 CLI 的用户会感受到变化。

0.5.0 新增功能(无需迁移):

  • cdpilot dismiss — 在 LLM 聊天注册墙上,启发式地自动点击“保持退出登录 / 不用了”等按钮。
  • cdpilot adaptive on — 在受 CAPTCHA 保护的主机上自动切换到 stealth 模式,并按主机持久保存状态。
  • cdpilot cookies save/load — 将 Cookie 导出/导入为 JSON,以便在多次运行间复用 CF/DataDome 验证状态。
  • cdpilot context create/list/close + CDPILOT_TARGET — 创建隔离的浏览器上下文,在单个浏览器内实现真正的并行自动化。
  • cdpilot fast / cdpilot show — 集中管理计时和视觉开关。
  • 纯性能优化:页面加载后等待时间从 1500ms 缩短至 300ms、scrollIntoView 立即执行、WebSocket 连接池、/json TTL 缓存。

完整列表及原因说明请参阅 CHANGELOG.md。

命令

导航与内容
cdpilot go <url>              # Navigate to URL (alias: open <url>)
cdpilot content               # Get page text content
cdpilot html                  # Get page HTML
cdpilot shot [file]           # Take screenshot (PNG)
cdpilot pdf [file]            # Save page as PDF
交互
cdpilot click <selector>      # Click element
cdpilot type <selector> <text># Type into input
cdpilot fill <selector> <val> # Set input value (React-compatible)
cdpilot submit <form>         # Submit form
cdpilot hover <selector>      # Hover element
cdpilot keys <combo>          # Keyboard shortcut (ctrl+a, enter, etc.)
cdpilot scroll-to <selector>  # Scroll element into view
cdpilot drag <from> <to>      # Drag and drop

如果真实鼠标点击(在框架内,或使用 --entropy=on)的目标在按住鼠标按钮期间发生移动或被遮挡,脚本不会再次点击:click 会打印 Pressed (released elsewhere, not clicked): …,并以 退出码 3 结束(已按下,但释放时目标未命中,未点击;1 仍表示“错误”)。如果页面在 mousedown 时替换了目标或导航离开了目标,则会打印 Pressed (the page replaced or left it, not clicked): …,并以退出码 0 结束。MCP(browser_click、browser_smart_click)会返回 isError: false,首行内容为 {"clicked": false, "reason": "moved"|"gone"|"unknown"}。batch 和 run 会完成每个步骤,然后在任一步骤失败时以退出码 1 结束;否则,如果有点击未成功,则以退出码 3 结束;否则以退出码 0 结束。

定位 iframe 内的元素

银行卡表单(Stripe/iyzico 风格)、嵌入式登录组件和 reCAPTCHA 复选框都位于 <iframe> 内。使用 >>> 在元素选择器前指定框架链,或传入 --frame:

# Payment-style page: the card fields are inside <iframe id="card" title="Secure card payment">
cdpilot fill  "iframe#card >>> input[name=cardnumber]" "4242424242424242"
cdpilot type  --frame "#card" "input[name=cvc]" "123"
cdpilot click "iframe[title='Secure card payment'] >>> button#pay-btn"

# Nested frames: outermost first
cdpilot click "iframe.checkout >>> iframe.card >>> button"

# --frame <selector|index|url-substring>, nestable with >>>
cdpilot click --frame 0 "button.submit"                   # first iframe (same order as `frame list`)
cdpilot fill  --frame "url=js.stripe.com" "input[name=cardnumber]" "4242424242424242"
cdpilot frame list --frame "#card"                        # iframes inside that frame
cdpilot frame eval --frame "#card" "document.title"       # runs in the frame's own page context
  • 适用于 click、fill、type、submit、hover、dblclick、rightclick、 smart-click、smart-fill、smart-select 和 frame list|eval|shadow。
  • 帧跳转可以是 CSS 选择器、从 0 开始的索引、name/id,或 url=<src substring>。--frame 也接受不带前缀的 src 子串。 引号内或 [...] 中的 >>> 会按字面处理。若选择器匹配的是一个 包裹 iframe 的元素(Stripe 的 #card-element),则会进入其中的 iframe,并在 stderr 上说明: note: '#card-element' is not an iframe; using the iframe inside it。
  • 已包含 >>> 的选择器和文本仍可正常使用:如果第一个 >>> 之前的部分在页面中找不到 iframe,或某一段为空(click "Next >>>"),则会照原样使用整个字符串,与之前完全相同。如果这样也失败,stderr 会输出一行说明: note: 'Home' matched no iframe; used the selector as written。 --frame 不会回退:找不到指定帧时会报错(退出码为 1)。
  • 对于 smart-click / smart-fill / smart-select,第一个 >>> 之前的部分只有在看起来像选择器(包含 #、. 或 [, 或以 iframe/frame 标签开头)或为 url=… 时才会被视为帧; 普通词语仍视为文本。即使 <main> 元素中包含 iframe, smart-click "Main >>> Settings" 仍会点击页面上名为 "Main >>> Settings" 的链接。帧索引或不带前缀的名称请使用 --frame。
  • 同源和跨源帧均可使用,包括进程外 iframe(站点隔离):cdpilot 通过 CDP 解析每次跳转(DOM.describeNode → 帧 ID → 帧的执行上下文,或通过 Target.attachToTarget 使用扁平会话连接进程外帧),绝不会通过 contentDocument,因为浏览器会阻止跨源访问。
  • 在帧内,click 和 smart-click 会发送真实鼠标输入 (isTrusted: true),与 hover、dblclick、rightclick 和 --entropy=on 点击一样;如果元素没有边框框,则会回退到脚本点击。 鼠标输入会在页面坐标中分发:系统会自动应用每个帧在页面中的偏移量和缩放 (transform: scale()、zoom),让浏览器将命中测试定位到正确的帧。按下鼠标前,cdpilot 会检查该点(沿途每个文档中都调用 elementFromPoint);如果有内容遮挡目标(例如 Cookie 横幅),则会改用脚本点击目标,并在 stderr 上输出一行说明(note: … is covered by div#cookie at the click point; used a script click)。cdpilot 自带的输入拦截器(show on、 MCP 会话)只会放行 cdpilot 自己的点击,仅限该次点击。
  • smart-click / smart-fill / smart-select 会先在页面中查找, 并比较经过空白折叠的文本(&nbsp; 和换行符都按一个空格处理)。如果页面上某个已启用元素的文本或标签包含完整查询内容,就会使用该元素。如果页面上唯一符合条件的元素都已禁用,命令会像以前一样失败(no enabled element matches …),且不会查找帧。否则会按广度优先顺序搜索可见帧,查找完整查询匹配项(最多 20 个帧,所有搜索 CDP 调用总计限时 2 s),并在 stderr 上报告匹配结果: smart-click: matched inside frame iframe#card (https://…)。搜索只会查找,不会点击或输入;随后命令会在选定的帧中执行一次。若没有匹配的帧,则会像以前一样使用页面上的部分(词语)匹配。超过 2 s 时: smart-click: frame search stopped after 2s (3 of 7 frames);届时尚未响应的帧不会被触及。
  • smart-fill 和 smart-select 只会自动搜索与页面同源的帧,确保输入值不会意外填入第三方帧(广告、聊天或支付组件);如需访问跨源帧,请使用 >>> 或 --frame。smart-click 会搜索所有可见帧。
  • 不带 --frame 的 frame list 会像以前一样打印相同的列表。
调试
cdpilot console [url]         # Capture console logs
cdpilot network [url]         # Monitor network requests
cdpilot debug [url]           # Full diagnostic (console+network+perf+shot)
cdpilot perf                  # Performance metrics
cdpilot eval <js>             # Execute JavaScript
cdpilot eval-batch <json>     # Run N JS expressions in 1 roundtrip (5-30x faster)
# Example: read 4 DOM values in a single CDP roundtrip instead of 4
cdpilot eval-batch '["document.title","location.href","document.links.length","document.images.length"]'
# → [{"ok":true,"value":"..."}, {"ok":true,"value":"..."}, ...]
性能
cdpilot block                                # Show status
cdpilot block on                             # Enable (default preset: images+fonts+ads)
cdpilot block off                            # Disable
cdpilot block preset images,fonts,ads,media  # Set patterns from named presets
cdpilot block patterns '*.png' '*.woff2'     # Custom URL patterns
cdpilot block clear                          # Drop all patterns

隐身注意事项: block 会改变指纹特征——真实浏览器会加载 图片、字体和分析脚本。Cloudflare 级别的机器人检测器会注意到缺失的 请求。对于隐身/反机器人目标,请保持 block 关闭;对于已知安全的内部网站, 如果速度比伪装更重要,则将其开启。

cdpilot fast                       # Show status (effective auto-wait ms)
cdpilot fast on                    # Auto-wait 5s → 2s, less idle padding
cdpilot fast off                   # Back to defaults
CDPILOT_WAIT_MS=1000 cdpilot click # Per-command override (env wins over fast mode)
cdpilot show                       # Show status (visual feedback on/off)
cdpilot show on                    # Re-enable glow border + cursor + ripples + keystrokes
cdpilot show off                   # Default since 0.4.4 — quiet, professional output

0.4.4 中更改了视觉反馈的默认设置——旧动画(绿色光效、 移动光标、点击涟漪)会让每个操作看起来都像是新手在操控屏幕。现在可通过 cdpilot show on 选择启用。MCP 服务的 持续光效流程(CDPILOT_MCP_SESSION=1)不受影响——依赖会话期间可见反馈的 AI Agent 仍会自动看到这些效果。

标签页管理
cdpilot tabs                  # List open tabs
cdpilot new-tab [url]         # Open new tab
cdpilot switch-tab <id>       # Switch to tab
cdpilot close-tab [id]        # Close tab
cdpilot close                 # Close active tab
网络控制
cdpilot throttle slow3g       # Simulate slow 3G
cdpilot throttle fast3g       # Simulate fast 3G
cdpilot throttle offline      # Go offline
cdpilot throttle off          # Back to normal
cdpilot proxy <url>           # Set proxy (legacy single-URL form)
cdpilot proxy off             # Remove proxy

# v0.7.0: named pools (BrightData, IPRoyal, Anchor, etc.)
cdpilot proxy add brd "http://USER:[email protected]:22225" --geo us
cdpilot proxy add ipr "http://USER:[email protected]:12321" --sticky
cdpilot proxy use brd         # Activate one pool
cdpilot proxy list            # Show pools (credentials redacted)
cdpilot proxy show [<name>]   # Active or named pool URL (redacted)
cdpilot proxy remove <name>   # Drop a pool
TLS 指纹(v0.8.0)
cdpilot tls-check                        # Probe JA3/JA4/H2 via tls.peet.ws
cdpilot tls-check --service browserleaks # Alternate echo
cdpilot tls-check --json                 # Raw JSON

已知限制: v0.8.0 附带了探测工具(tls-check),但没有内置 TLS 修复方案。 目前没有基于 Chromium、已修正 TLS 且以独立二进制形式发布并支持 --remote-debugging-port 的浏览器。 Camoufox 使用 Firefox+Juggler(不支持 CDP); Patchright / undetected-chromedriver / nodriver 是 Python/Playwright 库, 而非独立浏览器。若没有协议适配器,cdpilot 的纯 CDP 架构与它们都不兼容。 跟踪计划: v0.9 路线图(采用 curl-impersonate 语义的 TLS-MITM 插件, 或采用经过 BoringSSL 修补的 Chromium 分支)。

请求拦截
cdpilot intercept block <pattern>                    # Block requests
cdpilot intercept mock <pattern> <json-file>         # Mock responses
cdpilot intercept headers <pattern> <header:value>   # Add headers
cdpilot intercept list                               # List active rules
cdpilot intercept clear                              # Clear all rules
设备模拟
cdpilot emulate iphone        # iPhone emulation
cdpilot emulate ipad          # iPad emulation
cdpilot emulate android       # Android emulation
cdpilot emulate reset         # Back to desktop
地理位置
cdpilot geo istanbul          # Set location to Istanbul
cdpilot geo london            # Set location to London
cdpilot geo 41.01 28.97       # Custom coordinates
cdpilot geo off               # Remove override
无障碍功能
cdpilot a11y                  # Full accessibility tree
cdpilot a11y summary          # Quick summary
cdpilot a11y find <role>      # Find elements by ARIA role
会话管理
cdpilot session               # Current session info
cdpilot sessions              # List all sessions
cdpilot session-close [id]    # Close session
高级功能
cdpilot cookies [domain]             # List cookies (filter by domain)
cdpilot cookies save <file> [<domain>]  # Export cookies as JSON
cdpilot cookies load <file>          # Import cookies (replay CF clearance)
cdpilot cookies save --host x.com    # Save to per-host cache
cdpilot cookies load --host x.com    # Load from per-host cache
cdpilot cookies list                 # Cached hosts + age + CF clearance flag
cdpilot cookies clear --host x.com   # Remove one host
cdpilot cookies clear --all          # Wipe entire cache
cdpilot cookies clear --older-than 7d  # Remove stale entries
cdpilot cookies auto on              # Toggle global auto-save/replay flag (v0.6.1: requires safe-list)
cdpilot cookies auto add <host>      # Opt host into auto save/replay (v0.6.1)
cdpilot cookies auto remove <host>   # Remove host from safe-list
cdpilot cookies auto list            # Enable flag + current safe-list
cdpilot cookies cf-replay <url>      # Inject cached CF clearance before nav
cdpilot wipe [--cookies|--storage|--tabs|--keep h1,h2]
                                     # v0.6.2: per-task state hygiene (cross-task contamination)
cdpilot storage               # localStorage contents
cdpilot upload <sel> <file>   # Upload file to input
cdpilot multi-eval <js>       # Execute JS in all tabs
cdpilot headless [on|off]     # Toggle headless mode
cdpilot frame list            # List iframes (index = --frame <index>)
cdpilot frame eval --frame <f> <js>  # Run JS inside an iframe (cross-origin too)
cdpilot dialog auto-accept    # Auto-accept dialogs
cdpilot permission grant geo  # Grant geolocation
并行上下文
cdpilot context create [url]  # Make fresh browser context + tab (prints JSON)
cdpilot context list          # Tree of contexts and their tabs
cdpilot context close <ctx>   # Destroy a context (refuses 'default')

通过环境变量固定目标上下文,以便在后续命令中操作其标签页:

ID=$(cdpilot context create https://example.com | jq -r .target_id)
CDPILOT_TARGET=$ID cdpilot eval 'document.title'

真正的隔离——每个上下文都有独立的 Cookie/存储空间。适用于并行运行 N 个 AI 聊天查询且不污染历史记录, 或测试已登录与未登录流程的 A/B,而无需启动多个浏览器。

智能导航(支持大模型)
cdpilot dismiss               # Click best "Stay signed out / No thanks" button
cdpilot dismiss aggressive    # Handle chained modals (cookie banner → signup)

内置英语和土耳其语模式库。明确排除具有破坏性、外观相似的选项(删除账户、退出登录、订阅), 可安全地串联到查询工作流中。

视频理解

单张截图无法捕捉动态画面。cdpilot watch 会运行连续 屏幕录制(Page.startScreencast),将 JPEG 帧写入环形缓冲区,让 AI Agent 能查询某个时间段并实际观看发生了什么—— 动画、鼠标光标移动、滚动、爆炸效果——而不是仅凭一张静止画面猜测。

cdpilot watch start <url|file://...>   # Begin screencast, play the video
cdpilot watch query --at 1:23 --window 5s  # Frames around a timestamp
cdpilot watch ask "did the menu animate open?"  # Ask about recent frames
cdpilot watch status          # Show capture state + buffer size
cdpilot watch stop            # Stop the screencast

支持本地文件(file://...)和在线视频(YouTube、Vimeo、 Twitter、Facebook、Instagram)。零依赖——Pillow 是可选的,仅 用于检测帧间动态。

DRM 限制: 受 DRM 保护的播放器(Netflix 等)在 CDP 层会渲染为 黑帧——cdpilot 无法捕获这些画面。所有 非 DRM 内容均可正常使用。

MCP 会将其作为 browser_watch_* 工具提供给 AI Agent。

视频理解(命令)
cdpilot watch start <url|file://>     # Start screencast, play video
cdpilot watch query --at 1:23 --window 5s  # Frames around a timestamp
cdpilot watch ask "did the modal slide in?"  # Ask about recent frames
cdpilot watch status                   # Capture state + buffer size
cdpilot watch stop                     # Stop screencast
隐身与 CAPTCHA

零依赖的反指纹层——修补 navigator.webdriver、 chrome.runtime、插件(正确继承 PluginArray)、WebGL 供应商/渲染器、权限、硬件并发数以及 Worker 构造函数。通过 Page.addScriptToEvaluateOnNewDocument 注入, 确保在任何页面脚本运行之前生效。默认禁用;可选择启用。

启动时,cdpilot 还会传入 --disable-blink-features=AutomationControlled, 关闭 Blink 运行时标志;Cloudflare 和 DataDome 会探测该标志,以检测 自动化浏览器。

真实鼠标点击(帧、--entropy=on、click @ref、dblclick、rightclick)会按住鼠标键 40-120 毫秒,模拟真人按压;CDPILOT_PRESS_MS=min-max 可更改范围(0-0 = 立即释放)。

三级隐身模式

cdpilot mode 是推荐的入口——通过一个开关设置 cdpilot 接触多少指纹特征,从最少到最多:

cdpilot mode             # show current tier + what it injects
cdpilot mode regular     # no fingerprint patch — cleanest, fastest (default)
cdpilot mode stealth     # light patch: webdriver / chrome.runtime / permissions
cdpilot mode undetected  # full patch: + plugin array + WebGL + Worker

regular 是默认模式,因为 Stealth Bench V1 发现,仅启用完整补丁集本身就会降低评分——合成插件数组本身就是一种暴露。stealth 级别会特意省略插件伪装;只有面对难以应付的目标时,才升级到 undetected。自适应层会为每个主机学习合适的级别,并在遇到 CAPTCHA 时升级。效果会在下次导航时生效。环境变量覆盖项: CDPILOT_MODE=<tier>。旧版 stealth on/off 开关仍然有效,并与级别保持一致:

cdpilot stealth on            # enable fingerprint patches (opt-in)
cdpilot stealth off           # disable (default)
cdpilot stealth status        # show which patches are applied

cdpilot captcha-check         # JSON detection of Turnstile/hCaptcha/reCAPTCHA/
                              # DataDome/PerimeterX/Arkose/GeeTest. Exit 0/3
cdpilot captcha-wait [sec]    # block until user solves (interactive)
                              # or poll with JSON stream (non-interactive)

cdpilot adaptive [on|off|status]
                              # Auto-escalate to stealth on hosts that show
                              # CAPTCHA. Persistent per-host memory.
cdpilot adaptive forget <host>
                              # Remove a hostname from the stealth list
cdpilot adaptive clear        # Drop the stealth host memory entirely

自适应模式是一种“快速运行,遇阻时再翻墙”的自动化方式:cdpilot 默认在开放模式下运行,每次导航后检测 CAPTCHA;一旦检测到 CAPTCHA,就会将主机添加到持久列表,并开启隐身模式重试一次。绝不会自动降级。设计上以保守为原则。

Web Bot Auth(签名 Agent)

与隐身模式相反。隐身模式试图让浏览器看起来像真人;Web Bot Auth 则声明“这是一个自动化 Agent,以下是它的身份凭证”。浏览器发出的每个请求都携带 Ed25519 HTTP Message Signature(RFC 9421) 签名,网站或其前置的 Cloudflare 会根据你在自己域名上发布的密钥目录进行验证。格式遵循 draft-meunier-web-bot-auth-architecture 和 draft-meunier-http-message-signatures-directory, 并复现 Cloudflare 参考实现 (cloudflare/web-bot-auth) 的 Ed25519 测试向量。

**可选依赖项。**签名需要 Python cdpilot 运行环境中的 cryptography 包(如果你设置了 CDPILOT_PYTHON,则使用该环境):

pip install cryptography

如果没有该依赖项,bot-auth 命令和 launch --bot-auth 会显示提示并以状态码 2 退出。其他所有命令仍照常工作。

1. 生成密钥(仅需一次):

cdpilot bot-auth init --agent-url https://your-domain.com

这会将 Ed25519 私钥写入 CDPILOT_HOME/bot-auth/ed25519.key(默认为 ~/.cdpilot),并以 0600 模式创建。cdpilot 从不打印或记录密钥;如果该文件可被其他人读取,则会发出警告。Agent URL 必须是 https:// 源站(不能包含路径)。再次执行 init 时会拒绝替换密钥,除非你传入 --force,因为新密钥将不再匹配你发布的目录。

2. 在自己的域名上托管已签名的目录。cdpilot bot-auth directory 会将公钥打印为 JWKS,其中 kid 是该密钥的 RFC 7638 JWK 指纹。Cloudflare 还要求对目录响应进行签名,因此 --headers 会打印随响应一起提供的标头:

cdpilot bot-auth directory --headers        # headers, a blank line, then the JSON body
cdpilot bot-auth directory --headers --json # the same as {"authority", "headers", "body"}
Content-Type: application/http-message-signatures-directory+json
Signature-Input: sig1=("@authority";req);created=…;keyid="<thumbprint>";alg="ed25519";expires=…;nonce="…";tag="http-message-signatures-directory"
Signature: sig1=:<base64 Ed25519 signature>:

{ "keys": [ … ] }

将响应正文和这三个标头托管在 https://your-domain.com/.well-known/http-message-signatures-directory。签名覆盖 ("@authority";req),即获取目录时所用的主机:默认使用 Agent URL 的主机,也可通过 --authority <host> 指定。目录中的每个密钥都有一个签名。签名有效期为 24 小时(--ttl <seconds>),因此静态主机需要每天刷新签名,可以使用 cron,或运行相同签名逻辑的边缘函数。以下是一个 cron 示例,用于重写标头文件以及 Web 服务器提供的响应正文:

# m h dom mon dow  — every day at 03:17, 48 h validity so one missed run does not break it
17 3 * * *  cdpilot bot-auth directory --headers --ttl 172800 --json > /var/www/wba/directory.json.tmp \
            && mv /var/www/wba/directory.json.tmp /var/www/wba/directory.json

你的服务器(或边缘函数)会从该 JSON 中读取 headers 和 body,并在 well-known 路径上提供它们。--content-digest 还会对响应正文进行签名(Content-Digest,RFC 9530),与 Cloudflare 的参考向量一致;此时必须逐字节提供输出的响应正文。

3. 启动签名浏览器:

cdpilot launch --bot-auth        # or: CDPILOT_BOT_AUTH=1 cdpilot launch
cdpilot status                   # ... bot-auth: on (keyid <thumbprint>)
cdpilot go https://example.com   # this request is signed, and so is everything after it
cdpilot stop                     # stops the browser and the signer

launch --bot-auth 会在浏览器旁启动一个小型的分离式签名器。它使用与空闲关闭监视器相同的自派生方式,生命周期与浏览器完全一致。它持有一个 CDP 连接,并自动附加到每个页面、弹出窗口、新标签页、进程外 iframe 和工作线程。它会在 Fetch 的“Request”阶段为每个请求签名,包括每次重定向跳转。因此,页面自行发出的请求也会签名:计时器、fetch()(即使你的 cdpilot 命令已经返回)、以及页面打开的标签页。data:、blob: 和 chrome-extension: 请求不会离开浏览器,因此会原样通过。如果请求签名失败,该请求会以未签名状态发出,一行日志会写入 CDPILOT_HOME/bot-auth/signers/<port>.log(仅主机),页面绝不会因此受阻。对已经运行的浏览器执行 launch --bot-auth 会为其添加签名器。

每个请求会获得三个标头:

标头值
Signature-Agent"https://your-domain.com"
Signature-Inputsig1=("@authority" "signature-agent");created=…;keyid="<thumbprint>";alg="ed25519";expires=…;nonce="…";tag="web-bot-auth"
Signaturesig1=:<base64 Ed25519 signature>:

expires 为 created 加 5 分钟。nonce 是 64 个随机字节经 Base64 编码后的值,每个请求都会生成新的值。

这是旧版 Signature-Agent 格式(draft-05 A.2.3),也是默认格式,因为这是 Cloudflare 的验证器接受的格式:Cloudflare 会拒绝后续草案中的字典格式。若要改用字典格式(Signature-Agent: sig1="https://your-domain.com",覆盖项为 "signature-agent";key="sig1"),请运行 cdpilot bot-auth format dict(bot-auth format legacy 可切回旧版格式,bot-auth format 可查看当前格式,bot-auth init --agent-format dict 可在创建时设置)。更改从下一次 launch --bot-auth 开始生效。

不会签名的内容。 WebSocket 握手不会签名:浏览器不会通过 CDP 的 Fetch 域传递这些握手,因此页面打开的 wss:// 连接会在不带这些标头的情况下发出。Service Worker 内部的缓存命中以及 data:/blob: URL 永远不会到达服务器。

如果签名器退出或挂起。 签名器运行期间,浏览器的每个请求都会停留在 Fetch 阶段,直到签名器添加完标头。如果签名器被终止,请求会以未签名状态发出;此后,cdpilot status 和 cdpilot go 会各输出一行标准错误信息(签名器未运行,请求会以未签名状态发出,请再次运行 cdpilot launch --bot-auth),直到你重新启动签名器或运行 stop。如果签名器冻结(进程已停止或正在调试器中),请求会挂起:运行 cdpilot stop,然后再次运行 launch --bot-auth。cdpilot 仅在进程的命令行为对应端口的签名器、且浏览器是该签名器所附加到的浏览器时,才信任其签名器状态;因此,如果陈旧状态文件中的 pid 被其他程序复用,该状态会被丢弃,绝不会向该进程发送信号。

签名器运行时,空闲关闭仍然有效:签名器会附加到每个页面,因此 cdpilot 不再判断“是否有页面已附加”,而是统计除签名器以外的 CDP 客户端(按套接字所有者统计:macOS 和 Windows 上使用 netstat,Linux 上使用 ss);watch 守护进程或 Playwright 会话会让浏览器保持打开状态。在 Linux 上,ss -tnp 只会显示你自己的进程所拥有的套接字,因此以其他用户身份运行的客户端不会被计入,空闲关闭可能会在该客户端仍在使用浏览器时将浏览器关闭。

隐身模式冲突。 签名表示“我是 Agent”,而隐身模式表示“我不是”。如果同时传入 --bot-auth 和 --stealth/--undetected,或者 cdpilot mode 为 stealth 或 undetected,cdpilot 会输出一行警告并应用 bot-auth。签名器运行时,不会注入隐身脚本或用户代理覆盖项,自适应升级也不会在隐身级别重试。 向 Cloudflare 注册。 目录上线后,请通过 Cloudflare 控制面板中的 Bot Submission Form 提交目录,并将其注册为 已签名的 Agent(代表用户行事的 Agent)或 已验证的机器人;请参阅 Cloudflare 关于 已签名的 Agent和 通过密码学验证的机器人 的文章。使用 Cloudflare 的网站随后会将你的请求识别为来自你的 Agent。未检查 Web Bot Auth 的网站会忽略这些标头。

摩擦阶梯(渐进式反机器人检测)

真实网站不会只甩出一个 CAPTCHA,而是会逐步叠加防御措施。 cdpilot friction 会报告当前触发的阶梯级别,让 Agent 做出恰当响应,而不是靠猜测。共有六个级别,从低到高:

none → rate_limited → soft_captcha → login_wall → otp_sms → hard_block
cdpilot friction              # JSON: current rung + recommended response policy

双语(英语 + 土耳其语)DOM 启发式检测。检测**只读,不会绕过任何机制。**响应策略刻意保持保守:

  • rate_limited → 自动指数退避并重试
  • soft_captcha → 交由验证码工具处理
  • login_wall / otp_sms / hard_block → 标记为需要人工接手,不会自主解决

最后一条是道德边界,而非缺失的功能:cdpilot 不会尝试自行突破登录、OTP/SMS 验证门槛或直接封锁。 MCP 将此功能公开为 browser_friction。

按住不放(PerimeterX / HUMAN 行为挑战)

PerimeterX 的“按住不放”是一种行为挑战,而不是令牌——没有可调用的服务商。唯一的解决方法是真正执行按下 → 按住 → 释放的手势,cdpilot 通过 CDP Input 域模拟该手势:按住约 3–7 秒,时长采用高斯随机化,并在按住期间产生 ±1–2px 的微小抖动。

cdpilot press-hold                       # auto-find the px-captcha target
cdpilot press-hold "#px-captcha button"  # explicit selector

检测到 perimeterx 挑战时,captcha-solve 会自动将请求路由到此处。 MCP 将此功能公开为 browser_press_hold。

验证码求解器插件(v0.6+)

可选集成 2captcha、anti-captcha 和 capmonster。每次求解费用约为 $0.001–0.003。API 密钥存储在 ~/.cdpilot/captcha-providers.json (chmod 600)中——绝不会提交到 git。

# One-time setup
cdpilot captcha config --provider 2captcha --api-key YOUR_KEY
cdpilot captcha config --provider anticaptcha --api-key YOUR_KEY  # fallback

# Enable auto-solve (adaptive layer auto-solves on detect)
cdpilot captcha auto on

# Manual solve (debug / scripting)
cdpilot captcha solve --type recaptcha-v2 --site-key SK --url https://example.com
# returns: {"token": "03AGdBq2...", "duration_ms": 12500, "cost": 0.003, "provider": "2captcha"}

cdpilot captcha solve --type hcaptcha --site-key SK --url URL
cdpilot captcha solve --type turnstile --site-key SK --url URL
cdpilot captcha solve --type funcaptcha --site-key SK --url URL

# Status & balance
cdpilot captcha status   # {"configured": [...], "preferred": "2captcha", "auto_enabled": true}
cdpilot captcha balance  # {"2captcha": 1.23, "anticaptcha": 0.50}

支持的类型:recaptcha-v2、recaptcha-v3、hcaptcha、turnstile、funcaptcha

令牌通过 CDP 的 Runtime.evaluate 注入,无需浏览器端库。 启用 captcha auto on 后,自适应层会在每次导航后自动检测并求解。未启用时,仍会进行检测,但需要手动求解。

预期基准测试提升(v0.6): reCaptcha 从 2/6 提升至 5+/6,hCaptcha 从 2/3 提升至 3/3

图片 CAPTCHA + 配置档案预热

captcha-solve 用于处理上述令牌求解器无法处理的基于图片的速率限制 CAPTCHA:

cdpilot captcha-solve                       # auto-detect + route (incl. press-hold)
cdpilot captcha-solve --provider amazon-local  # offline OCR (default)
cdpilot captcha-solve --provider capsolver   # BYOK image-to-text
cdpilot captcha-solve --provider 2captcha    # BYOK image-to-text
  • Amazon 经典图片 CAPTCHA(“输入你看到的字符”页面)通过可选的 amazoncaptcha 库在本地进行 OCR (pip install amazoncaptcha — 纯 Python + Pillow,MIT 许可证)。未安装时,命令会报告这一情况并正常退出;不会增加硬性依赖。
  • BYOK 提供商(capsolver、2captcha)通过图片转文本 API 工作,使用 CAPSOLVER_API_KEY / TWOCAPTCHA_API_KEY。
cdpilot profile warm          # age the profile for reCAPTCHA v3 score

profile warm 会浏览一组低风险网站,以积累 Cookie 和历史记录的时间,这会随着时间推移提高 reCAPTCHA v3 的行为评分。此功能有意设计得较慢——请在会话开始前运行,而不要在会话中直接运行。

公开的机器人检测面板,测量时间为 2026-09-27,使用无头 Brave(Chrome 154) (方法和原始结果):

modebot.sannysoft.com(31 项)incolumitas intoliincolumitas fpscannerincolumitas new-tests
regular(无补丁,默认)28 项通过 / 3 项失败5/619 项通过 / 3 项失败 / 1 项警告全部通过
stealth31 项通过6/619 项通过 / 1 项失败 / 1 项警告全部通过
undetected31 项通过6/619 项通过 / 1 项失败 / 1 项警告全部通过
  • fpscanner 中剩余的失败项是 'webdriver' in navigator,在所有现代 Chrome 中该表达式都为真;伪造这一项会让 cdpilot 显得与众不同。
  • regular 的失败项都源自 HeadlessChrome 用户代理。stealth/undetected 会在 go 启动的页面加载时改写它;同一页面中后续单独运行的命令 仍能读取到 HeadlessChrome。
  • new-tests:所有键值均正常;所有等级中 connectionRTT 都报告为未知。
  • 无法测量 nowsecure.nl 和 areyouheadless(固定的、始终交互的 Turnstile 测试密钥;HTTP 502)。

本页较早公布的数据(sannysoft 24/24、intoli 6/6)是在 2026 年 4 月使用 v0.4.x 测得;现已由上表取代。

可靠性
cdpilot browser [name|auto]   # workload-aware browser selection
cdpilot browser install chrome-for-testing   # for extension development (see above)
cdpilot health                # JSON: alive, port, tabs, browser, today's crashes, idle close

cdpilot health 专为 shell 看门狗设计:

until cdpilot health >/dev/null; do cdpilot launch; sleep 2; done

在 macOS 上显示今天 Brave 的崩溃次数,数据来自 ~/Library/Logs/DiagnosticReports/, 让你能在自动化悄无声息地停滞之前发现性能下降。

自动启动。 如果页面命令(go、content、click、shot 等)发现 浏览器未运行,就会像 cdpilot launch 一样启动浏览器(使用相同的配置文件、 相同的无头/可见设置),然后继续执行,并向 stderr 输出一行: cdpilot: browser was not running — launched it (CDPILOT_NO_AUTOLAUNCH=1 to disable)。 生命周期、状态和配置命令(launch、stop、close、 close-tab、stop-all、project-stop、session-close、status、health、 tabs、sessions、projects、headless、proxy、browser、extensions、 mcp、serve 等)绝不会启动浏览器。CDPILOT_NO_AUTOLAUNCH=1 会恢复旧版的 "CDP connection error. Is the browser running?" 错误,并以退出码 1 退出。

空闲时自动关闭。 对于由页面命令自动启动,或由 MCP 服务启动(包括 browser_launch)的浏览器,如果 15 分钟内没有 cdpilot 命令或可见页面变化, 就会自动关闭,避免已完成的 Agent 任务继续占用内存。显式执行 cdpilot launch 启动的浏览器会保持打开(你可能正在手动浏览),除非你指定: cdpilot launch --idle-close 30 或 CDPILOT_IDLE_CLOSE=30。此环境变量也会 设置自动启动后的关闭延迟(浏览器启动时读取;允许小数);0 会关闭空闲自动关闭。 你自行启动的浏览器,或 cdpilot 仅连接到的浏览器,绝不会被关闭。

使用行为包括:除只读检查(status、 health、projects、version)以外的任何 cdpilot 命令(cdpilot health 看门狗循环不会让 浏览器保持运行)、MCP 工具调用、serve 请求、仍连接到页面的 CDP 客户端 (长时间运行的命令、watch、通过 connectOverCDP 运行的 Playwright),以及打开页面的 URL 或标签页集合发生的任何变化(有人导航、新开或关闭标签页)。标题变化不算,因此, 自行改写标题的页面(时钟、未读计数器)无法让浏览器保持运行。cdpilot status 和 cdpilot health 会显示 idle close in 12m 或 idle close off。

实现方式:每条命令都会记录时间戳到 ~/.cdpilot/projects/<id>/last-activity;启动时会 启动一个小型的独立监视进程(每个端口一个;Windows 上不会显示控制台窗口),每 ≤30 秒 检查一次,像 cdpilot stop 一样停止浏览器,在注册表中将其标记为已停止,然后退出; 如果浏览器因其他原因关闭,它也会立即退出。由 serve --api 启动的浏览器由 服务管理,不会自动空闲关闭。

超时。 任何命令都可以使用 --timeout <seconds>,放在命令名称之前或之后; 也可以通过 CDPILOT_TIMEOUT 设置默认值(命令行标志优先;0 表示禁用)。它会限制整个命令的实际运行时间:超时后,cdpilot 会向 stderr 输出 cdpilot: timed out after <N>s (<command>),杀死其启动的子进程,并以退出码 124 退出(与 GNU timeout 相同)。已经运行并注册的浏览器会继续运行。

cdpilot --timeout 10 click "#submit"      # before the command...
cdpilot shot page.png --timeout 30        # ...or after it
CDPILOT_TIMEOUT=60 cdpilot run flow.cdp   # default for every command (and each script line)

对于 mcp 和 serve,该值不会应用于长期运行的服务本身,而是传递给它运行的每次 工具调用/请求。

会话日志

每条命令(以及每次 MCP 工具调用)都会向本地的项目专属日志追加一行 JSON,因此浏览器任务完成后,就能查到执行过什么以及发现了什么。任何内容都不会离开本机。

cdpilot log                 # today's commands: time, exit, command, url, result
cdpilot log --md            # Markdown report: pages visited, actions, errors, files produced
cdpilot log --json          # raw lines (one JSON object per command)
cdpilot log --days 3        # include the last 3 days
cdpilot log --path          # where the files are

每行包含 ts、cmd、args、exit、duration_ms、命令执行后的页面 url 和 title(若命令执行前已有这些信息)、约 200 个字符的输出 summary、error 行,以及写入的 files(截图、PDF)。文件存放在 ~/.cdpilot/projects/<project-id>/log/<YYYY-MM-DD>.jsonl。

写入任何内容之前都会进行脱敏:传给 fill、type、smart-fill、smart-select、assert-value 和 dialog prompt 的值都会变成 «redacted:N chars»;密码、令牌、密钥、机密、Cookie、身份验证相关标志和标头的值、看起来像令牌的参数,以及名称包含 token、key、secret、password、auth、code 或 session 的 URL 查询参数和片段值也会如此处理。cookies 和 storage 的输出绝不会写入日志;会记录 eval 的源代码,但超过 40 个字符的字符串字面量会被截断,看起来像机密的字符串会被替换。日志记录尽力而为:不会改变命令的输出或退出代码,写入失败时只会向 stderr 输出一行。设置 CDPILOT_LOG=0 可关闭日志;CDPILOT_LOG_DAYS(默认值为 14)可设置日志保留天数。MCP 服务通过 browser_log 提供此功能。

使用自己的浏览器(人在回路中)

Agent 遇到无法自行通过的 CAPTCHA 或登录页面时,由人来解决,Agent 随后在同一浏览器中继续操作。

最简单的方法不需要 connect。 cdpilot 自带的浏览器是一个正常的可见窗口,除非以无头模式启动(cdpilot headless on / CHROME_HEADLESS=1)。用户可直接在窗口中解决 CAPTCHA 或登录,之后 Agent 便可继续操作:

cdpilot go https://example.com/dashboard   # agent: "captcha detected" / login wall
cdpilot captcha-wait 300                   # agent waits while the person solves it
cdpilot go https://example.com/dashboard   # agent continues in the same window

该窗口使用 cdpilot 自带的配置文件,因此登录状态会保留,供之后的运行使用。

connect 适用于由你自行启动的浏览器,该浏览器需使用调试端口和你自己的配置文件目录(登录一次即可;它会保留 Cookie):

# macOS
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
  --remote-debugging-port=9450 --user-data-dir="$HOME/cdpilot-chrome"
# Linux
google-chrome --remote-debugging-port=9450 --user-data-dir="$HOME/cdpilot-chrome"
# Windows
"%ProgramFiles%\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9450 --user-data-dir="%USERPROFILE%\cdpilot-chrome"

cdpilot connect 9450          # or: cdpilot connect ws://127.0.0.1:9450/devtools/browser/<id>
cdpilot connect --auto        # or: find it via a DevToolsActivePort file
cdpilot go https://example.com/dashboard
cdpilot disconnect            # forget it; the browser keeps running

从 Chrome 136 开始,默认配置文件会忽略 --remote-debugging-port,因此必须使用单独的 --user-data-dir。connect --auto 会读取每个已知配置文件目录中的 DevToolsActivePort 文件(上方命令所用的 ~/cdpilot-chrome、Chrome stable/beta/dev/canary、Chromium、Brave、Vivaldi、Edge),跳过浏览器已关闭或该端口已被替换的浏览器所遗留的文件(文件中的浏览器 ID 必须匹配),并连接到第一个仍在运行的浏览器。它只会通过 HTTP 发起请求;只有在未找到仍在运行的浏览器时,才会发送 WebSocket 探测请求(Chrome 的 chrome://inspect 模式可能会对此弹出权限提示)。

暂不支持:Chrome 的 chrome://inspect/#remote-debugging 开关(Chrome 144+,即日常使用且已登录的配置文件)。在此模式下,Chrome 只会通过 WebSocket 响应(/json/version 和 /json 会返回 404),并且可能要求你允许每个新的调试连接,而 cdpilot 会通过 /json 列出标签页,并为每条命令建立新的连接。connect --auto 会识别此模式,并以退出代码 2 退出,同时给出上方的启动命令,而不是以不完整的方式运行。

cdpilot 对已连接的浏览器所做的操作:

  • 页面命令(go、click、fill、shot、……)会在首次执行页面命令时,在一个新窗口中打开一个供 cdpilot 自用的标签页,该窗口不会获得焦点 (使用 Target.createTarget,并设置 newWindow + background,因此你的窗口和 标签页会保持不变),之后会继续使用该标签页。close、 session-close 和空闲会话清理只会关闭此类标签页,即 cdpilot 在本次浏览器运行期间打开的标签页,绝不会关闭最后一个标签页。绝不会在你自己的标签页中导航或输入内容;只有明确指定标签页的命令才会操作它(switch-tab、close-tab <index|id>、CDPILOT_TARGET 和 multi-eval, 后者会在每个已打开的标签页中运行脚本)。
  • 它绝不会关闭或终止浏览器。close、close --force、stop、 stop --smart [--force]、project-stop、stop-all、session-close 和 MCP browser_close 最多只会关闭 cdpilot 自己的标签页(见上文),并打印 “已连接的浏览器仍在运行;运行 cdpilot disconnect 可断开连接”。空闲自动关闭不会操作该浏览器, tabs --reap 不会关闭任何内容,wipe、permission、cookies load 和 cf-replay 会被拒绝(添加 --allow-external 即可照常加载/重放 Cookie), context close 只会销毁由 context create 创建的上下文,而 launch / MCP browser_launch 不会启动任何内容。
  • close-tab 是一条显式命令,可以关闭你的标签页:不带参数时关闭当前 (cdpilot)标签页;也可以通过索引或 ID 指定要关闭的标签页。在 Windows 和 Linux 上,关闭最后一个标签页会退出浏览器,因此它不会关闭最后一个标签页。
  • 它不会向其中注入任何内容:没有隐身补丁或用户代理覆盖(无论 cdpilot mode / stealth 如何显示),没有发光效果,没有输入拦截器,没有开发扩展脚本,也不会自动恢复 Cookie。
  • 注册信息会一直保留,直到你运行 cdpilot disconnect。如果浏览器 已关闭,页面命令会以状态码 1 退出,并提示“你连接的浏览器已关闭;请重新运行 cdpilot connect 或运行 cdpilot disconnect”,而 cdpilot 绝不会另行启动浏览器。
  • 只有在有证据证明浏览器归其所有时,cdpilot 才会将其视为自己的浏览器:它在 launch 时记录的浏览器 ID(或者,对于较旧的记录,持有调试端口的运行中记录 PID)。端口被占用并不构成证据,因此遗留的注册表项绝不会导致 stop / close 操作端口 9222 上属于你自己的 Chrome。

风险:

  • 每条 cdpilot 命令,以及任何能够运行 cdpilot 的 Agent,都可以读取并使用该配置文件的 Cookie 和会话(邮件、银行、管理面板)。请使用只登录了任务所需服务的配置文件。
  • 只要浏览器在运行,所有本地程序都可以访问调试端口,而不仅仅是 cdpilot。完成后请关闭浏览器。
  • 网站更容易检测到自动化行为:cdpilot 不会对已连接的浏览器应用隐身处理。
  • cdpilot 的标签页会与你的标签页并列显示在同一个窗口中;当 Agent 指定你的某个标签页时,它仍可能对其执行操作(switch-tab、 close-tab <n>、multi-eval)。
WebMCP 工具(选择启用)

WebMCP 允许页面在 document.modelContext 上注册“工具”:可以通过 registerTool() 命令式注册,也可以通过 <form toolname tooldescription> 声明式注册(输入项由 toolparamdescription 描述)。cdpilot 通过浏览器自身的 API getTools() 和 executeTool() 列出并调用这些工具。在 Chrome 中,该 API 需要通过 chrome://flags/#enable-webmcp-testing 启用(Chromium 146+),因此请使用以下参数启动浏览器:

cdpilot launch --webmcp        # saved for this project: later launches (auto-launch too) keep it
cdpilot go https://example.com/shop
cdpilot tools list             # name, title, description, annotations, input schema
cdpilot tools list --json
cdpilot tools call add_to_cart '{"sku":"A1","qty":2}'
cdpilot tools call add_to_cart --arg sku=A1 --arg qty=2
cdpilot launch --no-webmcp     # turn it off again (applies at the next start)
  • launch --webmcp 会向浏览器的命令行添加 --enable-features=WebMCP,并将此模式与隐身模式配置一起保存(项目配置文件中的 webmcp.json);CDPILOT_WEBMCP=1|0 可覆盖此设置。模式启用时,cdpilot status 会显示一行 WebMCP 状态。 Chrome 只会在启动时读取功能标志:已经运行的浏览器会一直使用原有标志,直到执行 cdpilot stop。
  • tools list 会显示页面及其同源 iframe 中的工具(附带框架 URL),标记表单工具及表单是否会自行提交(toolautosubmit),并显示 title 和 readOnlyHint / consequentialHint / untrustedContentHint 注释。不会向页面注入任何内容:列表反映的是浏览器当时的注册表,因此会随重新加载和导航而更新。这两个命令都在 cdpilot 自己的隔离世界中运行(不使用 Runtime.enable),因此页面脚本即使包装了 getTools() / executeTool(),也无法添加工具、修改结果或查看调用;只有当该隔离世界无法访问 document.modelContext 时,cdpilot 才会使用页面的主世界,并会在 stderr 中说明。没有工具时,它会说明原因(运行中的浏览器未启用 WebMCP、不是安全上下文、浏览器版本过旧、文档未按源隔离,或页面未注册任何工具),并以 0 退出。
  • tools call 会先根据工具的 inputSchema 检查参数(required、type——true 不属于整数——、enum、const、嵌套的 properties 和 items;其他关键字交由页面处理);参数不匹配、工具未知或工具出错时,会以 1 退出。它会传递一个 AbortSignal,并在 --timeout(默认 20 s)超时后将其中止,随后以 124 退出,并显示 timed out after <N>s (--timeout); its execution was aborted。信号会在 --timeout 的截止时间触发;看门狗会再等待 3 s,以便输出该提示。 没有 toolautosubmit 的表单工具会等待用户提交表单。 多个框架注册了同名工具时,--frame <url-part> 可指定其中一个(完全匹配的框架 URL 优先);未指定时会使用顶层文档中的工具;如果顶层文档没有该工具,调用会停止并列出各个框架。
  • MCP:仅当项目启用了 WebMCP 模式时(或服务端设置了 CDPILOT_WEBMCP=1),才会列出 browser_site_tools 和 browser_site_tool_call。

安全性:tools call 会运行页面自身的代码,而工具名称、描述和结果都属于页面内容:请将其视为不可信内容。 会话日志会记录参数和结果,并在任何嵌套层级对名称包含 password、token、key、secret、auth 等字样的字段进行脱敏。

扩展与工作站使用
CDPILOT_OFFSCREEN=1 cdpilot launch   # headed, but no window on your screen
  • 屏幕外模式(CDPILOT_OFFSCREEN=1)会让浏览器保持有头模式(真实渲染,没有无头浏览器指纹),但会将窗口放置在不会抢夺焦点的位置——适用于在同时使用的工作站上进行自动化操作。
  • 多实例池(CDPILOT_POOL_SIZE)——计划中,尚未发布。 请参阅路线图。
  • Docker + Xvfb 测试框架——用于一个单独的私有基准测试仓库(cdpilot-bench),不属于此软件包。

与 AI Agent 配合使用

cdpilot 专为由 AI Agent 作为工具调用而设计:

Claude Code(MCP)
{
  "mcpServers": {
    "cdpilot": {
      "command": "npx",
      "args": ["cdpilot", "mcp"]
    }
  }
}
任意大模型(工具调用)
{
  "name": "browser",
  "description": "Control a browser via CDP",
  "parameters": {
    "command": "go https://example.com"
  }
}
Python(子进程)
import subprocess
result = subprocess.run(["npx", "cdpilot", "go", url], capture_output=True, text=True)
print(result.stdout)

环境变量

变量默认值描述
CDP_PORT9222CDP 调试端口
CHROME_BIN自动检测浏览器二进制文件路径
CDPILOT_PROFILE~/.cdpilot/profile隔离的浏览器配置文件
BROWSER_SESSION自动会话标识符
CDPILOT_MODEregular隐身级别覆盖值(regular/stealth/undetected)
CDPILOT_OFFSCREEN0有头模式但在屏幕外渲染——不会有窗口抢占焦点
CDPILOT_TIMEOUT未设置为每条命令设置默认 --timeout(秒)(命令行标志优先,0 表示禁用);超时后以状态码 124 退出
CDPILOT_NO_AUTOLAUNCH01 = 页面命令不会启动浏览器,而是报错并显示旧版“浏览器正在运行吗?”提示
CDPILOT_IDLE_CLOSE15浏览器 cdpilot 启动后,若没有 cdpilot 命令或页面变更,经过多少分钟后自动关闭(允许小数,0 = 永不关闭;启动时读取)。默认值适用于自动启动和 MCP 启动;显式 CLI launch 不启用此项,除非设置了该变量或指定 --idle-close <min>
CDPILOT_LOG10 = 不写入会话日志(cdpilot log)
CDPILOT_LOG_DAYS14保留会话日志的天数;每天首次写入时会删除更早日期的文件(0 表示全部保留)

工作原理

┌─────────────┐     HTTP/WebSocket      ┌──────────────┐
│  cdpilot │ ◄──────────────────────► │ Brave/Chrome │
│   (CLI)     │    Chrome DevTools       │  (CDP mode)  │
└─────────────┘     Protocol             └──────────────┘
       │                                        │
       │  Zero dependencies                     │  Isolated profile
       │  Pure HTTP + WebSocket                 │  Separate from your
       │  single file, stdlib + websockets      │  personal browser
       └────────────────────────────────────────┘

没有 Puppeteer。没有 Playwright。没有 Selenium。 只有直接进行 CDP 通信。

隐身基准测试 V1

cdpilot 通过一组包含 80 个高难度网页任务的测试进行基准评测,以衡量其应对现代反机器人系统的成功率。Gemini 2.5 Flash 作为控制器驱动 cdpilot;成功是指完整完成任务且未遭拦截。

v0.5.3 结果(当前)
类别成功数 / 总数比率
自定义反机器人5 / 5100.0%
Temu 滑块1 / 1100.0%
hCaptcha2 / 367.0%
Cloudflare12 / 2255.0%
DataDome5 / 1338.0%
reCaptcha2 / 633.0%
Akamai1 / 617.0%
PerimeterX2 / 1811.0%
GeeTest0 / 40.0%
Shape0 / 10.0%
Kasada0 / 10.0%
总计30 / 8037.5%
版本历史
版本模式总数比率
v0.5.0基线(关闭隐身 / 关闭自适应)30 / 8037.5%
v0.5.0仅隐身(开启隐身 / 关闭自适应)32 / 8040.0%
v0.5.0完整(开启隐身 / 开启自适应)26 / 8032.5%
v0.5.1完整 — 回归问题修复29 / 8036.25%
v0.5.2完整 — 熵自动钩子28 / 8035.0%
v0.5.3完整 — 收紧熵作用范围30 / 8037.5%
v0.6.0+ CAPTCHA 求解器 + cookies-auto(回归)15 / 8018.75%
v0.8.0完整 — cookies 限定安全主机 + 按任务清除(无代理,无 TLS 分支)29 / 8036.25%
v0.7.0(插槽)+ 命名代理池取决于用户代理—
v0.8.0(插槽)+ TLS 感知启动器(camoufox/undetected-chrome)取决于浏览器选择—

cdpilot 不会做什么: cdpilot 是规避引擎,而不是 CAPTCHA 求解器。我们优先采用结构性隐身(JS 指纹识别、行为熵),以防挑战出现。当 CAPTCHA 阻碍进度且无法绕过时,任务就会失败——这才是对我们成功率的诚实定义。PerimeterX(2/18)、GeeTest(0/4)和 Akamai(1/6)是已知弱项;v0.7+(住宅代理)和 v0.8+(通过 camoufox 修正 TLS 指纹)将直接针对这些问题。

推荐配置

根据 Stealth Bench V1 的结果:

  • 速度优先(适用于大多数场景):cdpilot launch — 使用默认浏览器行为,不应用补丁
  • 启用 Stealth(推荐,综合表现最佳):cdpilot launch && cdpilot stealth on
  • 完整自适应(适用于特定的验证码密集型工作流):cdpilot launch && cdpilot stealth on && cdpilot adaptive on

对于 Stealth Bench V1 的任务组合,完整自适应层与基准方案持平(30/80 对 30/80)。仅启用 Stealth(32/80 = 40%)仍是表现最佳的单一变体。请针对你的具体工作负载进行测试并择优选择。

对比

特性cdpilotPuppeteerPlaywrightSelenium
安装大小一个 Python 文件 + 一个小型 Node 启动器,无需 node_modules400MB+200MB+100MB+
依赖项0 npm(Python:websockets,自动安装)50+30+Java + 驱动程序
设置时间即时数分钟数分钟麻烦
适用于 AI Agent是手动配置手动配置手动配置
浏览器下载否是(Chromium)是(3 个浏览器)否
CLI 优先是否(库)否(库)否
MCP 支持是否否否

商业化 / Pro(即将推出)

cdpilot CLI 现在是、将来也始终是免费且开源的(MIT)。

未来的付费产品:

  • cdpilot cloud — 远程浏览器实例,无需本地浏览器
  • 团队控制面板 — 共享会话、审计日志、使用情况分析
  • 优先支持 — 为企业集成提供直接帮助

安全性

  • 隔离的浏览器配置文件 — cdpilot 在 ~/.cdpilot/profile 中运行,与日常使用的浏览器分开。你的 Cookie、密码和历史记录绝不会暴露。
  • 禁止任意文件访问 — MCP 截图文件名会经过清理,并限制在截图目录中。路径遍历会被阻止。
  • 安全的 CSS 选择器 — 传递给 querySelector 的所有选择器都会进行 JSON 转义,以防止注入。
  • 不暴露网络 — CDP 仅监听 127.0.0.1。默认情况下无法进行远程连接。
  • 无依赖项 — 零 npm/Python 运行时依赖,意味着没有供应链攻击面。

发现漏洞?请直接给维护者发送邮件,而不要创建公开问题。

Cookie 持久化(v0.6+)

按主机缓存 Cookie,并在导航前自动重放。对于存在高成本挑战的网站(Cloudflare、DataDome)尤其有用——通过验证后,通行 Cookie(cf_clearance、__cf_bm)会被缓存,并在下次访问时重放。

# Enable auto-mode — cookies saved/replayed on every navigate
cdpilot cookies auto on

# Manual per-host workflow
cdpilot cookies save --host x.com   # cache current session cookies
cdpilot cookies load --host x.com   # inject before navigating
cdpilot cookies cf-replay https://x.com  # explicit CF clearance injection

# Inspect and clean
cdpilot cookies list                     # all cached hosts + age + CF flag
cdpilot cookies clear --older-than 7d   # prune stale cache

存储位置:~/.cdpilot/cookies/<host>/cookies.json(权限为 chmod 600,绝不会提交到 git)。 加载时会自动筛除已过期的 Cookie。

路线图

唯一内置测试断言的浏览器 MCP。以下是我们已发布的内容和接下来的计划:

已发布
  • 70+ 个 CLI 命令(导航、点击、填充、截图、PDF、控制台、网络、视频理解、摩擦阶梯……)
  • 用于集成 AI Agent 的 MCP 服务(Claude Code、Cursor 等)
  • 10 个内置测试断言 — assert、assert-url、assert-title、assert-count、assert-value、assert-attr、assert-visible/hidden、wait-for、check(批量)、screenshot-diff
  • test 运行器 + trace 查看器 — cdpilot test [--watch] 运行 *.cdpt.js 文件;cdpilot trace open <run> 打开该次运行的时光回溯跟踪查看器
  • 无障碍树快照(a11y-snapshot)— 结构化文本带有 @ref 句柄,Agent 可直接操作,无需视觉模型;在我们测量的四个页面上,其体积比页面原始 HTML 小 1.4–42 倍(2026-09-27)。但它并不总比截图更省:链接密集的页面产生的文本可能比小尺寸截图的成本更高
  • 高效利用 Token 的截图 — 元素级裁剪(缩小 13 倍)、JPEG 质量控制、格式选择
  • 视觉回退(describe)— 一次调用即可获取无障碍信息、截图和文本
  • 带注释的截图 — 在交互元素上叠加 @N 徽标
  • 自动等待 — 基于 MutationObserver,自动等待元素最长 5 秒
  • wait-for-text — 基于文本的自适应等待(子树 + characterData),适用于流式 AI 回复、异步提示和无需选择器的同步
  • eval-batch — 在一次 CDP 往返中运行 N 个 JS 表达式(相比顺序执行 eval,速度提升 5–30 倍)
  • block — 通过 Network.setBlockedURLs 阻止请求,并内置预设(图片/字体/广告/媒体);启用后页面加载速度提升 3–10 倍
  • dismiss — 使用启发式方法自动点击 LLM 聊天注册墙(EN+TR 模式库,带有破坏性操作防护)
  • adaptive — 在受 CAPTCHA 保护的主机上自动升级到 stealth 模式,并按主机持久记忆(“快速运行,翻越障碍”)
  • cookies save/load — 将 Cookie 导出/导入为 JSON(在不同运行之间重放 CF/DataDome 通行状态)
  • context 池 + CDPILOT_TARGET — 隔离的浏览器上下文,可在单个浏览器中实现真正的并行自动化(Playwright 的并行标签页模式)
  • fast / show — 集成计时与视觉切换功能。0.5.0 中默认采用静默/快速模式
  • WebSocket 池 + /json TTL 缓存 — 为 MCP/批处理工作负载复用连接,且零性能回退
  • 批量命令 — 通过 stdin 传入 JSON 数组,执行多步自动化
  • 视觉反馈系统(持续绿色发光、光标、涟漪、按键显示)
  • AI 控制警告提示(自动化期间用户进行交互时显示红色警告)
  • 多项目浏览器隔离(每个项目都有独立的端口和配置文件)
  • 预检向导(首次运行时自动安装依赖项)
  • 持久 MCP 发光效果(整个 AI 会话期间保持显示,类似 Claude 的橙色发光效果)
  • DevExtension 系统(无需浏览器商店即可注入原生 JS)
  • 智能命令 — smart-click、smart-fill、smart-select — 按可见文本进行交互,无需 CSS 选择器或 LLM。现支持禁用元素防护(不再错误地报告“已点击”禁用按钮)、Shadow DOM 遍历(Lightning、Polymer、lit-element 小组件)、根据区域设置匹配文本(土耳其语 İ/i、德语 ß),以及 smart-fill 浮动标签支持(通过 aria-labelledby 和 closest 标签解析适配 Material / Ant / Chakra)
  • 视频理解(watch)— 持续将屏幕录制写入环形缓冲区,让 AI Agent 可查询时间窗口并查看动态内容(动画、光标、滚动),而不只是单张静态帧。支持本地 file:// 和在线视频(YouTube/Vimeo/Twitter 等);不支持 DRM 播放器(Netflix)
  • 摩擦阶梯(friction)— 6 级渐进式反机器人检测(none → rate_limited → soft_captcha → login_wall → otp_sms → hard_block),支持 EN+TR 双语,只读;触发速率限制时自动退避,登录/OTP/硬拦截会标记为需要人工接管(不进行自主绕过)
  • 三级 stealth 模式(mode regular|stealth|undetected)— 通过单一开关控制指纹表面,并按主机自适应学习等级
  • 按住求解器(press-hold)— 模拟真人按下 → 按住 → 释放的手势(高斯分布 3–7 秒 + 微抖动),用于 PerimeterX/HUMAN 行为挑战;captcha-solve 会自动路由至此
  • 图像 CAPTCHA + 配置文件预热 — 离线 Amazon 图像 OCR(可选 amazoncaptcha 库)+ BYOK 图像转文本(capsolver/2captcha);profile warm 通过延长配置文件使用时间来提升 reCAPTCHA v3 评分
  • 离屏模式(CDPILOT_OFFSCREEN)— 在不抢占窗口焦点的情况下进行有头渲染
  • 数据提取(extract)— 以文本、JSON 或列表格式提取结构化 DOM 数据
  • 页面观察(observe)— 列出所有交互元素及其可用操作
  • 脚本运行器(run)— 执行 .cdp 脚本文件并报告通过/失败结果
  • iframe 定位 — "iframe#card >>> input" / --frame 可用于元素命令,支持同源和跨源(进程外)框架;智能命令会自动搜索框架
即将推出
  • 多实例池(CDPILOT_POOL_SIZE)—— N 个独立浏览器进程,按负载最低原则分发
  • 会话录制与回放——录制浏览器会话并以确定性方式回放
  • 隐身模式(Pro)——仿人类的鼠标操作和打字、防指纹追踪、验证码求解
  • cdpilot Cloud——托管式浏览器会话 API、REST + WebSocket MCP 端点
  • Chrome 扩展——无需命令行,即可在任何浏览器中使用 cdpilot
  • 性能审计——通过 CDP Performance 域检测 Core Web Vitals(LCP、CLS、INP)
  • WCAG 无障碍审计——自动生成无障碍合规报告
  • Claude Code Skill 模式——除 MCP 外,还可作为 .claude/skills/ 技能运行

有想法?提交 issue 或提交 PR!

贡献

git clone https://github.com/mehmetnadir/cdpilot.git
cd cdpilot
npm install
npm test

欢迎提交 PR!请先阅读 CONTRIBUTING.md。

许可证

MIT——随意使用。


以 cdpilot 理念打造:一个工具,只做一件事,并把它做好。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。