ohmyperf

ohmyperf

Real-machine, real-browser web perf measurement with ~99% iframe coverage. LLM-native + AI-agent-loop ready.

Category
Visit Server

README

OhMyPerf

The first perf tool an LLM agent can actually fix your site with β€” statistical proof, not vibes.

🌐 Try the viewer live: hoainho.github.io/ohmyperf/viewer/ β€” drag any report.json onto the page and inspect every metric, every long-task, every render-blocking opportunity in your browser. No install, no signup.

npm ohmyperf MCP server MCP Chromium License

OhMyPerf measures Core Web Vitals on a real machine with a real Chromium, then closes the loop: an AI agent can call measure β†’ propose_patch β†’ verify_fix in one conversation turn β€” and prove the fix improved your LCP/INP/CLS with a Mann-Whitney U test at Ξ±=0.05, not "looks better to me."

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ measure  β”‚ β†’  β”‚ propose_patch β”‚ β†’  β”‚  verify_fix  β”‚
β”‚ real CWV β”‚    β”‚ ranked, ROI   β”‚    β”‚  p-value per β”‚
β”‚ + trust  β”‚    β”‚ first-party   β”‚    β”‚   metric     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     ↓                  ↓                    ↓
 trustScore         fixPlan             verdict:
 servability       (18 patches         improvement |
 originClass        for tradeit.gg)    neutral |
                                       regression

30-second demo

Real CLI output, no editing:

$ npx -y @ohmyperf/cli@latest run https://example.com --runs 2 --format json
[ohmyperf] INFO OhMyPerf v1.0.0 report
[ohmyperf] INFO url:     https://example.com
[ohmyperf] INFO browser: chromium 148.0.7778.0 (bundled)
[ohmyperf] INFO mode:    real; runs=2; duration=2430ms
[ohmyperf] INFO aggregated:
[ohmyperf] INFO   lcp        median=  256.0  cov=25.0%  n=2
[ohmyperf] INFO   cls        median=  0.000  cov= 0.0%  n=2
[ohmyperf] INFO   fcp        median=  256.0  cov=25.0%  n=2
[ohmyperf] INFO   ttfb       median=  224.5  cov=25.5%  n=2
[ohmyperf] INFO   tbt        median=    0.0  cov= 0.0%  n=2
[ohmyperf] INFO   runtime.taskDuration median=   25.2  cov=20.2%  n=2
[ohmyperf] INFO wrote /path/to/ohmyperf-out/report.json

The full report.json is what LLM agents see β€” including (v0.2.0, pending publish):

  • Report.trustScore β€” overall + per-metric {level, sampleConfidence, effectConfidence, recommendedAction}
  • Report.fixPlan β€” ranked, deduped, ROI-scored patches with applicability: first-party | third-party-cannot-apply
  • Report.meta.servability β€” real-page | bot-challenge-suspected | error-page | timeout-partial | unknown
  • Every Resource tagged with originClass: same-origin | same-site | same-org | cross-site

CoV 25% on 2 runs (above 20% noise floor) β†’ trustScore: low β†’ agent's recommendedAction: "rerun with --runs 10 or --mode ci-stable before drawing budget conclusions". Honest about its own variance, not vibes.

Why this exists

Lighthouse / PSI OhMyPerf
Runs on Synthetic CPU in a Google datacenter Your actual hardware
Cross-origin iframes Network-only (opaque inside) Per-frame CDPSession (~99% coverage)
Agent-callable None MCP server, 16 tools
Statistical proof of fix Threshold gates (flake-prone) Mann-Whitney U, Ξ±=0.05, per-metric noise floors
First-party vs CDN Manual eyeballing originClass + same-org tier for org-owned CDNs
Bot challenge detection Treats Cloudflare interstitials as real pages servability: bot-challenge-suspected
Honest about variance One number, take it or leave it trustScore + per-metric CoV + recommendedAction

Install

# CLI
npm install -g @ohmyperf/cli
ohmyperf run https://your-site.com

# MCP server β€” for Claude (OpenCode/Cursor/Cline) to call tools directly
npm install -g @ohmyperf/mcp-server

# Zero-install one-off
npx -y @ohmyperf/cli@latest run https://your-site.com

Requires Node β‰₯ 22. Playwright Chromium auto-downloads on first run (~150 MB).

Use it from an AI agent

Add to your MCP client config (Claude Desktop example):

{
  "mcpServers": {
    "ohmyperf": {
      "command": "npx",
      "args": ["-y", "@ohmyperf/mcp-server@latest"]
    }
  }
}

Then your LLM has 16 tools available: measure, propose_patch, verify_fix, get_fix_plan, get_trust_score, get_servability, diff, list_reports, and more. Tested with Claude, OpenCode, Cursor, Cline.

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Engine: @ohmyperf/core (frozen 1.0.0 public API)               β”‚
β”‚  Β· Playwright + raw CDP (Target.setAutoAttach for cross-origin) β”‚
β”‚  Β· Plugin runtime Β· Calibration Β· Outlier rejection Β· Diff      β”‚
β”‚  Β· LLM-first signals: trustScore Β· fixPlan Β· servability        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚
        β”œβ”€β”€β–Ί CLI                 npx -y @ohmyperf/cli run <url>
        β”œβ”€β”€β–Ί npm SDK             import { runEngine } from "@ohmyperf/core"
        β”œβ”€β”€β–Ί MCP server          12 tools + 7 prompts (v0.1.0) β€” 17 tools in v0.2.0 [Unreleased]
        β”œβ”€β”€β–Ί Chrome extension    click toolbar icon β†’ measure current tab
        β”œβ”€β”€β–Ί VSCode extension    Cmd+Shift+P β†’ OhMyPerf: Measure URL
        β”œβ”€β”€β–Ί Website             hoainho.github.io/ohmyperf β€” drop report.json on /viewer
        β”œβ”€β”€β–Ί Share-server        Cloudflare Workers or Node
        β”œβ”€β”€β–Ί ESLint plugin       7 CWV-linked rules at editor-save time
        └──► Fixers SDK          archetype registry + proposePatches()

Status: v0.1.0 on npm. v0.2.0 (issue #7) ships the agent fix loop + LLM-first signals + 2 new packages, pending credential refresh.

Why OhMyPerf

Concern Lighthouse / PageSpeed OhMyPerf
Where measurement runs Synthetic emulated CPU in a datacenter The user's actual machine
CWV numbers Inflated by synthetic throttle Match what users actually experience
Cross-origin iframes Network-only β€” opaque inside Per-frame CDPSession via Target.setAutoAttach({flatten:true})
CI reproducibility Lighthouse-CI exists but synthetic Two modes: real (honest variance) + ci-stable (CPU calibration + Fast 4G throttle)
Accuracy Authoritative, internal LCP/FCP/TTFB Β±10% vs Lighthouse 13.x (validated); INP/CLS via official web-vitals/attribution
Diagnostics Audit list with savings estimates LCP/INP sub-parts bar, CLS culprit + rect, long-task β†’ JS URL, render-blocking with wastedMs, third-party impact (details)
Regression detection Threshold gates (flake-prone) Mann-Whitney U significance test with per-metric noise floors
Plugin model Audit-API only, internal Every metric, audit, reporter is a plugin
Sharing PSI URL (public, ephemeral) Hosted shareable links + static viewer + self-host backend
AI agent access None First-class MCP server (Claude / OpenCode / Cursor / Cline)

Surfaces

# Surface Package Quickstart
1 CLI @ohmyperf/cli ohmyperf run https://example.com
2 npm SDK @ohmyperf/core import { runEngine, measure } from "@ohmyperf/core"
3 Chrome extension apps/extension-chrome/ Load unpacked β†’ click toolbar icon
4 Website (SPA) apps/website/ Β· spec measurement-spa pnpm --filter @ohmyperf/website dev β†’ measure at /measure, view at /viewer, history at /report. Static export to CF Pages.
5 VSCode extension apps/ide-vscode/ Cmd+Shift+P β†’ OhMyPerf: Measure URL
6 MCP server apps/mcp-server/ 14 tools incl. measure, propose_patch (v0.2.0), verify_fix (v0.2.0)
7 Share-server packages/share-server/ Cloudflare Workers or node dist/node.js
8 ESLint plugin (v0.2.0) @ohmyperf/eslint-plugin npm i -D @ohmyperf/eslint-plugin + extends: ['plugin:ohmyperf/recommended']
9 Fixer SDK (v0.2.0) @ohmyperf/fixers import { proposePatches } from "@ohmyperf/fixers"

CLI quickstart

# Install
npm install -g @ohmyperf/cli
ohmyperf install-browser

# Measure
ohmyperf run https://example.com --runs 5 --format json,html

# CI-gating mode (calibrated CPU + Fast 4G)
ohmyperf run https://example.com --mode ci-stable --runs 5

# Compare two reports with Mann-Whitney significance (exit 1 on regression)
ohmyperf diff baseline.json candidate.json

# Share a report to a hosted endpoint
export OHMYPERF_SHARE_ENDPOINT=https://ohmyperf.dev
ohmyperf share ./ohmyperf-out/report.json

# Diagnostics
ohmyperf doctor
ohmyperf list-plugins --json

Subcommands: run, diff, share, doctor, list-plugins, install-browser. Exit codes 0–12 documented per the cli-surface capability spec.

Example output

[ohmyperf] INFO OhMyPerf v1.0.0 report
[ohmyperf] INFO url:     https://example.com
[ohmyperf] INFO browser: chromium 147.0.7727.0 (bundled)
[ohmyperf] INFO mode:    real; runs=5; duration=4823ms
[ohmyperf] INFO aggregated:
[ohmyperf] INFO   lcp        median=  44.0  cov=4.3%  n=5
[ohmyperf] INFO   fcp        median=  44.0  cov=4.3%  n=5
[ohmyperf] INFO   ttfb       median=   6.5  cov=12.3% n=5
[ohmyperf] INFO   cls        median=  0.000 cov=0.0%  n=5
[ohmyperf] INFO   tbt        median=   0.0  cov=0.0%  n=5
[ohmyperf] INFO audits: 1
[ohmyperf] INFO   [PASS] a11y.axe-violations
[ohmyperf] INFO wrote ./ohmyperf-out/report.json (9 KB)
[ohmyperf] INFO wrote ./ohmyperf-out/report.html (28 KB)

npm SDK quickstart

import { runEngine, createSilentLogger } from "@ohmyperf/core";
import { createPlaywrightAdapter } from "@ohmyperf/driver-playwright";
import { cwvPlugin, axePlugin } from "@ohmyperf/plugins-builtin";
import { writeJsonReport } from "@ohmyperf/reporter-json";

const { driver, adapter } = createPlaywrightAdapter({
  url: "https://example.com",
  kind: "chromium",
});

const report = await runEngine({
  opts: {
    url: "https://example.com",
    runs: 5,
    mode: "real",
    plugins: [cwvPlugin(), axePlugin({ tags: ["wcag2aa"] })],
  },
  driver,
  adapter,
  logger: createSilentLogger(),
});

console.log(report.aggregated.lcp);
// { median: 44, p75: 45, p95: 47, mean: 44.5, stdev: 1.2, cov: 0.027,
//   runs: 5, droppedOutliers: 0 }

await writeJsonReport(report, "./out");

The public API (@ohmyperf/core) is frozen at 1.0.0-stable and enforced by api-extractor in CI. See packages/core/etc/core.api.md for the 45-export contract.

Chrome extension

cd apps/extension-chrome
pnpm build
# Chrome β†’ chrome://extensions β†’ Developer mode β†’ Load unpacked
# Point at apps/extension-chrome/extension-dist/

Click the toolbar icon on any tab. A "measuring…" badge appears, then opens a viewer tab with the full HTML report when done. Uses chrome.debugger directly β€” no companion app, no localhost relay.

Chrome Web Store submission is documented as deferred (requires publisher account + privacy policy URL + review cycle).

VSCode extension

cd apps/ide-vscode
pnpm build
# Code β†’ Extensions β†’ β‹― β†’ Install from VSIX
# Or develop: F5 in this folder launches an Extension Development Host.

Commands:

  • OhMyPerf: Measure URL β€” prompts for URL, runs the CLI, opens result in a webview.
  • OhMyPerf: Open Report File… β€” file picker for replaying saved reports.

Settings: ohmyperf.cliPath, ohmyperf.defaultUrl, ohmyperf.defaultRuns, ohmyperf.defaultMode.

VSCode Marketplace submission is documented as deferred.

MCP server (for AI agents)

OhMyPerf ships an MCP (Model Context Protocol) server so AI agents like Claude Desktop, OpenCode, Cursor, Cline, and Continue can call measure and diff as first-class tools.

Register with OpenCode

~/.config/opencode/opencode.json:

{
  "mcp": {
    "ohmyperf": {
      "type": "local",
      "command": ["npx", "ohmyperf-mcp"]
    }
  }
}

Register with Claude Desktop

~/Library/Application Support/Claude/claude_desktop_config.json (macOS):

{
  "mcpServers": {
    "ohmyperf": {
      "command": "npx",
      "args": ["ohmyperf-mcp"]
    }
  }
}

Install from Glama (MCP directory)

The OhMyPerf MCP server is listed in the Glama MCP directory β€” one-click install paths for every Glama-supported client, no npx command required.

# Glama CLI (one-off)
npx -y @glama/mcp-server@latest install hoainho/ohmyperf

# Or just point your client at the stdio command:
command:  npx
args:     [-y, @ohmyperf/mcp-server]

The glama.json at the repo root pins the install command + maintainer metadata so the Glama listing stays in sync with this README. Claim your own copy at https://glama.ai/mcp/servers/hoainho/ohmyperf/score to edit the description, configure Docker build instructions, and receive review notifications.

Tools exposed

What's available where: @ohmyperf/mcp-server@0.1.0 currently on npm exposes the 12 tools NOT marked (v0.2.0). The 5 v0.2.0-tagged tools (propose_patch, verify_fix, get_fix_plan, get_trust_score, get_servability) are committed on main and will land when v0.2.0 publishes β€” track at issue #7. All 17 tools + 7 prompts are also available today by pointing an MCP client at npx -y @ohmyperf/mcp-server@main once v0.2.0 lands.

Tool Input Output
measure { url, runs?, mode?, plugins?, browserPath?, collectTrace? } Human summary + Saved to: <path> + aggregated JSON; full report saved + exposed as resource
diff { baseline, candidate, failOnRegression? } Mann-Whitney significance table + { hasRegressions, metrics }
analyze_report { reportPath | uri, insightName, limit? } Slice for one insight (lcp-breakdown / render-blocking / long-tasks / third-parties / opportunities / audits / resources / frames)
generate_markdown_summary { reportPath | uri, title? } PR-comment-ready Markdown summary with 🟒/🟑/πŸ”΄ verdict block
generate_html_report { reportPath | uri, outputDir?, theme?, style? } Single-file HTML viewer written to disk
generate_deck { reportPath | uri, outputDir?, style?, title? } Multi-slide HTML presentation (⌘P β†’ PDF for stakeholder distribution)
find_regression_cause { baseline, candidate } Ranked hypotheses (new render-blocking, grown assets, new long tasks, new third-parties) with evidence
enforce_budget { url, budget, mode?, runs? } CI-style pass/fail per metric with exit-code-style verdict
track_url { url, runs?, mode?, ... } Measure + append to time-series + return improving/stable/regressing trend
list_runs / list_styles / diff_resources various Resource browsing + brand catalog + URI-based diff
propose_patch (v0.2.0) { reportPath | uri, opportunityId?, url?, maxPatches? } Structured { archetype, url, search, replace, rationale, expectedImpactMs, confidence }[] patches an agent can apply
verify_fix (v0.2.0) { baselineReportPath | baselineUri, candidateUrl, runs?, mode? } Re-measures candidate + Mann-Whitney U diff vs baseline; verdict βœ… no regression / ❌ REGRESSION DETECTED
get_fix_plan (v0.2.0) { reportPath | uri, limit?, applicabilityFilter? } Precomputed ranked, ROI-scored fixPlan slice only β€” saves the agent parsing the full 50KB+ report
get_trust_score (v0.2.0) { reportPath | uri } trustScore.overall + per-metric verdicts + recommendedAction so agents skip noisy measurements before acting
get_servability (v0.2.0) { reportPath | uri } meta.servability classification β€” real-page / bot-challenge-suspected / error-page / timeout-partial / unknown β€” so agents don't gate CI on a Cloudflare interstitial

Saved reports surface as resources at ohmyperf://reports/<timestamp>-<id>.json so the agent can read them back later without re-measuring.

Killer flow: closed agent fix loop (v0.2.0)

1. measure(url)              β†’ report.json + opportunities
2. propose_patch(reportPath) β†’ { archetype: "render-blocking-script-add-defer",
                                  search: '<script src="vendor.js"',
                                  replace: '<script src="vendor.js" defer',
                                  expectedImpactMs: 320,
                                  confidence: "high" }
3. (agent applies patch + deploys to preview)
4. verify_fix(baseline, candidateUrl) β†’ βœ… no regression / ❌ REGRESSION

End-to-end loop time: ~5.5s against a real public URL (commit a41301f verified composition). Patches archetypes covering ~80% of typical opportunities (render-blocking scripts/stylesheets, LCP image fetchpriority + preload).

Website

Live at hoainho.github.io/ohmyperf (zero-credential GitHub Pages mirror, deployed via .github/workflows/deploy-pages.yml). Cloudflare Pages deploy at ohmyperf.dev is pending domain registration (#9).

cd apps/website
pnpm build                              # Next.js static export to out/
OHMYPERF_BASE_PATH=/ohmyperf pnpm build # for GitHub Pages subpath

Routes:

  • / β€” landing page (light/dark theme, no external network requests)
  • /viewer/ β€” drag-drop report.json to render in browser (no upload, no analytics, no signup)
  • /measure/ β€” in-browser measurement SPA (CDP via the Chrome extension when installed)
  • /report/ β€” local measurement history
  • /r/:id β€” served by the share-server when deployed alongside

Share-server (hosted shareable links)

Two deployment targets from the same Hono codebase:

Cloudflare Workers + R2 + D1 (production)

cd packages/share-server
# wrangler.toml + D1 schema (D1_SCHEMA export)
wrangler d1 execute ohmyperf-db --file=schema.sql
wrangler deploy

Node + filesystem (self-host)

cd packages/share-server
pnpm build
PORT=4170 OHMYPERF_SHARE_DATA_DIR=./data node dist/node.js
# listening on http://127.0.0.1:4170

API:

POST /api/share          { report, password?, expiresInMs?, private? } β†’ { id, url, expiresAt }
GET  /api/r/:id          β†’ raw report JSON (with optional password gate)
GET  /r/:id              β†’ rendered HTML (uses @ohmyperf/viewer)
DELETE /api/r/:id        β†’ 204

Per-IP rate limit (10/hour default), 10 MB body cap, mandatory security headers (X-Content-Type-Options, Referrer-Policy, X-Frame-Options), env-secret scrubber in the upload client.

GDPR / Privacy Policy / DPA / DSAR endpoint defer to legal review.

CI integration

Drop-in templates/ci/github-actions.yml:

- run: npx ohmyperf run "$OHMYPERF_URL" --mode ci-stable --runs 5 \
       --format json,html,markdown --output ./perf
- uses: actions/upload-artifact@v4
  with: { name: ohmyperf-reports, path: perf/ }
- if: github.event_name == 'pull_request'
  run: ohmyperf diff .ohmyperf-baseline/report.json perf/report.json

Auto-posts the Markdown summary as a PR comment via actions/github-script@v7. Mann-Whitney significance gates the merge.

Architecture

Monorepo: pnpm workspaces + Turborepo.

ohmyperf/
β”œβ”€β”€ packages/
β”‚   β”œβ”€β”€ core/                     # Engine, plugin runtime, calibration, diff
β”‚   β”œβ”€β”€ driver-playwright/        # Playwright + raw CDP (newCDPSession)
β”‚   β”œβ”€β”€ driver-extension/         # chrome.debugger driver
β”‚   β”œβ”€β”€ plugins-builtin/          # cwv, axe, custom-metric-example
β”‚   β”œβ”€β”€ reporter-{json,html,markdown}/
β”‚   β”œβ”€β”€ viewer/                   # Pure-TS HTML report renderer
β”‚   β”œβ”€β”€ share-client/             # Upload + redaction pipeline
β”‚   β”œβ”€β”€ share-server/             # Hono backend (Workers + Node)
β”‚   └── tests-oopif-corpus/       # Synthetic cross-origin iframe fixtures
β”œβ”€β”€ apps/
β”‚   β”œβ”€β”€ cli/                      # ohmyperf binary (citty)
β”‚   β”œβ”€β”€ website/                  # Static landing + drag-drop viewer
β”‚   β”œβ”€β”€ extension-chrome/         # MV3 + chrome.debugger
β”‚   β”œβ”€β”€ ide-vscode/               # Command palette + webview
β”‚   └── mcp-server/               # @modelcontextprotocol/sdk stdio server
└── openspec/                     # OpenSpec proposal + ADRs

ADRs:

  • ADR-001 Driver abstraction; Playwright primary; raw CDP via newCDPSession()
  • ADR-002 OOPIF via Target.setAutoAttach({flatten:true}); CLS dual reporting
  • ADR-003 Plugins in-process; npm trust; shared reports are inert JSON
  • ADR-004 Chrome extension via chrome.debugger
  • ADR-005 Cloudflare Workers + R2 + D1; Hono + S3 + Postgres self-host parity

Capability matrix

Cross-browser deep-inspection is Chromium-only. Firefox and WebKit get CWV via the web-vitals polyfill + standard PerformanceObserver.

Metric Chromium Firefox WebKit
LCP / CLS / FCP / TTFB βœ… βœ… web-vitals βœ… web-vitals
INP βœ… ⚠️ partial ⚠️ partial
Cross-origin OOPIF deep inspect βœ… CDP ❌ ❌
Coverage (unused JS/CSS) βœ… Profiler ❌ ❌
Trace / heap snapshot βœ… ❌ ❌
HAR / network waterfall βœ… βœ… βœ…
axe-core a11y βœ… βœ… βœ…

Honest defer list

Documented per surface in each commit message. Not blockers for v0 dogfood:

  • Per-frame collector support in Chrome extension's measurement path Done (v0.2.0): cross-origin OOPIFs get real CDP sessions via context.newCDPSession(frame).
  • Source-map detection on longestScript Done stage-1 (v0.2.0): schema slot + sourceMappingURL regex detection. Stage 2 (VLQ decode + fetch + repo-root mapping) deferred to v0.3 β€” depends on adding @jridgewell/sourcemap-codec.
  • VSCode Marketplace publish engineering ready (v0.2.0) β€” .github/workflows/publish-vscode.yml + vsce package verified locally produces valid .vsix; needs anh's VSCE_PAT secret. See docs/PUBLISH-VSCODE.md.
  • Cloudflare Pages website deploy engineering ready (v0.2.0) β€” .github/workflows/deploy-website.yml ready; needs anh's CLOUDFLARE_API_TOKEN + CLOUDFLARE_ACCOUNT_ID secrets. See docs/DEPLOY-WEBSITE.md.
  • smithery.ai + glama.ai MCP listings engineering ready (v0.2.0) β€” smithery.yaml configured for stdio runtime. See docs/PUBLISH-MCP-LISTINGS.md.
  • Chrome Web Store extension publish (requires publisher account + privacy policy URL + review cycle)
  • JetBrains Marketplace + IntelliJ plugin (v0.3+)
  • GDPR / Privacy Policy / DPA / Terms / DSAR endpoint (require legal review)
  • Argon2id password hashing in share-server (v0 uses SHA-256; Workers doesn't expose Argon2id natively)
  • Source-map decorations + CodeLens in VSCode extension (v0.3+)
  • Scenario user-flow files in CLI (v0.3+ β€” engine assumes single-URL goto)
  • TypeScript loader for .ts scenario files (v0.3+; v0 supports .mjs only)
  • Cloud real-device farm (explicit non-goal per ADR-002)
  • RUM SDK (different product category, explicit non-goal)
  • Mobile-native apps (Android/iOS WebView remote debugging is v0.4+)

Repository state

365 tests across 13 workspaces, all passing on Node 22 and Node 24, against real Chromium + real Hono server + mocked chrome.debugger/vscode APIs:

@ohmyperf/core                 94
@ohmyperf/driver-playwright     6
@ohmyperf/driver-extension      6
@ohmyperf/viewer               83
@ohmyperf/reporter-markdown     8
@ohmyperf/reporter-deck        50
@ohmyperf/share-server         10
@ohmyperf/design-tokens        32
@ohmyperf/website               7
ohmyperf-vscode                 2
@ohmyperf/extension-chrome      4  (+ 1 deferred-skip integration test)
@ohmyperf/mcp-server           13
@ohmyperf/tests-oopif-corpus   19
@ohmyperf/tests-visual-regression  3
@ohmyperf/eslint-plugin         7  (v0.2.0 β€” RuleTester)
@ohmyperf/fixers                9  (v0.2.0 β€” proposePatches + archetype registry)
ohmyperf-cli                   10
@ohmyperf/runner               24
                            ──────
                              387 (+ 1 skip)

Quality gates wired in CI:

  • pnpm typecheck across 31 workspaces (strict TS, exactOptionalPropertyTypes, noUncheckedIndexedAccess)
  • pnpm lint with import-layering rules (plugins can't import core internals, viewer can't import drivers, CDP types stay inside driver packages)
  • pnpm test (Vitest) with OHMYPERF_CHROMIUM_PATH for real-browser tests
  • pnpm license:audit β€” 396+ packages scanned, allow-list of Apache-2.0 / MIT / ISC / BSD / MPL-2.0
  • pnpm --filter @ohmyperf/core api:check β€” api-extractor enforces the frozen 1.0.0 public surface
  • actionlint v1.7.12 across all 7 workflows (0 warnings)
  • publish-stable.yml preflight: npm whoami + npm access list packages @ohmyperf to catch misconfigured tokens before pipeline cost (skips itself in OIDC-only mode)

Contributing

This project follows OpenSpec conventions. Architecture changes go through the multi-agent deep-design pipeline (Metis scope + Oracle architecture + Momus review) before code. See openspec/ for the proposal and ADRs.

Pull requests must:

  • Pass pnpm typecheck && pnpm lint && pnpm test && pnpm license:audit
  • Update the API contract (packages/core/etc/core.api.md) when changing public exports
  • Match existing ESLint layering rules β€” no CDP types in @ohmyperf/core, no driver imports in @ohmyperf/viewer

License

Apache-2.0. See LICENSE and NOTICE for third-party attributions (axe-core is MPL-2.0; web-vitals, Playwright, Lighthouse audit modules, tracium-equivalent are Apache-2.0).

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured