Skip to main content
Glama

Chrome DevTools MCP

Official
parse.ts4.09 kB
/** * @license * Copyright 2025 Google LLC * SPDX-License-Identifier: Apache-2.0 */ import {PerformanceTraceFormatter} from '../../node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.js'; import {PerformanceInsightFormatter} from '../../node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.js'; import * as TraceEngine from '../../node_modules/chrome-devtools-frontend/front_end/models/trace/trace.js'; import {logger} from '../logger.js'; import {AgentFocus} from '../../node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/performance/AIContext.js'; const engine = TraceEngine.TraceModel.Model.createWithAllHandlers(); export interface TraceResult { parsedTrace: TraceEngine.TraceModel.ParsedTrace; insights: TraceEngine.Insights.Types.TraceInsightSets | null; } export function traceResultIsSuccess( x: TraceResult | TraceParseError, ): x is TraceResult { return 'parsedTrace' in x; } export interface TraceParseError { error: string; } export async function parseRawTraceBuffer( buffer: Uint8Array<ArrayBufferLike> | undefined, ): Promise<TraceResult | TraceParseError> { engine.resetProcessor(); if (!buffer) { return { error: 'No buffer was provided.', }; } const asString = new TextDecoder().decode(buffer); if (!asString) { return { error: 'Decoding the trace buffer returned an empty string.', }; } try { const data = JSON.parse(asString) as | { traceEvents: TraceEngine.Types.Events.Event[]; } | TraceEngine.Types.Events.Event[]; const events = Array.isArray(data) ? data : data.traceEvents; await engine.parse(events); const parsedTrace = engine.parsedTrace(); if (!parsedTrace) { return { error: 'No parsed trace was returned from the trace engine.', }; } const insights = parsedTrace?.insights ?? null; return { parsedTrace, insights, }; } catch (e) { const errorText = e instanceof Error ? e.message : JSON.stringify(e); logger(`Unexpeced error parsing trace: ${errorText}`); return { error: errorText, }; } } export function getTraceSummary(result: TraceResult): string { const focus = AgentFocus.full(result.parsedTrace); const serializer = new TraceEngine.EventsSerializer.EventsSerializer(); const formatter = new PerformanceTraceFormatter(focus, serializer); const output = formatter.formatTraceSummary(); return output; } export type InsightName = keyof TraceEngine.Insights.Types.InsightModels; export type InsightOutput = {output: string} | {error: string}; export function getInsightOutput( result: TraceResult, insightName: InsightName, ): InsightOutput { if (!result.insights) { return { error: 'No Performance insights are available for this trace.', }; } // Currently, we do not support inspecting traces with multiple navigations. We either: // 1. Find Insights from the first navigation (common case: user records a trace with a page reload to test load performance) // 2. Fall back to finding Insights not associated with a navigation (common case: user tests an interaction without a page load). const mainNavigationId = result.parsedTrace.data.Meta.mainFrameNavigations.at(0)?.args.data ?.navigationId; const insightsForNav = result.insights.get( mainNavigationId ?? TraceEngine.Types.Events.NO_NAVIGATION, ); if (!insightsForNav) { return { error: 'No Performance Insights for this trace.', }; } const matchingInsight = insightName in insightsForNav.model ? insightsForNav.model[insightName] : null; if (!matchingInsight) { return { error: `No Insight with the name ${insightName} found. Double check the name you provided is accurate and try again.`, }; } const formatter = new PerformanceInsightFormatter( result.parsedTrace, matchingInsight, ); return {output: formatter.formatInsight()}; }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ChromeDevTools/chrome-devtools-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server