Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ AI agents are good at interpreting performance data and unreliable when they wri
| You want to | Use |
| ----------------------------------------------------- | ---------------------------------------------------------------- |
| Audit a URL with any agent that has a terminal | The [Copy prompt](#copy-prompt) button on each snippet page |
| Give an agent the snippets as tools | The [MCP server](#mcp-server) |
| Let the agent drive your Chrome (login, interactions) | The [Agent Skills](#agent-skills) with Chrome DevTools MCP |
| Run snippets from scripts or CI | The [CLI](#cli) |
| Give an agent the whole documentation | [`llms.txt`](https://webperf-snippets.net/llms.txt) ([details](#documentation-for-agents)) |
Expand All @@ -29,6 +30,16 @@ Not sure which snippet to run? Start from the symptom in [Which snippet should I

Snippet pages have a **Copy prompt** button above the code. It copies a prompt that asks any AI agent with a terminal to run that snippet with the [CLI](#cli) on the URL you give it, and to report the value, the cause and the issues. The agent runs the published snippet instead of rewriting it or estimating the result.

### MCP server

The CLI includes an MCP server: an agent in any MCP client (Claude Code, Cursor, VS Code, Gemini CLI) calls the snippets and the workflows as tools, on a headless Chromium, and reads the object each one returns. It is listed in the [MCP Registry](https://registry.modelcontextprotocol.io) as `io.github.nucliweb/webperf-snippets`.

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

See the [MCP server documentation](https://webperf-snippets.net/MCP) for other clients, the tools, the resources and prompts, and the CrUX key.

### Agent skills

The snippets are packaged as [Agent Skills](https://agentskills.io/) for Claude Code, Cursor, OpenCode, Gemini CLI, VS Code extensions and [other compatible agents](https://agentskills.io/). With [Chrome DevTools MCP](https://github.com/ChromeDevTools/chrome-devtools-mcp), the agent runs the snippets in your browser and reads the object they return.
Expand Down
2 changes: 2 additions & 0 deletions cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ The results of a run can add steps on the same page load: LCP over 2.5 s adds `L
claude mcp add webperf -- npx -y webperf-snippets mcp
```

It needs the Chromium of Playwright (`npx playwright install chromium`); without it, the tools answer with that command. The [MCP server documentation](https://webperf-snippets.net/MCP) has the configuration of other clients (Cursor, VS Code, Claude Desktop, Gemini CLI). The server is listed in the [MCP Registry](https://registry.modelcontextprotocol.io) as `io.github.nucliweb/webperf-snippets`.

| Tool | What it does |
| --------------- | ---------------------------------------------------------------------------- |
| `list_snippets` | Lists the snippets with their category, title, short aliases and whether they track interactions. Takes an optional `category`. |
Expand Down
2 changes: 2 additions & 0 deletions content/CLI.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,8 @@ Each snippet page has a **Copy prompt** button above the code. The prompt asks a

The snippets an agent cannot run in a meaningful way have no button: the [Fetch & XHR Timeline](/DevTools-Overrides/Fetch-XHR-Timeline) overrides, which need DevTools Local Overrides, the [Long Animation Frames helpers](/Interaction/Long-Animation-Frames-Helpers), and [Network Bandwidth & Connection Quality](/Resources/Network-Bandwidth-Connection-Quality), because headless Chromium reports the connection of the machine it runs on. The [Back/forward cache](/Loading/Back-Forward-Cache) prompt says that the result is partial, since the CLI does not navigate back.

An agent in an MCP client can also call the snippets as tools: `webperf-snippets mcp` starts the [MCP server](/MCP) of the CLI.

## CI integration

GitHub Actions example, fail the PR if LCP exceeds 2.5s:
Expand Down
151 changes: 151 additions & 0 deletions content/MCP.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
---
type: guide
---

import { Callout } from '../components/Callout'

# MCP server

The CLI includes a [Model Context Protocol](https://modelcontextprotocol.io) 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](https://github.com/nucliweb/webperf-snippets/blob/main/snippets/SCHEMA.md).

```bash
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](https://registry.modelcontextprotocol.io) 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:

```bash
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

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

### Cursor, Claude Desktop, Gemini CLI and Antigravity

These clients read a JSON file with an `mcpServers` object:

| Client | File |
| --- | --- |
| Cursor | `.cursor/mcp.json` in the project, or `~/.cursor/mcp.json` for every project |
| Claude Desktop | `claude_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 |

```json
{
"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:

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

## Tools

| Tool | What it does |
| --- | --- |
| `list_snippets` | Lists the snippets with their category, title, short aliases and whether they track interactions. Takes an optional `category`. |
| `run_snippet` | Opens 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_workflow` | Runs 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_crux` | Returns 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_page` | Opens a URL in a page that stays open between calls and installs tracking snippets (`track`, such as `INP`). Returns a `sessionId`. |
| `interact` | Runs steps on an open page: `click`, `type`, `hover`, `scroll` or `wait`. |
| `read_results` | Returns what the tracking snippets of an open page have recorded. |
| `close_page` | Closes an open page. |

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:

| Resource | What it has |
| --- | --- |
| `webperf://schema` | The contract every snippet result follows: base shape, statuses, how to read a result. |
| `webperf://schema/{snippet}` | The fields one snippet returns, with an example. |
| `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](https://developer.chrome.com/docs/crux/api), 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:

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

```json
{
"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.

```json
{
"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}" }
}
}
}
```

<Callout type="info">
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.
</Callout>

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](/#agent-skills) with [Chrome DevTools MCP](https://github.com/ChromeDevTools/chrome-devtools-mcp), which run the same snippets in your Chrome.

## Further reading

- [Model Context Protocol](https://modelcontextprotocol.io) | modelcontextprotocol.io
- [CLI](/CLI) | The same snippets and workflows from the command line and CI
- [Result contract of the snippets](https://github.com/nucliweb/webperf-snippets/blob/main/snippets/SCHEMA.md) | GitHub
- [Why the server is a subcommand of the CLI](https://github.com/nucliweb/webperf-snippets/blob/main/docs/adr/0002-mcp-server-as-cli-subcommand.md) | ADR 0002
3 changes: 3 additions & 0 deletions content/_meta.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ export default {
"CLI": {
"title": "CLI"
},
"MCP": {
"title": "MCP server"
},
"extension": {
"title": "DevTools extension (beta)"
},
Expand Down
11 changes: 11 additions & 0 deletions content/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ AI agents are good at interpreting performance data and unreliable when they wri
| You want to | Use |
| ----------------------------------------------------- | ----------------------------------------------------------- |
| Audit a URL with any agent that has a terminal | The [Copy prompt](#copy-prompt) button on each snippet page |
| Give an agent the snippets as tools | The [MCP server](#mcp-server) |
| Let the agent drive your Chrome (login, interactions) | The [Agent Skills](#agent-skills) with Chrome DevTools MCP |
| Run snippets from scripts or CI | The [CLI](#cli) |

Expand All @@ -22,6 +23,16 @@ Not sure which snippet to run? Start from the symptom in [Which snippet should I

Snippet pages have a **Copy prompt** button above the code. It copies a prompt that asks any AI agent with a terminal to run that snippet with the [CLI](/CLI) on the URL you give it, and to report the value, the cause and the issues. The agent runs the published snippet instead of rewriting it or estimating the result.

### MCP server

The CLI includes an MCP server: an agent in any MCP client (Claude Code, Cursor, VS Code, Gemini CLI) calls the snippets and the workflows as tools, on a headless Chromium, and reads the object each one returns.

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

→ [MCP server documentation](/MCP)

### Agent skills

WebPerf Snippets powers a set of [Agent Skills](https://github.com/nucliweb/webperf-snippets/tree/main/.claude/skills) for autonomous performance audits. An AI agent such as [Claude Code](https://claude.ai/code) executes the snippets deterministically through [Chrome DevTools MCP](https://github.com/ChromeDevTools/chrome-devtools-mcp), the same code, every time, across sessions and models.
Expand Down
1 change: 1 addition & 0 deletions public/llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
## Guides

- [WebPerf Snippets CLI](https://webperf-snippets.net/CLI.md)
- [MCP server](https://webperf-snippets.net/MCP.md)
- [DevTools extension](https://webperf-snippets.net/extension.md)
- [Which snippet should I use?](https://webperf-snippets.net/which-snippet.md)

Expand Down
Loading