# How DevToolsConnectionAdapter Bridges MCP and Chrome DevTools Protocols

> Learn how DevToolsConnectionAdapter bridges MCP and Chrome DevTools protocols by wrapping Puppeteer CDP sessions for seamless front-end communication.

- Repository: [ChromeDevTools/chrome-devtools-mcp](https://github.com/chromedevtools/chrome-devtools-mcp)
- Tags: internals
- Published: 2026-02-19

---

**The `DevToolsConnectionAdapter` (implemented as `PuppeteerDevToolsConnection`) wraps a Puppeteer CDP session to expose a native Chrome DevTools `CDPConnection` interface, enabling the DevTools front-end to communicate with Chrome through MCP as if it were running inside the browser itself.**

The `ChromeDevTools/chrome-devtools-mcp` repository provides a Model Context Protocol (MCP) server that embeds the Chrome DevTools front-end. At the heart of this integration sits the `DevToolsConnectionAdapter`, which translates between the Puppeteer-based Chrome DevTools Protocol (CDP) sessions and the DevTools UI's native connection expectations.

## What Is DevToolsConnectionAdapter?

The `DevToolsConnectionAdapter` is a protocol translation layer located in [`src/DevToolsConnectionAdapter.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/DevToolsConnectionAdapter.ts). It implements the `DevTools.CDPConnection.CDPConnection` interface expected by the DevTools front-end while internally operating on a `puppeteer.CDPSession`.

This design allows the MCP server to reuse the entire Chrome DevTools front-end codebase without modification. The DevTools UI believes it is talking to a standard Chrome CDP connection, while the adapter forwards all traffic through Puppeteer to the actual browser instance.

## Core Responsibilities of the Adapter

### Wrapping Puppeteer CDP Sessions

The adapter constructor receives a `puppeteer.CDPSession` and extracts its underlying `puppeteer.Connection` for session management. It stores this connection in a private `#connection` field and immediately begins setting up event forwarding.

This initialization occurs in [`src/DevToolsConnectionAdapter.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/DevToolsConnectionAdapter.ts) at lines 19-42, where the adapter also registers listeners for `SessionAttached` and `SessionDetached` events to handle child session lifecycles automatically.

### Forwarding CDP Events to DevTools Observers

For every attached CDP session, the adapter registers a wildcard "`*`" listener via `#startForwardingCdpEvents`. When any CDP event fires, the `#handleEvent` method repackages it as a `DevTools.CDPConnection.Event` object and dispatches it to all registered observers.

This mechanism ensures that DevTools front-end components (Network, Console, Debugger panels) receive real-time updates from the browser. The implementation spans lines 78-111 in [`src/DevToolsConnectionAdapter.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/DevToolsConnectionAdapter.ts).

### Handling DevTools RPC Commands

The `send` method translates DevTools RPC calls into Puppeteer CDP commands. It accepts a method name, parameters, and session ID, then looks up the correct Puppeteer session via `this.#connection.session(sessionId)`.

The method returns a promise that resolves to either `{result: ...}` or `{error: ...}` to match the DevTools connection contract. This implementation at lines 44-67 provides the critical bridge for bidirectional communication.

### Managing Child Session Lifecycles

The adapter automatically handles nested CDP sessions (such as those created for iframes or workers) by listening to `SessionAttached` and `SessionDetached` events on the root session. When a child session attaches, the adapter immediately begins forwarding its events; when it detaches, cleanup occurs automatically.

This eliminates the need for MCP to manually manage a tree of sessions, simplifying the architecture while supporting complex page structures with multiple execution contexts.

## How DevToolsConnectionAdapter Fits Into the MCP Architecture

The integration follows a clear pipeline from MCP server to DevTools UI:

1. **Session Creation**: In [`src/DevtoolsUtils.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/DevtoolsUtils.ts), the MCP server creates a Puppeteer CDP session via `await page.createCDPSession()`.

2. **Adapter Instantiation**: The code wraps this session in a `PuppeteerDevToolsConnection` (the adapter class) and builds a DevTools "universe" around it.

3. **Target Registration**: The adapter is passed to the DevTools `TargetManager` via `targetManager.createTarget(..., connection)`. The TargetManager now treats the MCP connection as a standard Chrome CDP connection.

4. **Observer Registration**: DevTools subsystems (Network, Console, etc.) register as observers on the connection to receive browser events.

5. **Bidirectional Flow**: Commands flow from DevTools UI → adapter → Puppeteer → Chrome, while events flow Chrome → Puppeteer → adapter → DevTools observers.

## Code Examples

### Sending DevTools Commands Through the Adapter

```typescript
import { PuppeteerDevToolsConnection } from './DevToolsConnectionAdapter.js';

// Assume `session` is a puppeteer.CDPSession
const connection = new PuppeteerDevToolsConnection(session);

async function enableNetworkMonitoring(sessionId: string) {
  const { result, error } = await connection.send(
    'Network.enable',
    {},
    sessionId
  );
  
  if (error) {
    throw new Error(`CDP command failed: ${error.message}`);
  }
  
  console.log('Network domain enabled:', result);
}

```

### Observing Network Events

```typescript
class NetworkEventLogger implements DevTools.CDPConnection.CDPConnectionObserver {
  onEvent(event: DevTools.CDPConnection.Event): void {
    if (event.method === 'Network.requestWillBeSent') {
      console.log('Outgoing request:', event.params.request.url);
    }
    
    if (event.method === 'Network.responseReceived') {
      console.log('Response received:', event.params.response.status);
    }
  }
}

// Register the observer on the adapter connection
const logger = new NetworkEventLogger();
connection.observe(logger);

// To stop listening:
// connection.unobserve(logger);

```

## Key Source Files

| File | Role in the Bridge | Location |
|------|-------------------|----------|
| [`src/DevToolsConnectionAdapter.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/DevToolsConnectionAdapter.ts) | Implements `PuppeteerDevToolsConnection` with event forwarding, command dispatch, and session lifecycle management. | [View on GitHub](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/DevToolsConnectionAdapter.ts) |
| [`src/DevtoolsUtils.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/DevtoolsUtils.ts) | Factory that creates Puppeteer CDP sessions and wraps them in the adapter before passing to DevTools TargetManager. | [View on GitHub](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/DevtoolsUtils.ts) |
| [`src/McpContext.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/McpContext.ts) | Maintains the high-level MCP server context that coordinates between the DevTools universe and MCP protocol handlers. | [View on GitHub](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/McpContext.ts) |
| [`src/third_party/index.js`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/third_party/index.js) | Re-exports Puppeteer types and DevTools type definitions required for the adapter's interface implementations. | [View on GitHub](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/third_party/index.js) |

## Summary

- **DevToolsConnectionAdapter** (`PuppeteerDevToolsConnection`) wraps Puppeteer CDP sessions to expose a native DevTools `CDPConnection` interface.
- **Event forwarding** uses wildcard listeners on all sessions to push browser events to DevTools observers in real-time.
- **Command dispatch** translates DevTools RPC calls into Puppeteer `session.send()` calls, handling promise resolution and error formatting.
- **Automatic session management** handles child sessions (iframes, workers) via `SessionAttached`/`SessionDetached` events without manual intervention.
- **Integration point** resides in [`src/DevtoolsUtils.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/DevtoolsUtils.ts), where the adapter connects the Puppeteer layer to the DevTools `TargetManager`.

## Frequently Asked Questions

### What is the difference between DevToolsConnectionAdapter and a standard CDP connection?

A standard CDP connection typically runs inside Chrome itself, where the DevTools front-end directly communicates with the browser's debugging protocol. The **DevToolsConnectionAdapter** is a translation layer that sits between the DevTools front-end and a Puppeteer-controlled browser session. It implements the same `CDPConnection` interface that DevTools expects, but internally forwards all traffic through Puppeteer's CDP session management rather than Chrome's native bindings.

### How does the adapter handle multiple browsing contexts like iframes?

The adapter automatically manages child sessions through the `SessionAttached` and `SessionDetached` CDP events. When the browser creates a new execution context (such as an iframe or web worker), the root session emits a `SessionAttached` event. The adapter's constructor registers listeners for these events and immediately begins forwarding events from newly attached sessions to registered observers. When a context is destroyed, `SessionDetached` triggers cleanup, removing the session from the forwarding pool without requiring manual intervention from MCP code.

### Can I use DevToolsConnectionAdapter with browsers other than Chrome?

The adapter is designed specifically for **Puppeteer CDP sessions**, which means it works with any browser that Puppeteer supports and that implements the Chrome DevTools Protocol. This includes Chromium, Chrome, and potentially other Chromium-based browsers that expose CDP endpoints. However, the adapter depends on Puppeteer's specific CDP session implementation (`puppeteer.CDPSession`), so it cannot be used directly with non-Puppeteer CDP clients or browsers that do not support the Chrome DevTools Protocol.

### Where does the bidirectional translation happen in the source code?

Bidirectional translation occurs in two primary locations within [`src/DevToolsConnectionAdapter.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/DevToolsConnectionAdapter.ts). **Incoming events** from the browser are handled by the `#handleEvent` private method (lines 94-111), which repackages raw CDP events into `DevTools.CDPConnection.Event` objects and dispatches them to observers. **Outgoing commands** from the DevTools UI are processed by the `send` method (lines 44-67), which translates DevTools RPC calls into Puppeteer `session.send()` invocations and formats the responses into the `{result}` or `{error}` structures expected by the DevTools front-end.