feat(browser): enhance CDP auto-discovery with port probe & opt-in priority

- Add TCP port reachability check to handle stale DevToolsActivePort files
- Make discoverChromeEndpoint() async with port probe before returning
- Change connection priority: extension mode is default, CDP is opt-in
  - OPENCLI_CDP_ENDPOINT: explicit CDP endpoint
  - OPENCLI_USE_CDP=1: enable DevToolsActivePort auto-discovery
  - Default: --extension mode (Playwright MCP Bridge)
- Add verbose logging for CDP discovery when -v flag is used
- Fix indentation inconsistency in connect() method
- Update README.md, README.zh-CN.md, SKILL.md with new connection docs
This commit is contained in:
jackwener committed 2026-03-15 19:44:27 +08:00
1 parent da155e96f0
commit a6e9c3b611
4 files changed
+28 -30

No files matched your search

+7 -13
View File
@@ -57,25 +57,19 @@ npm install -g @jackwener/opencli@latest
Browser commands need:
1. **Chrome** running **and logged into the target site** (e.g. bilibili.com, zhihu.com, xiaohongshu.com)
2. **[Playwright MCP Bridge](https://chromewebstore.google.com/detail/playwright-mcp-bridge/mmlmfjhmonkocbjadbfplnigmagldckm)** extension installed
#### Option A: Chrome 144+ Auto-Discovery (Recommended)
This is the default connection mode — no extra configuration needed beyond installing the extension.
No extensions needed. Just enable Chrome's built-in remote debugging:
#### Alternative: Chrome 144+ CDP Auto-Discovery
For Chrome 144+, you can skip the extension and use built-in remote debugging instead:
1. Open `chrome://inspect#remote-debugging` in Chrome
2. Check **"Allow remote debugging for this browser instance"**
3. That's it — opencli will auto-detect the running Chrome via `DevToolsActivePort`
3. Set `OPENCLI_USE_CDP=1` before running opencli
You can also manually specify a CDP endpoint via `OPENCLI_CDP_ENDPOINT` env var.
#### Option B: Playwright MCP Bridge Extension (Legacy)
For older Chrome versions or if auto-discovery doesn't work:
1. Install **[Playwright MCP Bridge](https://chromewebstore.google.com/detail/playwright-mcp-bridge/mmlmfjhmonkocbjadbfplnigmagldckm)** extension
2. Configure `PLAYWRIGHT_MCP_EXTENSION_TOKEN` (from the extension settings page)
> opencli will automatically fall back to extension mode if no running Chrome with remote debugging is detected.
You can also manually specify an endpoint via `OPENCLI_CDP_ENDPOINT` env var.
Public API commands (`hackernews`, `github search`, `v2ex`) need no browser at all.
+6 -12
View File
@@ -58,26 +58,20 @@ npm install -g @jackwener/opencli@latest
浏览器命令需要:
1. **Chrome** 浏览器正在运行,且**已登录目标网站**(如 bilibili.com、zhihu.com、xiaohongshu.com)
2. 安装 **[Playwright MCP Bridge](https://chromewebstore.google.com/detail/playwright-mcp-bridge/mmlmfjhmonkocbjadbfplnigmagldckm)** 扩展
#### 方式 A:Chrome 144+ 自动发现(推荐)
这是默认连接方式——安装扩展后无需额外配置。
无需安装扩展,只需开启 Chrome 内置远程调试:
#### 可选:Chrome 144+ CDP 自动发现
如果使用 Chrome 144+,可以跳过扩展,改用内置远程调试:
1. 在 Chrome 中打开 `chrome://inspect#remote-debugging`
2. 勾选 **"允许对此浏览器实例进行远程调试"**
3. 完成 — opencli 会通过 `DevToolsActivePort` 自动发现运行中的 Chrome
3. 运行时设置 `OPENCLI_USE_CDP=1`
也可通过 `OPENCLI_CDP_ENDPOINT` 环境变量手动指定 CDP endpoint。
#### 方式 B:Playwright MCP Bridge 扩展(旧版)
适用于旧版 Chrome 或自动发现不可用的情况:
1. 安装 **[Playwright MCP Bridge](https://chromewebstore.google.com/detail/playwright-mcp-bridge/mmlmfjhmonkocbjadbfplnigmagldckm)** 扩展
2. 配置 `PLAYWRIGHT_MCP_EXTENSION_TOKEN`(从扩展设置页获取)
> 如果未检测到开启远程调试的 Chrome,opencli 会自动回退到扩展模式。
公共 API 命令(`hackernews`、`github search`、`v2ex`)无需浏览器。
> **⚠️ 重要**:浏览器命令复用你的 Chrome 登录状态。运行命令前,你必须已在 Chrome 中登录目标网站。如果获取到空数据或报错,请先检查登录状态。
+3 -2
View File
@@ -34,8 +34,8 @@ npm update -g @jackwener/opencli
Browser commands require:
1. Chrome browser running **(logged into target sites)**
2. **Chrome 144+** (recommended): Open `chrome://inspect#remote-debugging` → enable remote debugging. opencli auto-discovers via `DevToolsActivePort`
3. **Fallback**: [Playwright MCP Bridge](https://chromewebstore.google.com/detail/playwright-mcp-bridge/mmlmfjhmonkocbjadbfplnigmagldckm) extension (auto-used when CDP not available)
2. [Playwright MCP Bridge](https://chromewebstore.google.com/detail/playwright-mcp-bridge/mmlmfjhmonkocbjadbfplnigmagldckm) extension (default connection mode)
3. **Alternative**: Chrome 144+ CDP auto-discovery — set `OPENCLI_USE_CDP=1` (no extension needed)
> **Note**: You must be logged into the target website in Chrome before running commands. Tabs opened during command execution are auto-closed afterwards.
@@ -333,6 +333,7 @@ ${{ index + 1 }}
| `OPENCLI_BROWSER_EXPLORE_TIMEOUT` | 120 | Explore timeout (sec) |
| `OPENCLI_EXTENSION_LOCK_TIMEOUT` | 120 | Extension lock timeout (sec) |
| `OPENCLI_CDP_ENDPOINT` | — | Manual CDP WebSocket endpoint (overrides auto-discovery) |
| `OPENCLI_USE_CDP` | — | Set to `1` to use Chrome 144+ CDP auto-discovery instead of extension |
| `OPENCLI_FORCE_EXTENSION` | — | Set to `1` to skip CDP and force extension mode |
| `PLAYWRIGHT_MCP_EXTENSION_TOKEN` | — | Auto-approve extension connection |
+12 -3
View File
@@ -310,11 +310,20 @@ export class PlaywrightMCP {
const mcpPath = findMcpServerPath();
if (!mcpPath) throw new Error('Playwright MCP server not found. Install: npm install -D @playwright/mcp');
// Chrome 144+ auto-discovery via DevToolsActivePort file.
// Falls back to --extension mode if no running Chrome is detected.
// Connection priority:
// 1. OPENCLI_CDP_ENDPOINT env var → explicit CDP endpoint
// 2. OPENCLI_USE_CDP=1 → auto-discover via DevToolsActivePort
// 3. Default → --extension mode (Playwright MCP Bridge)
// Some anti-bot sites (e.g. BOSS Zhipin) detect CDP — use forceExtension to bypass.
const forceExt = opts.forceExtension || process.env.OPENCLI_FORCE_EXTENSION === '1';
const cdpEndpoint = forceExt ? null : (process.env.OPENCLI_CDP_ENDPOINT ?? await discoverChromeEndpoint());
let cdpEndpoint: string | null = null;
if (!forceExt) {
if (process.env.OPENCLI_CDP_ENDPOINT) {
cdpEndpoint = process.env.OPENCLI_CDP_ENDPOINT;
} else if (process.env.OPENCLI_USE_CDP === '1') {
cdpEndpoint = await discoverChromeEndpoint();
}
}
return new Promise<Page>((resolve, reject) => {
const timer = setTimeout(() => reject(new Error(`Timed out connecting to browser (${timeout}s)`)), timeout * 1000);