Skip to main content

Overview

CDP (Chrome DevTools Protocol) mode allows agent-browser to connect to an existing browser instance instead of launching a new one. This enables control of:
  • Electron apps
  • Chrome/Chromium with remote debugging enabled
  • WebView2 applications
  • Any browser exposing a CDP endpoint
  • Remote browser services (Browserbase, Browser Use, Kernel)

Quick Start

Connect to Chrome

# 1. Start Chrome with remote debugging
google-chrome --remote-debugging-port=9222

# 2. Connect once, then run commands
agent-browser connect 9222
agent-browser snapshot
agent-browser click @e1
agent-browser close

# Or pass --cdp on each command
agent-browser --cdp 9222 snapshot
agent-browser --cdp 9222 click @e1

Auto-Connect

Use --auto-connect to automatically discover and connect to a running Chrome instance without specifying a port:
# Auto-discover running Chrome
agent-browser --auto-connect snapshot
agent-browser --auto-connect click @e1

# Or via environment variable
export AGENT_BROWSER_AUTO_CONNECT=1
agent-browser snapshot
Auto-connect discovers Chrome by:
  1. Reading Chrome’s DevToolsActivePort file from the default user data directory
  2. Falling back to probing common debugging ports (9222, 9229)
This is useful when Chrome 144+ has remote debugging enabled via chrome://inspect/#remote-debugging (which uses a dynamic port).

CDP Endpoint Format

The --cdp flag accepts either a port number or a full WebSocket URL:

Port Number (Local)

# Connects to http://localhost:9222
agent-browser --cdp 9222 snapshot
From src/browser.ts:1515-1518:
if (/^\d+$/.test(cdpEndpoint)) {
  // Port number - connect to localhost
  cdpUrl = `http://localhost:${cdpEndpoint}`;
}

WebSocket URL (Local or Remote)

# Connect to remote browser via WebSocket
agent-browser --cdp "wss://your-browser-service.com/cdp?token=..." snapshot

# Connect to local Chrome via WebSocket
agent-browser --cdp "ws://localhost:9222/devtools/browser/..." snapshot
From src/browser.ts:1509-1514:
if (
  cdpEndpoint.startsWith('ws://') ||
  cdpEndpoint.startsWith('wss://') ||
  cdpEndpoint.startsWith('http://') ||
  cdpEndpoint.startsWith('https://')
) {
  cdpUrl = cdpEndpoint;
}

Starting Chrome with Remote Debugging

macOS

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
  --remote-debugging-port=9222

Linux

google-chrome --remote-debugging-port=9222
# or
chromium --remote-debugging-port=9222

Windows

"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222

Headless Chrome

chrome --headless --remote-debugging-port=9222

Connection Lifecycle

CDP connections persist in the daemon across multiple commands:
# First command establishes connection
agent-browser --cdp 9222 open example.com

# Subsequent commands reuse the connection
agent-browser --cdp 9222 snapshot
agent-browser --cdp 9222 click @e1

# Close disconnects and shuts down daemon
agent-browser --cdp 9222 close
From src/browser.ts:1550, the CDP endpoint is cached:
this.cdpEndpoint = cdpEndpoint;
Reconnection is triggered if the endpoint changes (see src/browser.ts:854-857):
private needsCdpReconnect(cdpEndpoint: string): boolean {
  // Reconnect if endpoint changed
  if (this.cdpEndpoint !== cdpEndpoint) return true;
  // ... connection health checks ...
}

Auto-Connect Discovery

Auto-connect attempts multiple discovery strategies in order:

1. DevToolsActivePort File

Reads the WebSocket URL from Chrome’s active port file (Chrome 144+):
private readDevToolsActivePort(userDataDir: string): { port: number; wsPath: string } | null {
  const filePath = path.join(userDataDir, 'DevToolsActivePort');
  // ...
}
From src/browser.ts:1609-1610.

2. Port Probing

Probes common debugging ports (9222, 9229) if the file doesn’t exist:
# Check if any debuggable instance is running on default ports
curl http://localhost:9222/json/version
See src/browser.ts:1655-1691 for the full auto-connect implementation.

Limitations

No Profile Support

Profiles cannot be used with CDP connections because the remote browser already has its own profile:
# This will fail
agent-browser --profile ./profile --cdp 9222 open example.com
# Error: Profile cannot be used with CDP connection
From src/browser.ts:1204-1206:
if (hasProfile && cdpEndpoint) {
  throw new Error('Profile cannot be used with CDP connection');
}

No Extension Support

Extensions cannot be loaded via CDP connections:
# This will fail
agent-browser --extension ./my-ext --cdp 9222 open example.com
# Error: Extensions cannot be used with CDP connection
From src/browser.ts:1200-1202.

Download Path Ignored

The --download-path flag is ignored with CDP connections because downloads use the remote browser’s configuration:
agent-browser --download-path ./downloads --cdp 9222 open example.com
# Warning: --download-path is ignored when connecting via CDP
From src/browser.ts:1252-1257.

Page Switching

CDP sessions are page-specific. Switching pages invalidates the current CDP session: From src/browser.ts:1830-1858:
private async invalidateCDPSession(): Promise<void> {
  // Stop screencast if active (it's tied to the current page's CDP session)
  if (this.screencastActive) {
    await this.stopScreencast();
  }

  // Detach and clear the CDP session
  if (this.cdpSession) {
    try {
      await this.cdpSession.detach();
    } catch {
      // Session may already be detached
    }
    this.cdpSession = null;
  }
}
The next command automatically creates a new CDP session for the active page (see src/browser.ts:1921-1930).

Advanced Features

Screencast (Live Preview)

CDP mode supports screencasting for live browser preview:
# Enable streaming on port 9223
export AGENT_BROWSER_STREAM_PORT=9223
agent-browser --cdp 9222 open example.com

# Connect to ws://localhost:9223 to receive frames
From src/browser.ts:1942-1997, screencast uses CDP’s Page.startScreencast command.

Input Injection

CDP mode supports direct input injection (mouse, keyboard, touch) via the stream server or programmatically:
await browser.injectMouseEvent({
  type: 'mousePressed',
  x: 100,
  y: 200,
  button: 'left',
});
From src/browser.ts:2164-2228.

CDP Profiling

Use CDP’s Tracing API for performance profiling:
agent-browser --cdp 9222 profiler start
agent-browser --cdp 9222 open example.com
agent-browser --cdp 9222 profiler stop ./profile.json
From src/browser.ts:2021-2162.

Use Cases

Electron Apps

Control Electron apps that expose a CDP endpoint:
# Start Electron app with debugging
electron . --remote-debugging-port=9222

# Connect and automate
agent-browser --cdp 9222 snapshot
agent-browser --cdp 9222 click @e1

Browser Extensions Development

Test browser extensions in a real Chrome instance:
# Start Chrome with extension and remote debugging
chrome --load-extension=./my-extension --remote-debugging-port=9222

# Automate testing
agent-browser --cdp 9222 open chrome://extensions
agent-browser --cdp 9222 snapshot

WebView2 Apps

Connect to WebView2 applications on Windows:
# WebView2 apps typically expose CDP on a dynamic port
# Use auto-connect or discover the port manually
agent-browser --auto-connect snapshot

Remote Browser Services

Connect to remote browsers provided by cloud services:
# Browserbase (uses CDP internally)
agent-browser -p browserbase open example.com

# Browser Use (uses CDP internally)
agent-browser -p browseruse open example.com

# Kernel (uses CDP internally)
agent-browser -p kernel open example.com
These providers use CDP under the hood (see src/browser.ts:908-1153 for implementation).

Security Considerations

Localhost Only

When starting Chrome with --remote-debugging-port, the debugger binds to localhost by default:
# Safe - localhost only
chrome --remote-debugging-port=9222

# Dangerous - exposed to network!
chrome --remote-debugging-port=9222 --remote-debugging-address=0.0.0.0
Never expose the debugging port to the network without authentication.

Authentication

The Chrome DevTools Protocol does not require authentication by default. Anyone with network access to the debugging port has full control of the browser. For remote CDP connections, use:
  • TLS (wss://) to encrypt the connection
  • Token-based authentication in the WebSocket URL
  • Network-level security (VPN, SSH tunnel, firewall)

CDP Session Isolation

Each CDP session can control all pages in the browser. For security-sensitive automation, launch a dedicated browser instance:
# Dedicated instance for automation
chrome --user-data-dir=/tmp/automation-profile --remote-debugging-port=9222

Troubleshooting

Connection Refused

Failed to connect via CDP to http://localhost:9222
Solutions:
  1. Verify Chrome is running with --remote-debugging-port=9222
  2. Check if the port is actually listening: lsof -i :9222 (macOS/Linux) or netstat -ano | findstr :9222 (Windows)
  3. Try a different port if 9222 is already in use

Connection Dropped

If the remote browser crashes or restarts, the CDP connection is lost. Reconnect with:
agent-browser close  # Clean up stale connection
agent-browser --cdp 9222 open example.com  # Reconnect

Auto-Connect Not Working

Auto-connect requires Chrome to be running with remote debugging enabled. If it fails:
  1. Manually enable remote debugging in chrome://inspect/#remote-debugging
  2. Or start Chrome with --remote-debugging-port=9222
  3. Use --cdp 9222 explicitly instead of --auto-connect

Build docs developers (and LLMs) love