# Chrome DevTools MCP Performance Trace Analysis Pipeline: From Start to Insight

> Explore the chrome-devtools-mcp performance trace analysis pipeline. Learn how to capture, process, and analyze browser telemetry for actionable insights and LLM-ready reports.

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

---

**The chrome-devtools-mcp performance trace analysis pipeline is a three-stage workflow that captures browser telemetry through `performance_start_trace`, processes the raw data via `performance_stop_trace` using the DevTools TraceEngine, and extracts actionable metrics with `performance_analyze_insight` to generate LLM-ready performance reports.**

The chrome-devtools-mcp repository provides a Model-Context-Protocol implementation that allows large language models to control Chrome DevTools programmatically. The performance trace analysis pipeline enables automated capture, parsing, and interpretation of browser performance data through a deterministic sequence of tool calls defined in [`src/tools/performance.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/tools/performance.ts) and [`src/trace-processing/parse.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/trace-processing/parse.ts).

## How the Performance Trace Pipeline Works

The pipeline consists of three discrete tools that must be executed in sequence. Each tool is defined in [`src/tools/performance.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/tools/performance.ts) and interacts with the Chrome DevTools Protocol (CDP) through the bundled DevTools front-end libraries.

### Step 1: Starting the Trace with `performance_start_trace`

The `performance_start_trace` tool initiates a Chrome tracing session on the currently selected page. The implementation in [`src/tools/performance.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/tools/performance.ts) (lines 29-71) performs the following operations:

1. **Safety Check**: Calls `Context.isRunningPerformanceTrace()` to ensure only one trace runs concurrently. If a trace is active, the tool returns an error.
2. **State Management**: Marks the trace as active via `context.setIsRunningPerformanceTrace(true)`.
3. **Navigation Handling**: Optionally navigates to `about:blank` and back to the original URL based on the `reload` parameter.
4. **Trace Initiation**: Invokes `page.tracing.start({categories})` with a curated list of DevTools tracing categories (lines 71-84).
5. **Auto-Stop**: If `autoStop` is enabled, waits five seconds then calls the internal helper `stopTracingAndAppendOutput`.

### Step 2: Stopping and Processing with `performance_stop_trace`

The `performance_stop_trace` tool terminates the active tracing session and triggers the processing pipeline. Located in [`src/tools/performance.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/tools/performance.ts) (lines 15-27), this tool:

1. Verifies the running-trace flag through `Context.isRunningPerformanceTrace()`.
2. If no trace is active, returns silently.
3. Invokes `stopTracingAndAppendOutput` to handle the heavy lifting of data retrieval and parsing.

### Step 3: Extracting Insights with `performance_analyze_insight`

The `performance_analyze_insight` tool retrieves specific Performance Insights from the parsed trace data. Implemented in [`src/tools/performance.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/tools/performance.ts) (lines 40-74), the tool:

1. Retrieves the most recent trace from `context.recordedTraces()`.
2. Calls `response.attachTraceInsight(trace, insightSetId, insightName)`.
3. The underlying implementation uses `getInsightOutput` from [`src/trace-processing/parse.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/trace-processing/parse.ts) to look up the insight set by ID, retrieve the concrete insight model, and format it using `DevTools.PerformanceInsightFormatter`.

## Deep Dive: Trace Processing Architecture

The transition from raw binary trace data to structured insights involves several specialized components in [`src/trace-processing/parse.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/trace-processing/parse.ts) and the shared helper functions in [`src/tools/performance.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/tools/performance.ts).

### The `stopTracingAndAppendOutput` Helper

This function in [`src/tools/performance.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/tools/performance.ts) (lines 77-119) orchestrates the post-processing workflow:

| Action | Implementation Detail |
|--------|----------------------|
| Stop Tracing | `await page.tracing.stop()` returns a `Uint8Array` of raw trace events. |
| File Persistence | If `filePath` ends with `.gz`, the buffer is compressed using `zlib.gzip`. The file is saved via `Context.saveFile`. |
| Trace Parsing | Invokes `parseRawTraceBuffer(buffer)` to convert raw bytes into a structured `TraceResult`. |
| CrUX Enrichment | If `--performanceCrux` is enabled, calls `populateCruxData(result)` to query the Chrome UX Report API for each URL in the trace. |
| Result Storage | `context.storeTraceRecording(result)` adds the `TraceResult` to the session history. |
| Summary Generation | `response.attachTraceSummary(result)` appends a human-readable summary generated by `getTraceSummary`. |
| Cleanup | Clears the running-trace flag via `context.setIsRunningPerformanceTrace(false)`. |

### Parsing Raw Traces with `parseRawTraceBuffer`

Located in [`src/trace-processing/parse.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/trace-processing/parse.ts) (lines 27-63), this function interfaces with the DevTools TraceEngine:

1. Resets the shared `TraceEngine` instance via `engine.resetProcessor()`.
2. Decodes the `Uint8Array` to a string and parses the JSON.
3. Normalizes the data to an array of `Event` objects.
4. Feeds events to `engine.parse(events)`.
5. Extracts `engine.parsedTrace()` (a `ParsedTrace` object).
6. Returns both the parsed trace and any insight sets (`parsedTrace.insights`).
7. Wraps errors in `TraceParseError` for consistent error handling.

### Generating Human-Readable Summaries

The `getTraceSummary` function in [`src/trace-processing/parse.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/trace-processing/parse.ts) (lines 73-88) uses DevTools helpers to create markdown output:

```typescript
const focus = DevTools.AgentFocus.fromParsedTrace(parsedTrace);
const formatter = new DevTools.PerformanceTraceFormatter(focus);
const summaryText = formatter.formatTraceSummary();

```

The resulting summary includes a call tree, network request tables, and descriptions of data formats.

### CrUX Data Enrichment

The `populateCruxData` function in [`src/tools/performance.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/tools/performance.ts) (lines 121-158) enhances traces with real-world field data:

1. Builds a set of unique URLs from the trace metadata.
2. Queries the public Chrome UX Report API for each URL.
3. Stores the field data in `result.parsedTrace.metadata.cruxFieldData`.
4. This data is later incorporated into the trace summary formatter to compare lab vs. field metrics.

## Code Examples: Running the Pipeline

### Starting a Trace from an LLM Prompt

```json
{
  "tool": "performance_start_trace",
  "params": {
    "reload": true,
    "autoStop": false,
    "filePath": "trace.json.gz"
  }
}

```

**Effect:** Navigates to `about:blank`, starts tracing with the pre-defined categories, then navigates back to the original page.

### Stopping the Trace Manually

```json
{
  "tool": "performance_stop_trace",
  "params": {
    "filePath": "trace.json.gz"
  }
}

```

**Effect:** The trace is stopped, compressed, saved to `trace.json.gz`, parsed, CrUX data fetched (if enabled), and a markdown summary is attached to the response.

### Getting a Specific Insight

```json
{
  "tool": "performance_analyze_insight",
  "params": {
    "insightSetId": "main",
    "insightName": "LCPBreakdown"
  }
}

```

**Effect:** Returns the formatted insight text for the Largest Contentful Paint breakdown of the most recent trace.

### Full Pipeline in a Single Prompt

```text
Check the performance of https://example.com

```

The MCP client will typically issue the following tool calls internally:

1. `performance_start_trace` (with `reload: true`).
2. Wait for the page to load.
3. `performance_stop_trace` (save as [`trace.json`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/trace.json)).
4. `performance_analyze_insight` (choose an insight from the "Available insight sets" list).

The LLM receives a concise markdown report containing the overall performance summary, call-tree and network tables, and any requested insight details.

## Key Source Files

| File | Role | Link |
|------|------|------|
| [`src/tools/performance.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/tools/performance.ts) | Defines the three performance tools and the shared helper `stopTracingAndAppendOutput`. | [view](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/tools/performance.ts) |
| [`src/trace-processing/parse.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/trace-processing/parse.ts) | Parses raw trace buffers, extracts insights, and produces human-readable summaries. | [view](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/trace-processing/parse.ts) |
| [`src/third_party/index.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/third_party/index.ts) | Re-exports the DevTools front-end libraries (`DevTools`, `zod`, etc.) used by the performance pipeline. | [view](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/third_party/index.ts) |
| [`src/ToolDefinition.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/ToolDefinition.ts) | Provides the type-safe `defineTool` helper and the `Response`/`Context` contracts. | [view](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/tools/ToolDefinition.ts) |
| [`src/McpContext.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/McpContext.ts) | Holds the per-session state (recorded traces, flags, file helpers). | [view](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/McpContext.ts) |
| [`src/logger.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/logger.ts) | Simple logger used throughout the pipeline (e.g., for CrUX errors). | [view](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/logger.ts) |

## Summary

- The **chrome-devtools-mcp performance trace analysis pipeline** consists of three sequential tools: `performance_start_trace`, `performance_stop_trace`, and `performance_analyze_insight`.
- **Trace capture** uses the Chrome DevTools Protocol with a curated category list, enforced by a singleton flag in `McpContext` to prevent concurrent traces.
- **Post-processing** occurs in `stopTracingAndAppendOutput`, which handles gzip compression, file persistence, CrUX API enrichment, and storage of the `TraceResult` in session history.
- **Parsing** leverages the bundled DevTools `TraceEngine` in [`src/trace-processing/parse.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/trace-processing/parse.ts) to convert raw `Uint8Array` buffers into structured `ParsedTrace` objects containing insight sets.
- **Insight extraction** uses `DevTools.PerformanceInsightFormatter` to convert specific performance metrics (like `LCPBreakdown`) into markdown suitable for LLM consumption.

## Frequently Asked Questions

### What tracing categories does `performance_start_trace` use?

The tool initializes tracing with a curated list of DevTools categories specified in [`src/tools/performance.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/tools/performance.ts) (lines 71-84). These categories include essential performance events such as blink, v8, loading, and network timelines, ensuring comprehensive coverage of web performance metrics without overwhelming the trace buffer.

### How does the pipeline prevent concurrent trace sessions?

The implementation uses a boolean flag managed by `McpContext.isRunningPerformanceTrace()` and `context.setIsRunningPerformanceTrace()`. When `performance_start_trace` is invoked, it checks this flag in [`src/tools/performance.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/tools/performance.ts) (lines 29-35) and rejects new requests if a trace is already active, ensuring deterministic resource allocation.

### What is the difference between the trace summary and a performance insight?

The **trace summary** is a comprehensive markdown report generated by `getTraceSummary` in [`src/trace-processing/parse.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/trace-processing/parse.ts) (lines 73-88) using `DevTools.PerformanceTraceFormatter`, containing call trees and network tables. A **performance insight** is a specific metric extracted via `performance_analyze_insight` using `DevTools.PerformanceInsightFormatter`, targeting discrete issues like `LCPBreakdown` or layout shifts.

### How does CrUX enrichment work in the performance pipeline?

When the `--performanceCrux` flag is enabled, the `populateCruxData` function in [`src/tools/performance.ts`](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/src/tools/performance.ts) (lines 121-158) extracts unique URLs from the trace metadata and queries the public Chrome UX Report API. The field data is stored in `result.parsedTrace.metadata.cruxFieldData` and integrated into the trace summary, enabling comparison between lab results and real-world user experiences.