npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@perf-labs/mcp

v0.1.0-alpha.11

Published

KeepSnappy MCP server (stdio, read-only): performance findings, compare, window history and commits for coding agents.

Readme

@keepsnappy/mcp

KeepSnappy's MCP server for coding agents (Claude Code and others): it answers "what got slower, where, how sure, why, and what do I do" from the performance findings KeepSnappy measured on real phones. Read-only: it never starts a measurement, writes or recomputes anything (plan 48 §4).

It gives the same answers as the perflab CLI (perflab findings | finding | compare | history | commits | layers): both use this package's API client and answer layout, so a person and an agent read the same words.

Set it up in an app repo (TapIn)

  1. Ask the KeepSnappy owner for a project key with read scope (bun run create-key -- <org> <app> read in apps/api; it refuses an org or app that does not exist). Setup → Keys on the dashboard lists read keys and revokes them. A CI key (run scope) works too; an SDK key (ingest) does not.
  2. Put the key in your shell environment, not in the repo: export PERFLAB_KEY=pl_rk_… (for example in ~/.zshenv).
  3. Add .mcp.json at the repo root:
{
  "mcpServers": {
    "perflab": {
      "command": "npx",
      "args": ["-y", "@keepsnappy/mcp"],
      "env": {
        "PERFLAB_KEY": "${PERFLAB_KEY}",
        "PERFLAB_API": "https://perflab-api-864539138788.europe-west1.run.app"
      }
    }
  }
}

Claude Code expands ${PERFLAB_KEY} from your environment. PERFLAB_API is optional (the hosted API is the default). From a KeepSnappy checkout instead of npm: "command": "bun", "args": ["<perflab>/packages/mcp/src/bin.ts"].

Tools

| Tool | Answers | API | |---|---|---| | list_findings | Whether and when the branch was measured (measured: run sets, the newest set of each journey × phone with its commit, word and runs), then what got worse (Worse / Warning) or better, worst first. Filters: branch or main, journey, phone, state (present default, not-judged, resolved, all), limit (≤ 200), offset (the answer gives next_offset). | GET /v1/findings | | get_finding | One finding by id: what changed, where (journey, phone, branch, commit title and author, PR), how sure (runs per side, session spread, measured differently / not blocking, setup notes), why (components that rendered longer with their cause, counts that moved), what to do (a prompt for a coding agent), lifecycle (first and last seen; present, resolved, or not judged when the newest run set did not judge the measure; seen in N PRs). The prompt ends with the finding's id and page. | GET /v1/findings/:id | | compare_runs | Two runs side by side, window by window, and what differs in how they were measured. No statistics. | GET /v1/compare?a=&b= | | window_history | One window (screen, tap, scroll) of a journey on main over time, run by run, with commit titles, plus the findings on it. | GET /v1/history | | commits_between | The commits KeepSnappy measured between two points (run set ids or commit hashes), one entry per commit with its sessions. | GET /v1/commits | | explain_layers | Which of KeepSnappy's layers answers which question, and each layer's certificate (none issued yet). | GET /v1/layers |

Besides measures, a run in which the phone heated up (iOS thermal state nominal or fair at the start, serious or worse at its peak, or critical from a lower state) is a finding of its own (kind: "heat", layer 3), invalid runs included (REQ-MET-20). The comparison warning "Phone heats up" is a measure finding whose values are shares of cool-started runs.

An empty list is a clean result only when measured.newest exists and was judged: the answer's first line says "No KeepSnappy measurement on branch X" or "the newest run set was not judged" otherwise. Query parameters the API does not know are dropped, not refused (there is no ?commit= filter).

Every tool returns the text the CLI prints and the API's JSON as structured content. Every finding names its layer (4 = PR vs main, 5 = main over time), its certificate (null until plan 51 certifies the layer) and its limits.

Words

The one word table of packages/verdicts/src/headline.ts (REQ-VER-24): Worse / Warning / Better / No change / Can't compare / Not enough data yet, and "not blocking" as a badge on a Worse measured differently from main ("Worse (not blocking)"). The evidence ranks likely causes; it does not prove them.

Develop

bun install
bunx vitest run        # the server against a fake API serving findings built by the API's own finding module
bunx tsc --noEmit
PERFLAB_KEY=… bun src/bin.ts   # stdio