diff --git a/README.md b/README.md index aa9fcbb..b48ba59 100644 --- a/README.md +++ b/README.md @@ -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)) | @@ -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. diff --git a/cli/README.md b/cli/README.md index f241a41..a73f181 100644 --- a/cli/README.md +++ b/cli/README.md @@ -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`. | diff --git a/content/CLI.mdx b/content/CLI.mdx index a2ec112..283cf51 100644 --- a/content/CLI.mdx +++ b/content/CLI.mdx @@ -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: diff --git a/content/MCP.mdx b/content/MCP.mdx new file mode 100644 index 0000000..17aafa6 --- /dev/null +++ b/content/MCP.mdx @@ -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= -- npx -y webperf-snippets mcp +``` + +```json +{ + "mcpServers": { + "webperf": { + "command": "npx", + "args": ["-y", "webperf-snippets", "mcp"], + "env": { "CRUX_API_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}" } + } + } +} +``` + + +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](/#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 diff --git a/content/_meta.js b/content/_meta.js index a4e655d..878dffd 100644 --- a/content/_meta.js +++ b/content/_meta.js @@ -26,6 +26,9 @@ export default { "CLI": { "title": "CLI" }, + "MCP": { + "title": "MCP server" + }, "extension": { "title": "DevTools extension (beta)" }, diff --git a/content/index.mdx b/content/index.mdx index 7d0970b..9018cd1 100644 --- a/content/index.mdx +++ b/content/index.mdx @@ -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) | @@ -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. diff --git a/public/llms.txt b/public/llms.txt index 4606c27..c2fc8b1 100644 --- a/public/llms.txt +++ b/public/llms.txt @@ -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)