> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/vercel-labs/agent-browser/llms.txt
> Use this file to discover all available pages before exploring further.

# CDP Mode

> Connect to existing browsers via Chrome DevTools Protocol

## 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

```bash theme={null}
# 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:

```bash theme={null}
# 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)

```bash theme={null}
# Connects to http://localhost:9222
agent-browser --cdp 9222 snapshot
```

From `src/browser.ts:1515-1518`:

```typescript theme={null}
if (/^\d+$/.test(cdpEndpoint)) {
  // Port number - connect to localhost
  cdpUrl = `http://localhost:${cdpEndpoint}`;
}
```

### WebSocket URL (Local or Remote)

```bash theme={null}
# 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`:

```typescript theme={null}
if (
  cdpEndpoint.startsWith('ws://') ||
  cdpEndpoint.startsWith('wss://') ||
  cdpEndpoint.startsWith('http://') ||
  cdpEndpoint.startsWith('https://')
) {
  cdpUrl = cdpEndpoint;
}
```

## Starting Chrome with Remote Debugging

### macOS

```bash theme={null}
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
  --remote-debugging-port=9222
```

### Linux

```bash theme={null}
google-chrome --remote-debugging-port=9222
# or
chromium --remote-debugging-port=9222
```

### Windows

```powershell theme={null}
"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222
```

### Headless Chrome

```bash theme={null}
chrome --headless --remote-debugging-port=9222
```

## Connection Lifecycle

CDP connections persist in the daemon across multiple commands:

```bash theme={null}
# 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:

```typescript theme={null}
this.cdpEndpoint = cdpEndpoint;
```

Reconnection is triggered if the endpoint changes (see `src/browser.ts:854-857`):

```typescript theme={null}
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+):

```typescript theme={null}
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:

```bash theme={null}
# 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:

```bash theme={null}
# 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`:

```typescript theme={null}
if (hasProfile && cdpEndpoint) {
  throw new Error('Profile cannot be used with CDP connection');
}
```

### No Extension Support

Extensions cannot be loaded via CDP connections:

```bash theme={null}
# 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:

```bash theme={null}
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`:

```typescript theme={null}
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:

```bash theme={null}
# 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:

```typescript theme={null}
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:

```bash theme={null}
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:

```bash theme={null}
# 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:

```bash theme={null}
# 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:

```bash theme={null}
# 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:

```bash theme={null}
# 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:

```bash theme={null}
# 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:

```bash theme={null}
# 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:

```bash theme={null}
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`
