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

norma-mcp-init

v0.5.0

Published

Single source-of-truth registry of MCP clients powering every Norma by Quality Clouds one-click install surface (Phase 1b, QSA-1278).

Readme

norma-mcp-init

Norma MCP one-click installer — Phase 1b (epic QSA-1277). Cursor directory listing prep: docs/cursor-directory-listing.md (QSA-1459).

Install

One command works everywhere — no account needed beforehand, you sign in on first use:

npx norma-mcp-init

Cursor — Add to Cursor   VS Code — Add to VS Code

Claude Code — claude mcp add --transport http norma https://api.qualityclouds.ai/mcp

Claude Desktop / Lovable / v0 / claude.ai — paste the server URL in the app's connector settings: https://api.qualityclouds.ai/mcp

👉 Full per-client guide (all buttons, one-liners and manual snippets): INSTALL.md

This package is the home of the single client registry that powers every install surface (CLI, deep links, install page, docs). It is the source of truth so those surfaces can never contradict each other (functional spec §6, §40 / technical decision D1).

Scope of QSA-1278: the registry, its JSON Schema, a typed loader and CI validation. The CLI itself (detection, safe writer, reporter, probe) lands in QSA-1279/1280/1281; the release pipeline and npm publishing in QSA-1282; the generated install page and docs in QSA-1283.

The registry

One entry per client from the functional §1 table: Cursor, VS Code, Claude Code, Claude Desktop, Windsurf (local) and the web builders Lovable, v0, claude.ai. Each entry carries: id, display name, config file locations per OS (macOS/Windows/Linux), config entry templates (OAuth and API-key variants), deep-link / one-liner / connector-URL templates where supported, and minimum version notes.

Server identity & placeholders

The server is declared once under server (name, entryKey, url). Templates never hardcode the URL — they use render-time tokens so a single edit propagates to every surface:

| Token | Meaning | |---|---| | {{SERVER_URL}} | The MCP server URL (server.url) — the only thing written to a config | | {{SERVER_NAME}} / {{SERVER_NAME_URLENCODED}} | Server display name | | {{SERVER_ENTRY_KEY}} | Stable key our entry is upserted under (idempotency) | | {{CONFIG_BASE64}} / {{CONFIG_URLENCODED}} | Encoded OAuth entry JSON for deep links | | {{API_KEY}} | User-supplied key — only ever rendered into the API-key variant, never into an OAuth template or a deep link |

No credentials by construction: OAuth surfaces (entry template, deep link, connector URL, one-liner) contain only the server name and URL. This is enforced in CI (§7, §38).

server.url here is production (https://api.qualityclouds.ai/mcp) — every public surface (README, INSTALL.md, install page, deep links, default npx) resolves to prod. Staging and development are published only under npm dist-tags and are not advertised here; developers reach them with npx norma-mcp-init@staging / @dev. The endpoint is baked per environment at publish time — see docs/RELEASING.md. Note: the VS Code entry carries a static oauth.clientId (VS Code has no Dynamic Client Registration); the same id is used in all environments, so that Keycloak client must be registered in each realm — it is registered in the dev, staging and production realms.

Consuming the registry

import { clientRegistry, localClients, configLocations } from 'norma-mcp-init';

clientRegistry.server.url;            // "https://api.qualityclouds.ai/mcp"
localClients().map((c) => c.id);      // ["cursor","vscode","claude-code","claude-desktop","windsurf"]
configLocations('cursor', 'macos');   // ["~/.cursor/mcp.json"]

The build-time docs/landing pipeline reads the raw JSON directly: import clients from 'norma-mcp-init/clients.json'.

Development

npm install
npm run validate   # schema + semantic validation (CI gate — see below)
npm run typecheck
npm test           # vitest — covers the four acceptance-criteria scenarios
npm run build      # tsc -> dist/ + copies the registry JSON alongside

CI gate

npm run validate fails with a non-zero exit code if the registry violates the schema or the business rules (missing client, missing OS location, leaked credential). It runs in the GitHub Actions release workflow (and locally via prepublishOnly); the acceptance criterion "Invalid registry blocks release" is satisfied by this exit code.

Adding or changing a client

Edit src/registry/clients.json (and, only if a client needs a genuinely new config shape, add a writer variant later in the CLI). Run npm run validate. Because npx always fetches the latest published version, the fix reaches users with zero action on their side (§18, §34).

CLI — client detection (QSA-1279)

npx norma-mcp-init                    # detect installed clients, multi-select (detected pre-checked)
npx norma-mcp-init --client cursor    # target a client by name (repeatable), no prompt
npx norma-mcp-init --workspace        # write project-local config in the current folder
npx norma-mcp-init --api-key <key>    # CI/headless: write the API-key entry variant
npx norma-mcp-init --remove           # clean uninstall: remove only our entry
npx norma-mcp-init --help

Scope. By default the CLI writes the per-user config (global — the server is available in every window of that client). --workspace instead writes a project-local file in the current folder, for clients that support it:

| Client | Workspace file | |---|---| | Cursor | .cursor/mcp.json | | VS Code | .vscode/mcp.json | | Claude Code | .mcp.json |

Commit that file to share the server with everyone who opens the project. Clients without a project scope (Windsurf, Claude Desktop) are skipped under --workspace.

Detection is registry-driven and conservative (src/detection): a client is detected when its config file or parent directory exists for the current OS. Unresolvable locations (e.g. a missing Windows env var) are reported as not detected — never guessed. When no client is detected the CLI prints the full per-client manual instructions and the install page URL. --client exits non-zero if a named client's config location cannot be determined.

Selected clients are configured by the safe writer (src/config): a surgical, idempotent OAuth-mode upsert via jsonc-parser (server URL only — no credentials), with a single rotating .qc-backup, abort-on-malformed, and per-client isolation so one failure never aborts the run. A post-install probe checks reachability (401 + WWW-Authenticate = success) and the CLI prints a per-client report with the "sign in on first use" closing message.

--api-key writes the API-key entry variant embedding the user-supplied key (the only credential the CLI ever handles — it never creates keys). --remove deletes only our entry (desired-state: "nothing to remove" when absent), reusing the same backup/surgical/isolation guarantees. Both are covered by a round-trip test (§37): init → init → remove restores the prior state.

Install page & docs generation (QSA-1283)

Every published surface is generated from the registry at build time (src/surfaces, decision D1/D4) — hand-written per-client content is forbidden, because drift is the bug this phase kills:

npm run generate   # writes dist/surfaces/index.html and dist/surfaces/install.md

The landing/docs pipeline consumes the exported generators directly:

import { generateInstallPage, generateDocsMarkdown, deepLinkFor, badgeMarkdownFor } from 'norma-mcp-init';
  • Deep links (D3): static strings — cursor://…?config=<base64 {url}> and vscode:mcp/install?<url-encoded {name,type,url}> — identical for every user, carrying only the server name and URL (no secrets, enforced by tests).
  • Install page: one static "Get started in your IDE" page; client-side JS detects the OS to order options but never hides any — every path is always present, and each deep link is accompanied inline by the CLI command and the manual snippet (§9).
  • Docs/README parity: generateDocsMarkdown emits the same per-client content (badges, one-liners, connector URLs, manual snippets) from the one source (§6).

Publishing to npm (multi-environment)

Distribution is publication to the public npm registry; npx fetches and runs the package on the fly. One package, three targets selected by npm dist-tag — the endpoint is baked into each published artifact at build time. Full runbook: docs/RELEASING.md.

| Command | dist-tag | endpoint | git branch | version | |---|---|---|---|---| | npx norma-mcp-init | latest | api.qualityclouds.ai/mcp | main | X.Y.Z | | npx norma-mcp-init@staging | staging | api-staging.qualityclouds.ai/mcp | develop | X.Y.Z-staging.N | | npx norma-mcp-init@dev | dev | api-development.qualityclouds.ai/mcp | develop | X.Y.Z-dev.N |

Prerelease versions (-staging/-dev) are never resolved by a plain npx, so the non-prod targets stay invisible to the default install. The OAuth clientId is the same across all environments (see the note above).

⚠️ A published version is globally available within seconds and cannot be overwritten (only deprecated). scripts/release.mjs refuses to publish an environment from the wrong branch and computes the next prerelease index.

Ways to publish

  • Manual (local, needs npm whoami): npm run release:prod | release:staging | release:dev. Each runs prepublishOnly (build && validate && test), bakes the environment, and publishes under the right tag.
  • GitHub Actions: .github/workflows/release.yml — push to main publishes prod/latest; develop publishes @staging and @dev; needs an NPM_TOKEN repo secret.

Safe local verification (never publishes)

npm run release:staging -- --dry-run   # full flow, no upload
npm pack --dry-run                     # list exactly what would be uploaded