Build your MCP App once. Run it in every host.
Enpilink is our open-source TypeScript framework for MCP Apps and ChatGPT Apps: tools that render interactive React views inside Claude, ChatGPT, VS Code, Goose and other hosts.
MIT licensed, account-free, and yours to self-host.
npm create enpilink@latestA tool the model calls, with a real interface.
An MCP server gives an AI model tools it can call. An MCP App goes one step further: the tool also returns a view, and the host renders it right inside the conversation. A product list you can click, a form, a chart.
ChatGPT and the open MCP Apps standard run those views on different runtimes. Enpilink puts both behind one React API. You write the server and the views once, and every host gets the version it understands.
One stack for every host. MIT licensed, built on the official MCP SDK, nothing sent back to us.
It is React and TypeScript. Hooks instead of postMessage, hot reload, typed tool data.
See what the model sees. A Console to run every tool, and evals that check a prompt reaches it.
Everything around the view, already built.
The view is the part you want to write. Runtimes, types, auth, previews and tests are the parts that slow it down.
Write once, run in every host
One server and one set of React views. Enpilink serves both the MCP Apps and the ChatGPT Apps SDK versions, and the view picks the right runtime when it loads.
Type-safe end to end
Tool inputs are zod schemas, and views get typed input and output generated from the server. Rename a field and the type checker tells you, not the chat.
A hook for everything a view does
Call a tool, send a follow-up message, open a link, go fullscreen, keep state across remounts. React hooks, never raw postMessage.
Account-free dev, instant tunnel
One command starts the server, the Console and hot reload. Add --tunnel for a public /mcp URL to paste into Claude or ChatGPT. No signup.
A Console for the whole loop
Dashboard, logs, configuration, a Playground with realistic ChatGPT and Claude previews, and an OAuth debugger, right beside your server.
OAuth that is ready for production
Validate your identity provider’s tokens as a resource server, or run the built-in authorization server with a branded login and guest mode.
Tests for what unit tests miss
Evals check that a natural prompt reaches the right tool with the right arguments. View tests render every view across host, theme and device.
Yours to run
Admin plane secured by default, no telemetry, self-host anywhere Node runs. Built on the official MCP SDK v2 and the 2026-07-28 spec.
Server tool in. Interface out.
- 1SERVER
Define a tool
Register it on your MCP server with a zod input schema and the name of the view it renders.
- 2VIEW
Write the view
A React component that reads the tool’s typed output and acts through hooks.
- 3HOST
The host renders it
The model calls the tool, and Claude, ChatGPT or VS Code shows your view inline in the chat.
- Green SenchaTeaDetailstoolQuick lookmodalAdd to cartintent
- Oat Crunch CookiesSnacksDetailstoolQuick lookmodalAdd to cartintent
- Travel Press MugGearDetailstoolQuick lookmodalAdd to cartintent
A simplified recreation of the Console’s realistic preview, running the kitchen-sink demo’s catalog view. Switch hosts: the view is the same code.
This is a whole app.
One tool on the server, one component for its view. The view’s types come from the server, so the two cannot drift apart.
- 01 · SCAFFOLD A PROJECT
npm create enpilink@latest my-app - 02 · SERVER, CONSOLE AND HOT RELOAD
npm run dev - 03 · A PUBLIC /MCP URL FOR CLAUDE OR CHATGPT
npm run dev -- --tunnel
Needs Node.js 22 or later. The Console opens at localhost:3000.
src/server.ts
import { McpServer } from "enpilink/server";import { z } from "zod";const server = new McpServer({ name: "my-app", version: "0.0.1" }, {}) .registerTool( { name: "greeting", description: "Greet someone by name.", inputSchema: { name: z.string() }, view: { component: "greeting" }, }, async ({ name }) => { return { structuredContent: { message: `Hello, ${name}!` } }; }, );src/views/greeting.tsx
import { useToolInfo } from "../helpers.js"; // auto-generated from server schemaexport default function Greeting() { const { output } = useToolInfo<"greeting">(); return <h1>{output.message}</h1>;}Watch it, configure it, debug it. In one Console.
The Playground above is one tab of the Console that runs beside your app. The rest covers what happens after the view works. Outside your own machine, it is sign-in gated by default.
Dashboard and logs
Per-tool call volume, latency and error rate, with a live log stream. Recording is opt-in and stays on your server.
Configuration
Typed runtime settings, environment over file over database. Secrets stay in the environment, and every change is audited.
- Analytics enabledanalytics.enabled
- Live log streamflags.liveLogs
- Event retentionretention.events
- env only · maskedAdmin tokenENPILINK_ADMIN_TOKEN
OAuth debugger
Walks the MCP sign-in flow one step at a time and checks every response against the spec.
- Unauthenticated requestSPEC OK
- Protected Resource MetadataSPEC OK
- Authorization Server metadataSPEC OK
- Client registrationSPEC OK
- Authorization request
- Token exchange
- Authenticated MCP call
View tests
enpilink test views renders each view in both hosts, both themes and both devices, against screenshot baselines.
light · desktop
dark · desktop
light · mobile
dark · mobile
light · desktop
dark · desktop
light · mobile
dark · mobile
Simplified recreations of the Enpilink Console, redrawn from the kitchen-sink example. Placeholder bars stand in for live values.
Your first MCP App is one command away.
Free and open source under the MIT license. Read the code, open an issue, send a pull request.
npm create enpilink@latestReady to shift?
We accelerate Frontend delivery. The Frontend Delivery Factory installs the system that lets everyone in your org ship production Frontend.
Senior engineers, AI-native by default, shipping production code in your repo. Fast onboarding. Honest work.
- 01
You send the form.
A few lines on your product and timeline.
- 02
We reply within a day.
Usually faster. No forms after that.
- 03
We meet and plan.
Scope, team fit, start date. Then engineers.