Skip to content

feat(browser): Chrome 144+ auto-discovery via DevToolsActivePort#11

Merged
jackwener merged 1 commit intojackwener:mainfrom
backtime1993:feat/chrome-auto-discovery
Mar 15, 2026
Merged

feat(browser): Chrome 144+ auto-discovery via DevToolsActivePort#11
jackwener merged 1 commit intojackwener:mainfrom
backtime1993:feat/chrome-auto-discovery

Conversation

@backtime1993
Copy link
Contributor

Summary

  • Chrome 144+ introduced a built-in remote debugging toggle at chrome://inspect#remote-debugging — no --remote-debugging-port flag needed
  • Chrome writes the active port and browser GUID to a DevToolsActivePort file in the user data directory
  • This PR reads that file to auto-discover the CDP WebSocket endpoint, connecting via --cdp-endpoint instead of --extension
  • Eliminates the need for the Playwright MCP Bridge browser extension in most cases

How it works

DevToolsActivePort file (written by Chrome):
  9222
  /devtools/browser/b15b034e-2ea2-4b81-afe3-ef6699de8b5f

→ Constructs: ws://127.0.0.1:9222/devtools/browser/b15b034e-...
→ Passes to Playwright MCP: --cdp-endpoint ws://...

Connection priority

  1. OPENCLI_CDP_ENDPOINT env var (manual override)
  2. DevToolsActivePort auto-discovery (Chrome/Edge, cross-platform)
  3. --extension mode fallback (original behavior, fully backward compatible)

Platform support

Platform Chrome Edge Chromium
Windows
macOS
Linux

Setup (for users)

  1. Open chrome://inspect#remote-debugging
  2. Check "Allow remote debugging for this browser instance"
  3. That's it — opencli will auto-detect the running Chrome

Test plan

  • Tested on Windows with Chrome 146 — opencli weibo hot works correctly
  • Test on macOS with Chrome 144+
  • Test on Linux with Chrome/Chromium
  • Verify fallback to --extension mode when Chrome is not running / feature disabled

🤖 Generated with Claude Code

Chrome 144+ allows enabling remote debugging from chrome://inspect
without any command-line flags (--remote-debugging-port). Chrome writes
the active port and browser GUID to a DevToolsActivePort file in the
user data directory.

This change reads that file to auto-discover the CDP WebSocket endpoint,
eliminating the need for the Playwright MCP Bridge browser extension in
most cases.

Connection priority:
1. OPENCLI_CDP_ENDPOINT env var (manual override)
2. DevToolsActivePort auto-discovery (Chrome/Edge, cross-platform)
3. --extension mode fallback (original behavior)

Supports Windows, macOS, and Linux with Chrome, Edge, and Chromium.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@backtime1993 backtime1993 force-pushed the feat/chrome-auto-discovery branch from a757f32 to 55f71de Compare March 15, 2026 11:23
@jackwener jackwener merged commit c20eaee into jackwener:main Mar 15, 2026
@jackwener
Copy link
Owner

Thanks for the great contribution @backtime1993! 🎉

The PR has been merged. On top of your code, I made a few enhancements:

  1. TCP port reachability check — stale DevToolsActivePort files won't cause connection timeouts anymore
  2. Opt-in CDP mode — extension remains default; CDP via OPENCLI_USE_CDP=1 or OPENCLI_CDP_ENDPOINT
  3. Verbose logging-v flag now shows CDP vs extension mode
  4. Docs updated — README, README.zh-CN, SKILL.md all updated

All tests pass ✅. Thanks again!

jackwener added a commit that referenced this pull request Mar 19, 2026
P0 Critical:
- #1 Fix double IIFE wrapping: unified wrapForEval() replaces
  normalizeEvaluateSource + ad-hoc wrap in page.evaluate()
- #2 Fix navigate race: check tab.status before addListener,
  reduced timeout 30s→15s

P1 Should Fix:
- #8 Remove unused permissions (scripting, host_permissions, content_scripts)
- #10 Add retry (3x, 500ms) + timeout (30s) to sendCommand()

P2 Cleanup:
- #3 Extract isWebUrl() to safely handle undefined tab.url
- #4 Sanitize maxDepth with Math.max/min bounds
- #6 Delete empty src/daemon/ directory
- #7 Remove dead createJsonRpcRequest + its test
- #9 Remove stale IIFE-mode comment
- #11 Validate body.id in daemon request handler
- #12 Guard ensureAttached: detach+re-attach on 'already attached'
- #14 Extract _tabOpt() helper (removes 13x spread duplication)
- #15 Add verbose warning for unsupported consoleMessages()

All 35 unit tests pass.
jackwener added a commit that referenced this pull request Mar 19, 2026
P0 Critical:
- #1 Fix double IIFE wrapping: unified wrapForEval() replaces
  normalizeEvaluateSource + ad-hoc wrap in page.evaluate()
- #2 Fix navigate race: check tab.status before addListener,
  reduced timeout 30s→15s

P1 Should Fix:
- #8 Remove unused permissions (scripting, host_permissions, content_scripts)
- #10 Add retry (3x, 500ms) + timeout (30s) to sendCommand()

P2 Cleanup:
- #3 Extract isWebUrl() to safely handle undefined tab.url
- #4 Sanitize maxDepth with Math.max/min bounds
- #6 Delete empty src/daemon/ directory
- #7 Remove dead createJsonRpcRequest + its test
- #9 Remove stale IIFE-mode comment
- #11 Validate body.id in daemon request handler
- #12 Guard ensureAttached: detach+re-attach on 'already attached'
- #14 Extract _tabOpt() helper (removes 13x spread duplication)
- #15 Add verbose warning for unsupported consoleMessages()

All 35 unit tests pass.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants