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

inspo-mcp

v0.1.16

Published

A curated archive of real website designs, served as an MCP server: 15 tools for search, design systems, palettes, reference components, site page flows, and recommendations.

Readme

Inspo MCP

A curated archive of 832 production sites (2,320 captured pages) - queryable over MCP - that gives coding agents visual taste before they write UI.

Every result is grounded in a real, shipped site: real fonts, frequency-ranked palettes traced to source, detected tech, named macrostructures, component crops, and - now - desktop + mobile pairs so an agent learns responsiveness, not just the desktop look.

This is, and stays, a standard MCP server - packaging it for one-line install just makes the same server trivially addable to any MCP client (Cursor, Claude Code, Claude Desktop, …). Two transports, same tools:

  • stdio - npx -y inspo-mcp (src/server-npm.ts) fetches the catalogue from the CDN; from a clone, src/server.ts reads the bundled static seed (no DB needed).
  • Streamable HTTP - a Next.js Route Handler (apps/web/src/app/api/mcp/route.ts) that ships with the site's Vercel deployment.

Tools

| Tool | What it does | |---|---| | search_screens(query, style?, industry?, macrostructure?, mode?, vibe?, color?, pageType?, paperBand?, displayClass?, accentHue?, device?, limit?) | Hybrid lexical + vector search across the archive (vector ranking needs TOGETHER_API_KEY). Returns palette, fonts, tech, tags, desktop + mobile image URLs, inline thumbnails. | | recommend(brief, macrostructure?, pageType?, mode?, vibe?, color?, device?) | One-call moodboard: a macrostructure pick plus shortlist, 5 exemplars, up to 3 matching reference components (fetch source with get_reference_jsx), a palette suggestion, an evidence packet, and heroGuidance + spacingGuidance. Start here. | | get_design_system(slug, live?) | Full DESIGN.md for a site - real fonts, palette + CSS vars, type ramp, detected tech. Thin rows are supplemented by a live fetch of the source (on by default; live:false skips it). | | compare(slugs[]) | 2-4 sites side by side: shared style tags, distinct macrostructures, register agreement. | | find_by_color(hex, tolerance?, limit?) | Real sites whose palette sits near a target colour (OKLAB distance). | | find_similar(slug, limit?, sameSite?) | A site's visual + structural neighbours. | | find_examples_for_macrostructure(name, limit?) | Exemplars of one of the 19 named macrostructures (Bento Grid, Specimen, …). | | find_components(type, …) / find_reference_components(type?, macro?) / get_reference_jsx(type, id) | Real component crops, an index of the canonical reference components, and the JSX source for one. | | get_filters() | Zero input: lists every accepted filter / enum value (styles, industries, macrostructures, vibes, page types) so the agent can pick valid arguments in one call. | | get_site_pages(siteSlug?) | A site's captured pages in reading order; with no argument, the directory of multi-page sites. | | get_screen(slug) / list_collections() / get_collection(slug) | Single record · editor-curated issues. |

Screenshot URLs are absolute Vercel Blob URLs, and component-crop URLs are built on INSPO_BASE_URL (default https://inspomcp.dev), so an agent can fetch them or hand them to a vision model directly.

Baked-in guidance: the server instructions + recommend() carry two composition rules to every agent. heroGuidance: compose the hero to fit the first viewport (~1280×800 / 100svh) - never overflow it - which kills the most common "AI-built page" failure (an oversized hero cut off below the fold). And spacingGuidance: separate sections with real block space (production sites run 80-160px between sections) and keep all copy inside a centered, padded column - which kills the second most common one (sections crammed into one block, text touching the viewport edge). The spacing numbers are measured from the archive, not invented.

Install (one line per client)

Hosted (recommended - no clone, no deps)

A hosted endpoint is live and free (no auth): https://inspomcp.dev/api/mcp. Add it as a remote MCP server:

# Claude Code
claude mcp add --transport http inspo https://inspomcp.dev/api/mcp
// Cursor - ~/.cursor/mcp.json (Claude Desktop: add the URL under Settings > Connectors, or use the npx form below)
{ "mcpServers": { "inspo": { "url": "https://inspomcp.dev/api/mcp" } } }

One command, any client

inspo-mcp install detects the MCP clients on the machine (Claude Code, Codex, VS Code, Cursor, Windsurf, Claude Desktop, Zed) and writes the config for each, pointed at the hosted endpoint:

npx -y inspo-mcp install

It shows the plan and asks before touching anything. --dry-run prints the plan and writes nothing, --client <id> targets one client, --local wires the npx stdio form instead of the hosted URL, and -y skips the prompt. Config files it edits are backed up alongside (mcp.json.inspo-backup); Zed's JSONC settings are printed for you to paste rather than rewritten, so your comments survive.

npx (zero-config)

No clone and no hosting - the stdio server (inspo-mcp) runs straight from npm via npx -y inspo-mcp and fetches the catalogue from the CDN:

// Claude Code: ~/.claude.json  ·  Cursor: ~/.cursor/mcp.json  ·  Claude Desktop: config
{ "mcpServers": { "inspo": { "command": "npx", "args": ["-y", "inspo-mcp"] } } }

Optional env: TOGETHER_API_KEY (enables query-embedding semantic search), INSPO_CATALOGUE_URL (point at a self-hosted catalogue), and INSPO_PROFILE / INSPO_IMAGES / INSPO_MAX_TOKENS (see Open-source models below).

Running npx -y inspo-mcp by hand looks like it does nothing: an MCP server speaks JSON-RPC on stdin/stdout and prints nothing on its own. From a terminal it now prints these install instructions instead (--help, --version; --stdio forces the server). It is meant to be launched by a client, so add it with one of:

claude mcp add inspo -- npx -y inspo-mcp

Local (stdio, from a clone)

The bin shim boots the TS server via tsx - no build step.

// Claude Code: ~/.claude.json  ·  Cursor: ~/.cursor/mcp.json  ·  Claude Desktop: config
{
  "mcpServers": {
    "inspo": {
      "command": "node",
      "args": ["/absolute/path/to/inspo/apps/mcp/bin/inspo-mcp.js"]
    }
  }
}

Restart the client; the agent gains all the tools above.

MCP registry

The server is described by server.json for the official MCP registry (name: io.github.Nutlope/inspo), covering both the npm stdio package and the hosted streamable-http endpoint. To publish or update the listing (needs the GitHub account that owns the repo):

brew install mcp-publisher
cd apps/mcp
mcp-publisher login github
mcp-publisher publish

Note: the npm package must be published with the matching mcpName field first (build-npm.mjs stamps it), and server.json's versions should match the published package version.

Keep the GitHub namespace casing exactly as returned by login (Nutlope, not nutlope); a mismatch causes a 403 even after successful authentication. If correcting mcpName on an already published npm version, bump VERSION in scripts/build-npm.mjs and both versions in server.json, rebuild, and publish the new npm version before running mcp-publisher publish.

Telemetry: the hosted endpoint writes one log line per tool call (tool name, success, duration) to the Vercel logs; no IPs and no query text are recorded. Local stdio/npx servers emit zero telemetry.

Open-source models (Kimi K2.7, GLM 5.2, Qwen, DeepSeek V4, MiniMax)

The server ships a second profile tuned to the harnesses OSS models actually run in. Two independent knobs:

| Env var | Values | What it does | |---|---|---| | INSPO_PROFILE | full (default) / lite | full exposes 15 tools; lite exposes the 9 highest-leverage tools (recommend, search_screens, get_screen, get_design_system, find_examples_for_macrostructure, find_reference_components, get_reference_jsx, get_site_pages, get_filters). Small models pick tools more reliably from a short list. | | INSPO_IMAGES | thumbs (default) / none | none returns text-only responses: no inline image blocks. Use it when the harness drops MCP images (Cline, OpenCode with a non-vision model) or the model is text-only (MiniMax, DeepSeek). Each result still carries the autopsy text (fold-composition breakdown), northstar, palette, and fonts, so the model "sees" through text. On the text-only profile (images=none) the list tools return a lean shape (northstar + palette + fonts); pass detail:"full" or call get_screen for the full autopsy. Inline images are PNG / JPEG / WebP (never AVIF). | | INSPO_MAX_TOKENS | unset (default) / an integer, 300-200000 | Hard ceiling on what one tool response may spend. Results are formatted concise, then the ranked tail is dropped, then inline thumbnails, until the response fits; the top result and every scalar field (tips, filters, hero guidance) always survive, and trimmed responses carry a budgetNote saying how many entries were dropped. Set this when the context window is tight. Every list tool also takes a per-call maxTokens argument, which wins over the env var. On the hosted endpoint, pass ?maxTokens= in the URL instead. |

Why a budget matters more here than for a text-only MCP

Tool results do not cost you once: they stay in the conversation and are re-read on every subsequent turn. In our own A/B evaluation, cache reads ran 3.3x cache writes, so a result pulled early is paid for many times over. Inline images are the dominant term - one recommend call is ~10 KB of text with images off and ~41 KB with thumbnails on - which is why the cheapest lever is fewer, better-targeted calls, and the second cheapest is images=none. INSPO_MAX_TOKENS is the backstop for when neither is under your control.

Zero-config defaults: when neither knob is set, the server reads the client name from the MCP handshake. Kimi CLI, OpenCode, Cline, Roo, Crush, Goose, Aider, Continue, Droid, and iFlow get lite + text-only; Kilo and Qwen Code get lite + thumbnails (their image path works); everything else (Claude Code, Cursor, ...) keeps full + thumbnails. Env vars always win. The hosted endpoint defaults to full + images=thumbs, matching the clients inspo-mcp install actually wires up (Claude Code, Cursor, VS Code, Windsurf, Zed, Claude Desktop - all of which read images). The stateless HTTP transport can't read the client name, so text-only harnesses opt DOWN explicitly: https://inspomcp.dev/api/mcp?profile=lite&images=none. Over stdio, clientInfo auto-detection still does this for you.

Schemas are flat (no $ref, no $schema, no additionalProperties) to satisfy strict validators (Moonshot's API, Together's function-calling layer, vLLM/xgrammar constrained decoding), and argument parsing is tolerant: "Dark", "Bento Grid", limit: "8", out-of-range limits, and bare domains (stripe.com) are all accepted. Slug misses return didYouMean suggestions so the model can self-correct in one step.

// Example: Kimi CLI (~/.kimi/mcp.json), explicit; auto-detection
// would land on the same settings
{
  "mcpServers": {
    "inspo": {
      "command": "npx",
      "args": ["-y", "inspo-mcp"],
      "env": { "INSPO_PROFILE": "lite", "INSPO_IMAGES": "none" }
    }
  }
}

Run / develop

pnpm --filter @inspo/mcp start            # stdio server
pnpm --filter @inspo/mcp test             # smoke test - boots in-process, lists the tools and exercises the core ones
pnpm --filter @inspo/mcp inspect          # MCP Inspector UI

Deploy the hosted endpoint

The MCP is exposed as a Next.js Route Handler in the web app, so it ships with the site's Vercel deployment - deploying apps/web deploys the endpoint too. Once the site is up, point clients at:

https://<your-domain>/api/mcp

The route serves the seed bundled into the web build and fetches the embedding sidecar from the CDN once per lambda for the vector tools (INSPO_CATALOGUE_URL overrides the store). Re-run publish-catalogue-to-blob.ts after seed changes:

pnpm --filter @inspo/worker exec tsx src/publish-catalogue-to-blob.ts --go

Security

  • Read-only. No write/mutate tools; the server only reads the curated catalogue.
  • No secrets in the response surface. The hosted route serves the static seed and reads only optional keys (TOGETHER_API_KEY, INSPO_CATALOGUE_URL) from Vercel environment variables; none are returned to clients. .env is gitignored; only .env.example is tracked.
  • Free + unauthenticated, abuse-resistant. The hosted endpoint needs no auth or API key; abuse is contained by a per-IP rate limit (120 requests a minute per warm instance) and a 256 KB request body cap.
  • get_design_system(live:true) fetches the screen's own source URL server-side (HTML + linked CSS only, no JS execution). Every URL (and every redirect) is validated by an SSRF guard before fetch: public http(s) named hosts only, no private / loopback / link-local / cloud-metadata or IP-literal targets, ports 80/443 only. The response body is byte-capped while streaming, and the hosted route adds a request body cap plus a per-IP rate limit.

Publishing npx inspo-mcp

The build esbuild-bundles the stdio server into one self-contained file with a clean, dependency-free package.json - the ~16MB seed is not bundled (it's fetched from the CDN at runtime), so the package stays ~1.5MB.

pnpm --filter @inspo/mcp build:npm   # → apps/mcp/dist/ (inspo-mcp.mjs + package.json)
node apps/mcp/dist/inspo-mcp.mjs     # optional: smoke-test (speaks MCP on stdio)
cd apps/mcp/dist && npm publish       # needs `npm login`; publishes the public package

The monorepo package.json stays private - only the generated dist/ artifact is published, so nothing here leaks. Re-run build:npm (and publish-catalogue-to-blob.ts) after seed changes, then bump VERSION in scripts/build-npm.mjs and re-publish.

Files

  • src/server.ts - stdio entry (monorepo)
  • src/server-npm.ts - standalone stdio entry for the published package (CDN catalogue)
  • src/install.ts - inspo-mcp install, the per-client config writer
  • src/http-handler.ts - shared Streamable-HTTP handler (used by the Vercel route)
  • src/tools.ts - all tool registrations + HERO_GUIDANCE (shared by all transports)
  • src/profile.ts - the lite / full tool surfaces and the images mode
  • src/format.ts - wire format (absolute URLs, inline image blocks, mobile fields)
  • src/call.ts - one-shot CLI client (tsx src/call.ts <tool> '<json>')
  • src/smoke.ts - pnpm test · scripts/build-npm.mjs - npx bundle builder