# How MCP Selects Chrome Channels (Stable, Beta, Dev, Canary)

> Discover how MCP selects Chrome channels like Stable, Beta, Dev, and Canary. Learn about the --channel CLI flag and its role in Puppeteer-compatible Chrome release identifiers.

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

---

**MCP selects Chrome channels through the `--channel` CLI flag, which defaults to `stable` and translates internal values into Puppeteer-compatible Chrome release identifiers.**

The Chrome DevTools MCP server allows developers to automate browser interactions across different Chrome release channels. Understanding how the Model Context Protocol (MCP) implementation in the `ChromeDevTools/chrome-devtools-mcp` repository handles channel selection ensures you target the correct browser binary for your automation tasks.

## The `--channel` CLI Flag and Default Behavior

MCP exposes channel selection as a first-class CLI argument with strict validation and sensible defaults.

### Allowed Channel Values

The flag accepts four specific string values defined in [`src/cli.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/cli.ts) (lines 12-19):

- `stable` – The standard release channel
- `beta` – The beta release channel
- `dev` – The developer release channel  
- `canary` – The canary (nightly) release channel

These values are enforced at the argument parsing level, preventing invalid channel specifications from propagating through the system.

### Defaulting to Stable

When you launch MCP without specifying a channel, the `parseArguments` function in [`src/cli.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/cli.ts) (lines 44-50) automatically injects `stable` as the default value. This ensures predictable behavior across different environments without requiring explicit configuration for standard use cases.

## How the Channel Selection Flows Through the Codebase

The channel parameter travels through three main architectural layers before reaching the browser automation engine.

### CLI Argument Parsing ([`src/cli.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/cli.ts))

The entry point validates and normalizes the `--channel` input. The argument definition uses a typed string constraint that limits inputs to the four supported channels, failing fast with a clear error message if users attempt to pass unsupported values like "nightly" or "enterprise".

### Auto-Connect Mode ([`src/main.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/main.ts))

In [`src/main.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/main.ts) (lines 94-96), the channel value is conditionally forwarded to the browser connection logic:

- **When `--auto-connect` is enabled**: The channel is passed to `ensureBrowserConnected` to locate the correct running Chrome instance
- **When `--auto-connect` is disabled**: The channel parameter is omitted from the connection options, as MCP assumes manual browser management

This conditional logic prevents channel conflicts when users manage their own browser lifecycle.

### Browser Connection and Launch ([`src/browser.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/browser.ts))

The [`src/browser.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/browser.ts) file contains the core translation logic that converts MCP channel names into Puppeteer-compatible identifiers. This file handles two distinct modes:

1. **Connection mode** (`ensureBrowserConnected`, lines 108-110): Translates the channel for attaching to existing processes
2. **Launch mode** (lines 81-90): Translates the channel for spawning new browser instances

Both paths use identical channel mapping logic to ensure consistency between connecting to existing Chrome processes and launching fresh ones.

## Channel-to-Puppeteer Translation Logic

MCP abstracts Chrome's release channels into a format that Puppeteer understands, handling the naming discrepancies between the two systems.

### The Channel Mapping Algorithm

In [`src/browser.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/browser.ts) (lines 108-110), MCP implements a conditional mapping:

- **`stable`** → `'chrome'` (Puppeteer's default stable identifier)
- **`beta`, `dev`, `canary`** → `` `chrome-${channel}` `` (e.g., `'chrome-canary'`, `'chrome-beta'`)

This translation allows Puppeteer to locate the correct binary in system paths without requiring users to memorize Puppeteer's specific naming conventions.

### User Data Directory Isolation

The channel selection also influences profile management. In [`src/browser.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/browser.ts) (lines 54-56), MCP constructs the user data directory path based on the channel:

- **Stable channel**: Uses `chrome-profile` (simple, unqualified name)
- **Other channels**: Uses `chrome-profile-${channel}` (e.g., `chrome-profile-canary`)

This isolation prevents cross-channel contamination of cookies, local storage, and browser settings when switching between different Chrome versions.

## Practical Usage Examples

### CLI Examples

Launch MCP with specific Chrome channels using the `--channel` flag:

```bash

# Default behavior (stable channel)

npx chrome-devtools-mcp

# Connect to Chrome Canary

npx chrome-devtools-mcp --channel canary

# Auto-connect to an existing Beta instance

npx chrome-devtools-mcp --auto-connect --channel beta

# Launch with Dev channel in headless mode

npx chrome-devtools-mcp --channel dev --headless

```

### Programmatic API Examples

When embedding MCP in your own applications, pass the channel parameter through the browser management functions:

```typescript
import { ensureBrowserLaunched, ensureBrowserConnected } from 'chrome-devtools-mcp/src/browser.js';

// Launch a new Dev channel instance
await ensureBrowserLaunched({
  channel: 'dev',
  headless: false,
  isolated: true
});

// Attach to an existing Canary process
await ensureBrowserConnected({
  channel: 'canary',
  devtools: true,
  autoConnect: true
});

```

The programmatic interface accepts the same four channel values (`stable`, `beta`, `dev`, `canary`) and applies identical translation logic before passing instructions to Puppeteer.

## Summary

- MCP uses the **`--channel`** CLI flag to determine which Chrome release to automate, defaulting to **`stable`** when unspecified.
- Four channels are supported: **stable**, **beta**, **dev**, and **canary**, validated at the argument parsing stage in [`src/cli.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/cli.ts).
- The channel value translates to Puppeteer identifiers: `stable` becomes `'chrome'`, while other channels become `'chrome-${channel}'` (e.g., `'chrome-canary'`).
- Channel selection affects **user data directory isolation**, with non-stable channels receiving distinct profile folders (`chrome-profile-${channel}`) to prevent cross-version contamination.
- In auto-connect mode, the channel helps locate existing browser processes; in launch mode, it determines which binary Puppeteer spawns.

## Frequently Asked Questions

### What happens if I don't specify a channel when running MCP?

If you omit the `--channel` flag, MCP automatically defaults to the `stable` channel. The `parseArguments` function in [`src/cli.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/cli.ts) (lines 44-50) explicitly injects `stable` as the default value during CLI initialization, ensuring consistent behavior across different environments without requiring manual configuration.

### Can I use MCP with Chrome Canary on macOS?

Yes, MCP fully supports Chrome Canary on macOS through the `--channel canary` flag. When specified, MCP translates `canary` into Puppeteer's `chrome-canary` identifier in [`src/browser.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/browser.ts) (lines 108-110), which Puppeteer then maps to the macOS application bundle at `/Applications/Google Chrome Canary.app`. MCP also creates an isolated user data directory named `chrome-profile-canary` to prevent profile conflicts with other channels.

### How does MCP handle user data directories for different channels?

MCP isolates browser profiles by channel to prevent data leakage between different Chrome versions. In [`src/browser.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/browser.ts) (lines 54-56), the logic checks the channel value: if it is `stable`, MCP uses the directory name `chrome-profile`; for any other channel (`beta`, `dev`, or `canary`), it appends the channel name to create `chrome-profile-${channel}`. This ensures that cookies, local storage, and extensions remain separate when switching between channels.

### Is the channel parameter used when auto-connect is disabled?

No, when `--auto-connect` is disabled, MCP intentionally omits the channel parameter from the browser connection options. In [`src/main.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/main.ts) (lines 94-96), the code only passes the channel value to `ensureBrowserConnected` when the `autoConnect` flag is true. This design assumes that users managing their own browser lifecycle (manual launch) are responsible for ensuring the correct Chrome binary is running, whereas auto-connect mode needs the channel hint to locate the appropriate process among potentially multiple running Chrome instances.