Chrome DevTools MCP Server

repository·main·Indexed 13 days ago

https://github.com/chromedevtools/chrome-devtools-mcp

An MCP server (version 1.7.0) that enables AI coding assistants like Claude, Cursor, and Copilot to interact with a live Chrome browser. It provides capabilities for performance analysis, advanced debugging of network requests and console messages, and reliable browser automation using Puppeteer.

Tokens
42.2K
Snippets
129
Records
204
Agent score
99%

What's inside Chrome DevTools MCP

  1. Overview of Chrome DevTools for agents

    main

    The chrome-devtools-mcp package allows AI coding agents (such as Claude, Cursor, Copilot, or Antigravity) to control and inspect a live Chrome browser instance. It functions as a Model-Context-Protocol (MCP) server, providing agents with access to Chrome DevTools for automation, debugging, and performance analysis.

    Key capabilities include:

    • Performance Insights: Recording traces and extracting insights using Chrome DevTools.
    • Advanced Debugging: Analyzing network requests, capturing screenshots, and inspecting browser console messages (including source-mapped stack traces).
    • Reliable Automation: Using Puppeteer to perform browser actions with automatic waiting for results.
  2. Isolate Chrome profiles with --isolated

    main
    By default, chrome-devtools-mcp reuses a persistent user data directory for the same Chrome channel. To prevent multiple MCP client sessions from sharing the same user data directory, or to ensure a clean environment that is automatically cleared after the browser closes, pass the --isolated flag. This launches each session with a temporary user data directory.
  3. Handle concurrent sessions with --experimentalPageIdRouting

    main

    If your MCP client shares a single server instance across multiple concurrent agents or subagents, use the --experimentalPageIdRouting flag. This flag exposes a pageId on page-scoped tools, allowing each agent to route its tool calls to the specific tab it is currently working with, preventing cross-agent interference.

    {
      "mcpServers": {
        "chrome-devtools": {
          "command": "npx",
          "args": [
            "-y",
            "chrome-devtools-mcp@latest",
            "--experimentalPageIdRouting"
          ]
        }
      }
    }
  4. Understand Chrome DevTools MCP user data directories

    main

    The server uses a dedicated user data directory for Chrome's stable channel. This directory is reused between runs unless --isolated is used.

    Default paths:

    • Linux / macOS: $HOME/.cache/chrome-devtools-mcp/chrome-profile
    • Windows: %USERPROFILE%\/.cache/chrome-devtools-mcp/chrome-profile

    For non-stable channels (like Canary), the channel name is appended to the directory (e.g., chrome-profile-canary).

  5. How the Chrome DevTools CLI daemon works

    main

    The CLI operates as a client to a background chrome-devtools-mcp daemon. The daemon uses Unix sockets on Linux/Mac and named pipes on Windows to maintain communication.

    Key Behaviors

    • Automatic Start: The daemon and the browser start automatically the first time you call a tool (e.g., list_pages) if they are not already running.
    • Persistence: The background instance is reused across commands, meaning browser state (cookies, open pages, etc.) is preserved.
    • Manual Control: You can manage the lifecycle of the background process using start, stop, and status commands.
    • Default Modes: Headless mode and isolated mode are enabled by default. You can disable isolation by providing a --userDataDir flag during start.
    # Check if the daemon is running
    chrome-devtools status
    
    # Stop the background daemon when finished
    chrome-devtools stop
  6. How the Chrome DevTools MCP workflow works

    main

    The chrome-devtools skill operates on a specific lifecycle and interaction model:

    Browser Lifecycle

    The browser starts automatically on the first tool call using a persistent Chrome profile.

    Page Selection

    Tools operate on the currently selected page. You must manage context using:

    1. list_pages: To see all available pages.
    2. select_page: To switch the active context to a specific page.

    Element Interaction

    Interaction is driven by unique identifiers. Use take_snapshot to retrieve the page structure. Each element in the snapshot contains a unique uid. Use these uids for interaction tools like click or fill.

    Note: If an element is not found, the page state may have changed. You should take a fresh snapshot to get updated uids before retrying.

  7. Identify elements considered for Largest Contentful Paint (LCP)

    main

    When debugging LCP, the following element types are candidates for the Largest Contentful Paint metric:

    • <img> elements: For animated content like GIFs, the first frame presentation time is used.
    • <image> elements: Specifically those located inside an <svg> element.
    • <video> elements: The metric uses either the poster image load time or the first frame presentation time, whichever occurs earlier.
    • Background images: Any element that loads a background image via the url() CSS property.
    • Block-level elements: Elements that contain text nodes or children that are inline-level text elements.
  8. Understand Accessibility Tree vs DOM

    main

    When debugging accessibility, distinguish between the DOM and the Accessibility Tree. While the DOM represents the full HTML structure, the Accessibility Tree represents what assistive technologies (like screen readers) actually 'see'.

    Key distinction: Visual hiding techniques behave differently. For example, CSS opacity: 0 keeps an element in the accessibility tree, whereas display: none or aria-hidden="true" removes it. Use the take_snapshot tool to retrieve the accessibility tree, as it is the most reliable source of truth for semantic structure.

  9. Exclude non-contentful elements from LCP analysis

    main

    Chromium-based browsers apply specific heuristics to ignore elements that do not contribute meaningful content to the user experience. When analyzing LCP, be aware that the following are typically excluded:

    • Elements with an opacity of 0.
    • Elements that cover the full viewport (these are often treated as background elements).
    • Placeholder images or images with low entropy.
  10. Capture and analyze memory heap snapshots

    main

    Use the Memory tools to debug memory leaks and analyze JavaScript object distribution. Most memory tools require the --memoryDebugging=true flag to be enabled.

    Core Workflow

    1. Capture: Use take_heapsnapshot to save a .heapsnapshot file from the current page.
    2. Analyze: Use get_heapsnapshot_details or get_heapsnapshot_summary to view statistics and aggregated node information.
    3. Compare: Use compare_heapsnapshots to find differences between an earlier (baseFilePath) and later (currentFilePath) snapshot.
    4. Inspect Objects: Use get_heapsnapshot_retaining_paths or get_heapsnapshot_dominators to understand why specific nodes are not being garbage collected.
    5. Cleanup: Use close_heapsnapshot to free memory once analysis is complete.
    // Example: Capturing a snapshot
    // Tool: take_heapsnapshot
    {
      "filePath": "/path/to/snapshot.heapsnapshot"
    }
  11. Understand how element size is calculated for LCP

    main

    LCP size calculations depend on the type of element being measured:

    • General Visible Area: The size is determined by what is visible within the viewport. Portions that extend outside the viewport, are clipped, or are part of an overflow do not count.
    • Image Elements: The size is the smaller of either the visible size or the intrinsic size.
    • Text Elements: The size is defined as the smallest rectangle that contains all text nodes.
    • Exclusions: When calculating size, margin, padding, and borders are not included.
    • Text Containment: Every text node is attributed to its closest block-level ancestor element for size calculation.
  12. Understand the four subparts of Largest Contentful Paint (LCP)

    main

    Largest Contentful Paint (LCP) measures the time from page load initiation until the largest image or text block is rendered in the viewport. To provide a good user experience, aim for an LCP of 2.5 seconds or less for at least 75% of page visits. LCP is composed of four distinct, non-overlapping subparts that sum to the total LCP time:

    | LCP subpart | % of LCP (Optimal) | Description |
    | ----------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
    | **Time to First Byte (TTFB)** | ~40% | The time from when the user initiates loading the page until the browser receives the first byte of the HTML document response. |
    | **Resource load delay** | <10% | The time between TTFB and when the browser starts loading the LCP resource. If the LCP element doesn't require a resource load (e.g., system font text), this time is 0. |
    | **Resource load duration** | ~40% | The duration of time it takes to load the LCP resource itself. If the LCP element doesn't require a resource load, this time is 0. |
    | **Element render delay** | <10% | The time between when the LCP resource finishes loading and the LCP element rendering fully. |