Skip to main content

What is CDP?

The Chrome DevTools Protocol (CDP) is a low-level protocol that enables programmatic control and inspection of Chrome/Chromium browsers. It provides access to:
  • DOM inspection and manipulation
  • Network request interception and modification
  • JavaScript execution and debugging
  • Performance profiling and tracing
  • Emulation (device, geolocation, timezone)
  • Security features (certificate errors, mixed content)
Browser Debugger CLI exposes CDP directly for operations not covered by high-level commands.

CDP Architecture

bdg cdp → Unix Socket → Worker → WebSocket → Chrome DevTools Protocol
Connection details (src/connection/cdp.ts):
  • Transport: WebSocket (typically ws://localhost:9222/devtools/page/{targetId})
  • Protocol: JSON-RPC 2.0 style (method calls with ID-based responses)
  • Domains: 53 domains (Page, Network, DOM, Runtime, etc.)
  • Methods: 300+ methods across all domains

Discovery Features

CDP is self-documenting. Use discovery commands to explore capabilities:

List All Domains

bdg cdp --list
Output (53 domains):
{
  "count": 53,
  "domains": [
    {
      "name": "Network",
      "description": "Network domain allows tracking network activities",
      "commands": 42,
      "events": 18,
      "experimental": false
    },
    {
      "name": "Page",
      "description": "Actions and events related to the inspected page",
      "commands": 67,
      "events": 23,
      "experimental": false
    }
  ]
}

List Methods in a Domain

bdg cdp Network --list
Output (Network domain has 42 methods):
{
  "domain": "Network",
  "count": 42,
  "methods": [
    {
      "name": "getCookies",
      "fullName": "Network.getCookies",
      "description": "Returns all browser cookies",
      "parameterCount": 1,
      "parameters": [
        {"name": "urls", "type": "array", "required": false}
      ],
      "example": "bdg cdp Network.getCookies"
    }
  ]
}

Describe a Method

bdg cdp Network.getCookies --describe
Output (full method schema):
{
  "type": "method",
  "name": "Network.getCookies",
  "domain": "Network",
  "method": "getCookies",
  "description": "Returns all browser cookies for the current URL",
  "parameters": [
    {
      "name": "urls",
      "type": "array",
      "required": false,
      "description": "The list of URLs for which to fetch cookies",
      "items": {"type": "string"}
    }
  ],
  "returns": [
    {
      "name": "cookies",
      "type": "array",
      "description": "Array of cookie objects"
    }
  ],
  "example": {
    "command": "bdg cdp Network.getCookies",
    "description": "Get all cookies for current page"
  }
}

Search Methods by Keyword

bdg cdp --search cookie
Output (all methods matching “cookie”):
{
  "query": "cookie",
  "count": 8,
  "methods": [
    {
      "name": "Network.getCookies",
      "domain": "Network",
      "description": "Returns all browser cookies",
      "example": "bdg cdp Network.getCookies"
    },
    {
      "name": "Network.setCookie",
      "domain": "Network",
      "description": "Sets a cookie with the given data",
      "example": "bdg cdp Network.setCookie --params '{...}'"
    }
  ]
}

Executing CDP Methods

Basic Execution

bdg cdp Runtime.evaluate --params '{"expression":"document.title"}'
Response:
{
  "success": true,
  "data": {
    "method": "Runtime.evaluate",
    "result": {
      "result": {
        "type": "string",
        "value": "Example Domain"
      }
    }
  }
}

Case-Insensitive Method Names

Method names are case-insensitive (src/commands/cdp.ts:105):
# All equivalent:
bdg cdp Network.getCookies
bdg cdp network.getcookies
bdg cdp NETWORK.GETCOOKIES

Methods Without Parameters

bdg cdp Network.getCookies
bdg cdp Page.reload
bdg cdp Runtime.getIsolateId

Methods With Parameters

Parameters must be valid JSON (--params flag):
# Set cookie
bdg cdp Network.setCookie --params '{
  "name": "session_id",
  "value": "abc123",
  "domain": "example.com"
}'

# Navigate to URL
bdg cdp Page.navigate --params '{"url":"https://example.com"}'

# Evaluate JavaScript
bdg cdp Runtime.evaluate --params '{
  "expression": "Array.from(document.querySelectorAll('a')).length",
  "returnByValue": true
}'

Common CDP Domains

Page Domain

Control page lifecycle and navigation:
# Reload page
bdg cdp Page.reload

# Navigate to URL
bdg cdp Page.navigate --params '{"url":"https://example.com"}'

# Get page layout metrics
bdg cdp Page.getLayoutMetrics

# Enable page domain events
bdg cdp Page.enable

Network Domain

Inspect and control network requests:
# Get cookies
bdg cdp Network.getCookies

# Clear browser cookies
bdg cdp Network.clearBrowserCookies

# Get response body for a request
bdg cdp Network.getResponseBody --params '{"requestId":"123.45"}'

# Enable network tracking
bdg cdp Network.enable

Runtime Domain

Execute JavaScript and inspect runtime:
# Evaluate expression
bdg cdp Runtime.evaluate --params '{
  "expression": "document.title",
  "returnByValue": true
}'

# Call function on object
bdg cdp Runtime.callFunctionOn --params '{
  "functionDeclaration": "function() { return this.length; }",
  "objectId": "node-123"
}'

# Get heap usage
bdg cdp Runtime.getHeapUsage

DOM Domain

Inspect and manipulate DOM:
# Get document root
bdg cdp DOM.getDocument

# Query selector
bdg cdp DOM.querySelector --params '{
  "nodeId": 1,
  "selector": "h1"
}'

# Get node attributes
bdg cdp DOM.getAttributes --params '{"nodeId": 123}'

Emulation Domain

Emulate devices and environments:
# Set device metrics
bdg cdp Emulation.setDeviceMetricsOverride --params '{
  "width": 375,
  "height": 667,
  "deviceScaleFactor": 2,
  "mobile": true
}'

# Set geolocation
bdg cdp Emulation.setGeolocationOverride --params '{
  "latitude": 37.7749,
  "longitude": -122.4194,
  "accuracy": 100
}'

# Set timezone
bdg cdp Emulation.setTimezoneOverride --params '{"timezoneId":"America/New_York"}'

Event-Based Domains

Some CDP domains use events instead of request/response patterns (src/commands/cdp.ts:25):
DomainBehaviorNotes
AuditsResults via Audits.issueAdded eventsUse bdg dom eval for direct contrast checking
OverlayVisual feedback only (empty responses)Use Overlay.hideHighlight to clear
ProfilerCall start, perform actions, then stopProfile data returned from stop
TracingData arrives via Tracing.dataCollected eventsCall start, perform actions, then end
Example (Audits domain):
# Enable audits (events will be fired, but not returned here)
bdg cdp Audits.enable

# Alternative: Direct evaluation
bdg dom eval 'getComputedStyle(document.querySelector("p")).color'

Error Handling

Method Not Found

Includes typo suggestions (src/commands/cdp.ts:159):
$ bdg cdp Network.getCookiez
Error: Method 'Network.getCookiez' not found

Did you mean:
  - Network.getCookies
  - Network.deleteCookies
  - Network.setCookie

Use: bdg cdp --search cookie

Invalid Parameters

JSON validation with helpful hints:
$ bdg cdp Network.setCookie --params '{invalid}'
Error: Error parsing --params: Unexpected token i in JSON at position 1

Use: bdg cdp Network.setCookie --describe (to see parameter schema)

CDP Timeout

Commands timeout after 30 seconds (src/connection/cdp.ts:604):
Command timeout: DOM.getDocument

The browser did not respond within 30s.

Possible causes:
  - Browser became unresponsive or frozen
  - Heavy page load or JavaScript execution
  - Network issues or slow connection
Exit code: 102 (CDP_TIMEOUT)

Blocked Methods

Some methods return large binary data that corrupts terminal output (src/commands/cdp.ts:402):
$ bdg cdp Page.captureScreenshot
Error: Page.captureScreenshot is blocked via raw CDP
Reason: Returns large base64 data that corrupts terminal sessions
Use: bdg dom screenshot [path]

Official CDP Documentation

For complete CDP reference:
Discover before implementing: Use --list, --search, and --describe to explore CDP capabilities programmatically before writing automation scripts.
Enable domains first: Many CDP domains require calling Domain.enable before their events or methods work (e.g., Network.enable, Page.enable).

Build docs developers (and LLMs) love