A small MCP server that gives premium users of api.webperf.se read-only access to their sites and test results from any MCP client (e.g. Claude Desktop).
It runs locally over stdio — there is nothing to host. The server is a thin client over the existing public HTTP API: it adds no privileges of its own, and all authorization stays on the server.
This is the important part.
- The MCP server is just another API client. It only calls the same public
endpoints (
/0.1/stats/…,/v1/tests) that already exist. It has no database access and no special powers. - Authorization stays server-side. api.webperf.se already scopes every
premium request to the sites your key is granted via
users_accessand returns403otherwise. The MCP cannot bypass that — it can never show data your key couldn't already fetch directly. - Read-only. v1 exposes only listing and reading. No retest, audit, or other mutating endpoints are wired up.
- Your key stays on your machine. This tool never writes your key anywhere
itself, and sends it only as the
api-keyheader tohttps://api.webperf.seover HTTPS. Where the key is stored depends on how you install:- Extension (recommended): the manifest marks the key
sensitive, so Claude Desktop keeps it in your operating system's keychain. - Manual config: the key sits in plaintext in your client's config file. That is normal for MCP, but worth knowing when you rotate it.
- Extension (recommended): the manifest marks the key
- Revocation is immediate. Because the key is checked on every request, if you rotate or revoke it in api.webperf.se, MCP access stops at once.
| Tool | What it does | Endpoint |
|---|---|---|
list_my_sites |
Lists the sites your key can access | GET /0.1/stats/ |
get_latest_results(site_id, type_of_test?) |
Latest test results for a site (scores and readable reports). Omits the large raw audit data; pass type_of_test to narrow to one test |
GET /0.1/stats/{site_id} |
get_raw_check_data(site_id, type_of_test) |
Opt-in: raw underlying audit data for one test, unescaped and parsed to JSON. Large (hundreds of KB) — only for when you explicitly want the machine detail behind a score | GET /0.1/stats/{site_id} |
get_test_history(site_id) |
Historical monthly scores for a site | GET /0.1/stats_per_month/{site_id} |
list_test_types(lang, active_only) |
Catalogue of test types (open data, no key) to read numeric type_of_test ids |
GET /v1/tests |
get_latest_results deliberately leaves out each test's raw json_check_data
(which can be hundreds of KB per test) to keep responses small and fast. When
you actually want that detail for a specific test, get_raw_check_data fetches
it for that one test and returns clean, parsed JSON.
Download webperf-mcp-<version>.mcpb from the
latest release and
double-click it. Claude Desktop will show an install prompt, ask for your
premium API key, and store it in your keychain.
That's the whole setup — no JSON to edit, no terminal, and no need to install
Python or uv yourself. The bundle declares the
uv runtime, so Claude Desktop fetches the right Python and dependencies on its
own.
You can also install it from Settings → Extensions → Install extension…, and change your API key later from that same screen.
Then ask things like "list my webperf sites" or "show the latest accessibility results for site 3843".
Clients that don't support MCP Bundles need the server configured by hand. The
easiest path is uvx, which runs it in an
isolated environment with no manual install:
uvx --from git+https://github.com/Webperf-se/webperf-mcp webperf-mcpFor Claude Code:
claude mcp add webperf --env WEBPERF_API_KEY=your-key-here \
-- uvx --from git+https://github.com/Webperf-se/webperf-mcp webperf-mcpFor a client that takes JSON (this is what the .mcpb does for you):
{
"mcpServers": {
"webperf": {
"command": "/Users/you/.local/bin/uvx",
"args": ["--from", "git+https://github.com/Webperf-se/webperf-mcp", "webperf-mcp"],
"env": {
"WEBPERF_API_KEY": "your-premium-api-key-here"
}
}
}
}Use the absolute path to
uvx. GUI-launched apps on macOS do not inherit your shellPATH— they get the bare launchd default (/usr/bin:/bin:/usr/sbin:/sbin), which does not include~/.local/binwhere the standard uv installer putsuvx. A plain"command": "uvx"fails there with nothing but a generic "server failed" message. Runwhich uvxto get your path, or symlink uv somewhere already on the defaultPATH.
python -m venv .venv && source .venv/bin/activate
pip install -e .
webperf-mcpWhen installed as an extension, Claude Desktop collects these for you; you only need them when configuring a client by hand.
| Variable | Required | Default | Purpose |
|---|---|---|---|
WEBPERF_API_KEY |
yes | — | Your premium api.webperf.se key |
WEBPERF_API_BASE |
no | https://api.webperf.se |
API base URL (e.g. for staging) |
WEBPERF_HTTP_TIMEOUT |
no | 30 |
Per-request timeout in seconds |
These are read from the process environment — set them in your MCP client's
env block. The server does not read a .env file.
manifest.json describes the extension: the uv runtime, the
tools, and the user_config fields Claude Desktop prompts for.
npx @anthropic-ai/mcpb validate manifest.json
npx @anthropic-ai/mcpb pack . webperf-mcp-0.1.1.mcpbAttach the resulting .mcpb to a GitHub release so the download link above
resolves. Keep version in manifest.json in step with pyproject.toml.
.mcpbignore keeps .env, virtualenvs and build artifacts out of the bundle.
Check it before publishing — pack zips the working directory, so a stray
secret would ship to every user. Verify with:
unzip -l webperf-mcp-0.1.1.mcpbMIT