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

enpilink

v1.1.1

Published

enpilink is a framework for building ChatGPT and MCP Apps

Downloads

1,342

Readme

enpilink

The open, account-free full-stack framework for MCP Apps — and the ChatGPT Apps SDK.

Build type-safe MCP servers whose tools render interactive React views inside Claude, ChatGPT, VS Code, Goose, and any other MCP-Apps-compatible host.

a fork of alpic-ai/skybridge · powered by


Account-free by design

Local dev, public tunneling, and deploy all work with no account, no token, and no vendor lock-in:

  • Account-free tunneling via srv.us — open and SSH-based, no signup. enpilink dev --tunnel gives you a public /mcp URL in seconds and auto-generates an SSH key at ~/.enpilink/id_ed25519 the first time.
  • No telemetry — zero analytics, no network calls, no embedded keys.
  • Deploy anywhereenpilink build produces a standard Node server (node dist/__entry.js); self-host on any platform or container.
  • All five mcp-ui interaction typestool, prompt, link, intent, and notify.

MCP Apps compliance

enpilink is a compliant MCP Apps framework, built on the official @modelcontextprotocol/ext-apps extension (stable spec 2026-01-26). It serves view resources for both runtimes so the same view runs in either host:

  • ui://views/ext-apps/* — MCP Apps (Claude, Goose, VS Code, …)
  • ui://views/apps-sdk/* — ChatGPT Apps SDK

The mcp-ui interaction types

An interaction type is one of the structured messages a view sends back to its host. The mcp-ui standard defines five, and enpilink supports all five (views send them through hooks, never raw postMessage):

| Type | Hook | Behavior | |---|---|---| | tool | useCallTool | real on both runtimes | | prompt | useSendFollowUpMessage | real on both runtimes | | link | useOpenExternal | real on both runtimes | | intent | useIntent | no spec equivalent on either runtime; best-effort extension, may no-op on hosts that don't route it | | notify | useNotify | real MCP notifications/message on MCP Apps; best-effort extension on the ChatGPT Apps SDK |

These five are the standard's view→host actions. They're a subset of the full hook API below (the rest of the hooks read host context or control your own view). New to all this? See PRESENTATION.md for a plain-language, diagram-led tour.

notify and intent are guarded and additive: they never throw and degrade to a no-op (or a log line) on hosts without support. See docs/guides/interaction-types.mdx for the full per-runtime matrix.

All view hooks

Everything a view can do from inside the iframe — import from enpilink/web. Hooks never touch raw postMessage; the bridge picks the right runtime call.

| Hook | What it does | Runtime | |---|---|---| | Interaction | | | | useCallTool | Call a server tool from the view; returns { callTool, callToolAsync, data, status, error } with pending/success/error state. | both | | useSendFollowUpMessage | Send a text message to the model as a user follow-up turn (prompt). | both | | useNotify | Surface a notification/status to the host: notify({ message, level?, title?, data? }). | both — real notifications/message on MCP Apps, best-effort on Apps SDK | | useIntent | Express a high-level intent for the host to route: sendIntent({ name, params? }). | both — best-effort extension, may no-op | | Navigation / links | | | | useOpenExternal | Open a URL outside the iframe via the host (use instead of window.open). | both | | useSetOpenInAppUrl | Override the URL the host's fullscreen "Open in app" affordance points to. | Apps SDK only (throws on MCP Apps) | | useRequestClose | Ask the host to dismiss/close the view. | both | | Layout / display | | | | useDisplayMode | Read and request the display mode — inline / pip / fullscreen. | both | | useRequestModal | Open the view in a host modal overlay; returns { isOpen, params, open }. | both | | useRequestSize | Ask the host to resize the iframe to fit your content. | both | | useLayout | Read the visual environment — max height, safe-area insets, theme. | both | | Context / data | | | | useToolInfo | Read the typed input / output / metadata of the tool call that rendered this view. | both | | useViewState | [state, setState] persisted on the host across remounts of the view. | both | | useUser | Session-stable user/environment info (device type, hover/touch capability). | both | | Files | | | | useFiles | Host file operations — upload, getDownloadUrl, selectFiles (native picker). | Apps SDK only (throws on MCP Apps) | | useDownload | Download an MCP EmbeddedResource / ResourceLink's contents via the host. | both | | Advanced | | | | useRegisterViewTool | Let the view expose its own tool to the host/model (app-provided tool). | MCP Apps only (no-op on Apps SDK) |

"both" = works on MCP Apps (Claude, Goose, VS Code…) and the ChatGPT Apps SDK. Apps-SDK-only hooks throw on MCP Apps; MCP-Apps-only hooks no-op on the Apps SDK.


Observability & Admin

enpilink ships an opt-in observability + admin layer — off by default, with zero overhead and zero network when disabled (still no telemetry to us).

  • Observability — set ENPILINK_ANALYTICS=1 to record per-tool-call volume, latency (p50/p95/p99), and error rate, viewable in the Console Dashboard with a live log stream. Try it with demo data: enpilink dev --mock (deterministic, in-memory, no real traffic). See docs/guides/observability.mdx.
  • Configuration — a typed config layer with env > file > DB precedence, a Configuration admin tab for runtime settings, env-only masked secrets, and a change audit log. See docs/guides/configuration.mdx.
  • Admin (production) — expose the Dashboard + Configuration in prod with enpilink start --admin + ENPILINK_ADMIN_TOKEN (refuses to start without a token). Two-tier auth keeps /mcp and the SPA shell public while gating the data APIs behind a static bearer token; for SSO, front it with a reverse proxy (Cloudflare Access / oauth2-proxy / Tailscale) or self-hosted OIDC. See docs/guides/admin.mdx.
  • Storage — pluggable adapters: memory (dev), sqlite (prod default, ENPILINK_DB_PATH), postgres (ENPILINK_DB_URL/DATABASE_URL/PG*), plus registerStorageAdapter for custom backends, and optional OpenTelemetry metrics export (ENPILINK_OTEL=1 + OTEL_EXPORTER_OTLP_ENDPOINT). See docs/guides/storage.mdx.

Documentation

New here? Read PRESENTATION.md first — a plain-language, diagram-led tour of the whole platform (what it solves, the standards, the technology, and how interaction types relate to hooks). No prior knowledge needed.

There's no hosted docs site yet — the full docs run locally with Mintlify:

pnpm install
pnpm docs:dev          # serves the docs at http://localhost:3000

What's inside docs/:

  • API reference (docs/api-reference/) — a page per hook and core API (useCallTool, useNotify, useViewState, registerTool, …), each with the signature, a runnable example, and runtime support. This is the "what can I actually do with this hook" reference.
  • Guides (docs/guides/) — task-oriented: communicating with the model, managing state, host-environment context, fetching data, the interaction types, and the observability / configuration / admin / storage layer.
  • Concepts & fundamentals — MCP Apps vs the Apps SDK, write-once-run-everywhere, type safety, and data flow.
  • Quickstart — create a new app, add to an existing server, deploy, migrate.

Tip: you can also read any page directly as Markdown in docs/ on GitHub — e.g. docs/api-reference/use-notify.mdx.


Quickstart

Prerequisites

  • Node.js ≥ 22
  • ssh (ships with macOS/Linux) — only needed for --tunnel

Run the built-in kitchen-sink demo

The fastest way to see everything is the bundled kitchen-sink showcase (a fictional store, Northwind): 9 tools, 9 views, all 4 interaction types, every host hook, deterministic mock data.

git clone https://github.com/enpitech/enpilink
cd enpilink && pnpm install && pnpm run build

cd examples/kitchen-sink
pnpm dev          # Console + HMR at http://localhost:3000/
pnpm dev:tunnel   # opens an account-free srv.us tunnel and prints a public /mcp URL

Then connect it to Claude:

  1. Copy the printed https://<hash>.srv.us/mcp URL.
  2. In Claude → Settings → Connectors → Add custom connector, paste that URL.
  3. Paste the contents of examples/kitchen-sink/specs/SYSTEM_PROMPT.md into your Claude project instructions (MCP can't set a host system prompt, so this tells the assistant which tools to call).

Scaffold a new app

npm create enpilink@latest my-app

POC distribution caveat. enpilink and @enpilink/console are not yet published to npm, so a freshly scaffolded app's npm install will fail on the workspace:* ranges in the templates. For real distribution, publish both packages to npm and run node scripts/bump.js <version> to rewrite the templates' workspace:* ranges to ^<version>. Until then, scaffold inside this monorepo (the templates resolve via the workspace) or use local pnpm pack tarballs. See Status below.

The account-free tunnel under the hood is just one SSH command:

ssh srv.us -R 1:localhost:<port>

enpilink wraps this with auto key-gen (~/.enpilink/id_ed25519), URL parsing, and auto-reconnect.


CLI

enpilink dev [--tunnel] [-p <port>] [--open] [--mock]   # dev server + Console + HMR (alias: enpi)
enpilink build                                           # compile server + views → dist/
enpilink start [--admin]                                 # run the production build (node dist/__entry.js)
enpilink create [dir]                                    # scaffold a new app (passthrough to create-enpilink)

Production gotcha

The production entry reads the __PORT environment variable (NOT PORT), defaulting to 3000:

__PORT=8080 node dist/__entry.js

enpilink start sets __PORT for you. enpilink build also rewrites server @/… path aliases automatically, so you do not need tsc-alias in your own build scripts.


Repo layout

enpilink/
├── packages/
│   ├── core/             → npm "enpilink": server framework + React hooks + Vite plugin + CLI (oclif + Ink)
│   ├── console/          → "@enpilink/console": dashboard / config / playground / docs web UI
│   └── create-enpilink/  → "create-enpilink": scaffolder (templates: blank, demo)
├── examples/
│   ├── kitchen-sink/     → the all-features showcase ("Northwind"); basis of the demo template
│   └── manifest-ui/      → minimal single-view smoke-test example
├── docs/                 → Mintlify documentation
├── skills/               → agent skill for building enpilink apps
└── scripts/              → version bump / overrides helpers

Status

This is a POC fork. Today:

  • ✅ Local dev, Console, HMR, build, and self-host all work account-free.
  • ✅ The account-free srv.us tunnel is live-verified end-to-end (the printed /mcp URL round-trips over a real public tunnel and survives reconnects).
  • Real npm distribution requires publishing enpilink + @enpilink/console to npm, then running node scripts/bump.js <version>. Until then, npm create enpilink is workspace-linked (works inside this repo / via local tarballs, not from a bare npm install).

Attribution & license

enpilink is released under the MIT License. It is forked from alpic-ai/skybridge (MIT); the original copyright is retained in LICENSE, and the fork's changes are summarized in NOTICE.

Built and maintained by the Enpitech team.