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

create-privos-mcp-app

v0.5.2

Published

CLI scaffolder for Privos MCP apps

Readme

create-privos-mcp-app

CLI scaffolder for PrivOS MCP app projects. Generates a ready-to-run Express + React + TypeScript app with MCP protocol support.

Version 0.3.0 adds the canonical Marketplace privos-app.json, production runtime-v3 dispatch verification, a production Dockerfile, NodeNext ESM server output and graceful container shutdown.

Version 0.5.0 fixes production UIs rendering blank: the generated server now serves the built UI through @privos_ai/app-server's serveBuiltUi helper instead of returning the raw Vite index.html. See Production UI: assets served by the Hub below — apps scaffolded from 0.4.0 or earlier keep the bug until upgraded.

--template instant scaffolds an INSTANT (frontend-only, no runtime) app for a publisher that ships only a UI — no server, no Dockerfile, no @privos_ai/app-server dependency. See Templates below.

Usage

npx create-privos-mcp-app my-app
cd my-app
npm install
npm run dev

Templates

npx create-privos-mcp-app my-app --template default    # Express + React + MCP server (the default)
npx create-privos-mcp-app my-app --template instant     # frontend-only, no server, no Dockerfile

default scaffolds the full MCP app server described below. instant scaffolds only the Vite/React UI plus a privos-app.json declaring executionMode: "INSTANT" with a required ui.entryPoints.roomTab and an optional agent section — there is no runtime to configure, so tools, serverUrl/runtimeTrustProvisioningUrl, port, resources, volumes and stateless are all rejected by privos-app lint for this mode. An unknown --template name exits with the list of valid names.

What Gets Generated

my-app/
├── privos-app.json         # Marketplace/runtime manifest, schema version 1
├── Dockerfile              # Marketplace source-build entry point
├── package.json            # @privos_ai SDKs, Express, React, Vite, TypeScript
├── tsconfig.server.json    # Production server build
├── vite.config.ts          # UI build config
└── src/
    ├── server.ts           # MCP server (manifest + JSON-RPC + UI serving)
    └── ui/
        ├── App.tsx            # PrivosAppProvider wrapper
        ├── main.tsx           # React entry point; sets the boot flag the shell's watchdog waits for
        └── lazy-boundary.tsx  # Error boundary for React.lazy panels — "Reload" on a stale chunk

Generated Server

The Express server handles:

| Route | Purpose | |-------|---------| | GET /.well-known/mcp/manifest.json | Exact reviewed privos-app.json | | POST /mcp | JSON-RPC 2.0: initialize, tools/list, resources/read | | UI serving | Vite dev server (dev) or static files (prod) |

Generated UI

Uses @privos_ai/app-react hooks:

import { PrivosAppProvider, usePrivosContext, useLists } from '@privos_ai/app-react';

The generated backend uses @privos_ai/app-server.

Production UI: assets served by the Hub

npm run build produces dist/index.html (the shell) plus content-hashed files under dist/assets/ (Vite base: './', build.manifest: true, sourcemap: false; no publicDir — everything the UI needs must ship as a hashed assets/ file). The generated server never serves dist/assets itself: at production boot it constructs serveBuiltUi({ distDir, appSlug }) once, and that instance answers resources/read for both the shell (ui://<app>/dashboard.html) and each asset (ui://<app>/assets/<file>) — the Hub fetches assets over the same MCP transport as the shell, caches them, and re-serves them from its own origin behind a short-lived per-user token so the about:srcdoc frame can load them cross-origin. This requires a Hub that understands the <meta name="privos-ui-assets" content="relay"> opt-in the shell carries and the asset-relay route — requires Hub ≥ tenant.N. On an older Hub the shell's inline boot watchdog shows a "Retry" panel after 10 seconds instead of rendering blank.

serveBuiltUi validates the build at construction and throws (crashing the process at boot, not on the first request) if:

  • any <script>/<link> tag in index.html is not ./assets/… or assets/… (the app was built without base: './');
  • a file under dist/assets does not match the content-hashed filename rule name-<hash>.ext (hash ≥ 8 chars) with an allowed extension (js, css, svg, json, woff, woff2, ttf, png, jpg, jpeg, gif, webp, avif, ico, wasm, gz);
  • a .map file is present under dist/assets (sourcemaps must never be published — the build already disables them);
  • an asset exceeds 2 MB.

Files that don't match the filename rule or aren't listed in the build's assets manifest are never served, even if they exist on disk.

Production runtime boundary

The generated server refuses to start in production until PRIVOS_RUNTIME_SECURITY_MODE is set:

  • managed-v2 requires the managed workload broker and legacy Cluster dispatch assertion;
  • runtime-v3 requires PRIVOS_RUNTIME_DISPATCH_TRUST_V3, parsed as the strict {hubKid,hubPublicJwk,affinity} configuration accepted by parseRuntimeDispatchTrustV3Json.

Set PRIVOS_RUNTIME_ALLOW_UNSIGNED_PREACTIVATION_READINESS=true only for a Hub-supervised local runtime. It does not permit executable or data-bearing methods, and Relay ignores it. Publisher readiness never uses this exception.

For runtime-v3, provisioning must supply the pinned Hub key and stable pre-start affinity (workspace, deployment, app, execution mode, generation, runtime installation, manifest digest, and resource-manifest hash). The server never learns trust from an inbound assertion. Local runtime configuration uses bounded process-local replay protection. Publisher configuration uses the durable single-process file store described below.

For publisher-hosted mode, replace the placeholder runtimeTrustProvisioningUrl in privos-app.json with the canonical public HTTPS endpoint reviewed by Marketplace, then set:

PRIVOS_RUNTIME_SECURITY_MODE=runtime-v3
PRIVOS_PUBLISHER_RUNTIME_TRUST_STORE_PATH=/var/lib/my-app/privos-runtime-trust.json
PRIVOS_PUBLISHER_SINGLE_PROCESS=true
PRIVOS_PORTAL_ISSUER=portal:marketplace-broker
PRIVOS_PORTAL_JWKS_URL=https://portal.privos.io/approval-jwks

The generated server mounts the trust endpoint before its JSON parser, verifies the Portal chain and Hub proof, persists atomic PREPARED/ACTIVE state, and uses the durable record as its dispatch trust resolver and replay store. The reference file store fails closed unless single-process mode is explicitly selected. Multiple processes or replicas require a shared transactional PublisherRuntimeTrustDurableStoreV3 implementation.

Changing privos-app.json after pairing

Edit privos-app.json and restart — the server sets manifest on the descriptor it passes to connectRelay (src/server.ts:222), so app-server echoes the loaded manifest and the Hub's Refresh detects the change. Re-pairing a live app is refused; use Hub Admin → Apps → your app → Settings → Refresh to review and approve the update instead.

Publish to PrivOS Marketplace

Keep privos-app.json and Dockerfile at the project root. Package the project so both files are at the ZIP root, not inside an enclosing directory. The Marketplace reads the package version, app identity, scopes, tools, resource request, state model and license tiers from this manifest and validates it server-side.

Register in Privos

  1. Start the app: npm run dev
  2. In PrivOS Admin → Apps → Connect App
  3. Enter server URL (e.g., http://localhost:3001)
  4. Review and add the app to the Hub App Library
  5. Open a room and choose Add to this room when room access is wanted

Documentation

License

MIT