Skip to Content
MCP server

MCP server

The CLI includes a Model Context Protocol (opens in a new tab) server, so an AI agent calls the snippets as tools instead of reading their source or writing its own measurement code. It opens the page in a headless Chromium, runs the published snippet and returns the object the snippet returns, which follows the result contract (opens in a new tab).

npx -y webperf-snippets mcp

The server runs over stdio: the client starts this command and talks to it through its standard input and output. It is listed in the MCP Registry (opens in a new tab) as io.github.nucliweb/webperf-snippets.

Install

The server needs Node.js 20.12 or later and the Chromium of Playwright, which npx does not download:

npx playwright install chromium

Without it, the tools answer with that same command, and an agent with a terminal can run it and call the tool again.

Claude Code

claude mcp add webperf -- npx -y webperf-snippets mcp

Or install the webperf plugin, which adds the same server with the major version of the CLI pinned, so a breaking release does not reach it:

/plugin install webperf --marketplace nucliweb/webperf-snippets

On Claude Code versions before 2.1.275, add the marketplace first with /plugin marketplace add nucliweb/webperf-snippets, then run /plugin install webperf@webperf-snippets.

Cursor, Claude Desktop, Gemini CLI and Antigravity

These clients read a JSON file with an mcpServers object:

ClientFile
Cursor.cursor/mcp.json in the project, or ~/.cursor/mcp.json for every project
Claude Desktopclaude_desktop_config.json, opened from Settings → Developer → Edit Config
Gemini CLI.gemini/settings.json in the project, or ~/.gemini/settings.json
Antigravity.agents/mcp_config.json in the workspace, or ~/.gemini/config/mcp_config.json; in the editor, MCP Servers → Manage MCP Servers → View raw config
{ "mcpServers": { "webperf": { "command": "npx", "args": ["-y", "webperf-snippets", "mcp"] } } }

VS Code

.vscode/mcp.json in the workspace, or the mcp.json of the user profile, names the object servers and requires the transport:

{ "servers": { "webperf": { "type": "stdio", "command": "npx", "args": ["-y", "webperf-snippets", "mcp"] } } }

Tools

ToolWhat it does
list_snippetsLists the snippets with their category, title, short aliases and whether they track interactions. Takes an optional category.
run_snippetOpens a URL in a headless Chromium, runs one snippet and returns the object it returns. Takes url, snippet (name, alias or Category/Name), and optional viewport and waitMs.
run_workflowRuns a workflow (core-web-vitals, audit, loading, interaction) and the follow-ups of its decision tree, such as LCP-Subparts when LCP is over 2.5 s. Takes url, workflow, and optional viewport and waitMs.
get_cruxReturns the CrUX p75 of LCP, CLS and INP for a URL, or for its origin. Takes url and an optional formFactor (phone, desktop, tablet).
open_pageOpens a URL in a page that stays open between calls and installs tracking snippets (track, such as INP). Returns a sessionId.
interactRuns steps on an open page: click, type, hover, scroll or wait.
read_resultsReturns what the tracking snippets of an open page have recorded.
close_pageCloses an open page.

The tools take http and https URLs, local servers such as http://localhost:3000 included, and refuse any other protocol, such as file://. The agent chooses the URLs, so it can reach what your machine reaches, an internal address too. Everything a tool returns comes from the measured page, and the server tells the agent, in its instructions and in the description of each tool, to read it as data and never follow what it says.

The snippets that record interactions (INP, Interactions, Input-Latency-Breakdown) run on a page opened with open_page: the agent installs them, clicks or types with interact and reads them with read_results. At most three pages are open at a time, a page closes after 10 minutes without use, and every page and Chromium close when the client disconnects.

Resources and prompts

The resources are documents a client can attach to the context:

ResourceWhat it has
webperf://schemaThe contract every snippet result follows: base shape, statuses, how to read a result, the rules of the issue codes.
webperf://schema/{snippet}The fields one snippet returns, with an example, and the codes of its issues.
webperf://workflows/{category}The workflows and the decision tree of a category.

The prompts chain the tools for a common task, each with a url argument: audit_lcp, debug_inp and audit_page. In Claude Code they run as /mcp__webperf__audit_lcp.

CrUX field data

get_crux needs a CrUX API key (opens in a new tab), free in the Google Cloud console, in the CRUX_API_KEY variable of the server. It goes in the configuration of the client, never in a tool argument:

claude mcp add webperf -e CRUX_API_KEY=<key> -- npx -y webperf-snippets mcp

The server of the plugin reads CRUX_API_KEY from the environment of Claude Code: export it in your shell before you start Claude Code.

{ "mcpServers": { "webperf": { "command": "npx", "args": ["-y", "webperf-snippets", "mcp"], "env": { "CRUX_API_KEY": "<key>" } } } }

In VS Code, an input keeps the key out of .vscode/mcp.json: VS Code asks for it the first time the server starts and stores it.

{ "inputs": [ { "type": "promptString", "id": "crux-api-key", "description": "CrUX API key", "password": true } ], "servers": { "webperf": { "type": "stdio", "command": "npx", "args": ["-y", "webperf-snippets", "mcp"], "env": { "CRUX_API_KEY": "${input:crux-api-key}" } } } }

An app opened from the Dock or the Start menu does not get the variables of your shell. If CRUX_API_KEY is only exported in your shell profile, set it in env. Keep a file with the key out of version control.

The other tools work without the key.

MCP server or Chrome DevTools MCP

The server measures a page in its own headless Chromium, with a fresh profile: no login, no extensions and no cache from earlier visits. To measure a page as you see it in your browser, with your session, use the Agent Skills with Chrome DevTools MCP (opens in a new tab), which run the same snippets in your Chrome.

Further reading

Last updated on