prefab
The TypeScript full-stack framework for MCP app UIs: author server-side, ship JSON, render anywhere.
Install / Use
claude mcp add Max-Health-Inc -- npx -y github:Max-Health-Inc/prefabIf the server publishes to npm under a different name, use that package instead — check the repo README.
MCP Server
Model Context Protocol server
Quality Score
Category
Development & EngineeringSupported Platforms
Tags
Our assessment of prefab
prefab scores 80/100 on our quality scale, 2039th of 3,478 Development & Engineering skills we index.
Its MCP Server is 17 KB long, well organised into 37 sections with 20 code examples: a thorough specification that gives an agent plenty to work with.
It has 3 GitHub stars, so there is little community track record yet; judge it on its content.
Maintenance, license and trust
- The repository was last updated 20 days ago, so prefab is actively maintained.
- Our last check on 2026-09-20 found the source still online.
- It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 92/100, with 1 caution from licensing, adoption, age or documentation. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
prefab compared with similar skills
All 4 of these similar skills score higher than prefab; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| prefab (this skill)by Max-Health-Inc | 80 | 3 | 20d ago | MCP Server |
| Agent-Reachby Panniantong | 100 | 86.1k | 13d ago | CLAUDE.md |
| headroomby headroomlabs-ai | 100 | 74.1k | today | CLAUDE.md |
| rufloby ruvnet | 100 | 73.5k | today | CLAUDE.md |
| CowAgentby zhayujie | 100 | 47.2k | today | CLAUDE.md |
Frequently asked questions
- How do I install prefab?
- Run
claude mcp add Max-Health-Inc -- npx -y github:Max-Health-Inc/prefab. The install tabs above show the steps for each supported agent. - Which AI agents does prefab work with?
- It is written for Claude Code and Claude Desktop, as a MCP Server file. Other agents that read the same format can often use it too.
- Is prefab safe to use?
- It is MIT-licensed and scores 92/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is prefab still maintained?
- The repository was last updated 20 days ago, so prefab is actively maintained.
Skill content
View source on GitHubprefab
The TypeScript full-stack framework for MCP app UIs: author server-side, ship JSON, render anywhere.
A superset of PrefectHQ's Python prefab-ui, on the $prefab v0.3 wire protocol (still renders legacy 0.2 payloads).
Write MCP servers in TypeScript/Bun and generate the same wire format that Python servers produce. Render the output in any web app with the included vanilla DOM renderer. Full circle: server-side DSL → JSON → browser UI.
- 115+ components — layout, form, data, charts, media, interactive, control flow
- Reactive state —
rx()expressions,SetState/ToggleState/AppendStateactions - MCP-native —
display(),display_form(),CallTool,SendMessagebuilt in - Browser renderer — zero dependencies, vanilla DOM (optional separate import)
- PostMessage bridge —
app()factory with dual-protocol handshake, host theme, lifecycle hooks - Auto-renderers —
autoTable(),autoChart(),autoForm(),autoMetrics()and more
Works Everywhere
The renderer is vanilla DOM — no framework dependency. Drop it into any web app:
- React — mount into a
refdiv - Vue / Svelte / Angular — same, it's just DOM
- Plain HTML — single
<script>tag - Electron / Tauri — desktop apps with web views
- Any iframe — MCP Apps, embedded widgets, sandboxed UIs
Any app that connects to MCP servers can render $prefab tool output as rich interactive UI — tables, charts, forms, badges — with zero custom code.
Install
npm install @maxhealth.tech/prefab
# or
bun add @maxhealth.tech/prefab
Quick Start
Server-side (MCP tool handler)
import { display, autoTable, H1, Column } from '@maxhealth.tech/prefab'
async function listUsers(args: any) {
const users = await db.query('SELECT * FROM users')
return display(
Column({ children: [
H1('Users'),
autoTable(users),
]}),
{ title: 'User List' }
)
}
Client-side (browser ext-app)
The auto-mount bundle handles the full lifecycle — bridge handshake,
tool-result rendering, and DOM mounting — with a single <script> tag:
<div id="root"></div>
<script src="https://cdn.jsdelivr.net/npm/@maxhealth.tech/prefab/dist/renderer.auto.min.js"></script>
Works in VS Code, Claude Desktop, ChatGPT, and any MCP Apps host.
For manual control, use renderer.min.js instead:
<script src="https://cdn.jsdelivr.net/npm/@maxhealth.tech/prefab/dist/renderer.min.js"></script>
<script>
const ui = await prefab.app();
ui.onToolInput((args) => {
// Render wire-format JSON received from the MCP host
ui.mount('#root', args);
});
</script>
Components
Layout
Column, Row, Grid, GridItem, Container, Div, Span, Dashboard, DashboardItem, Pages, Page, Detail, MasterDetail
Typography
Heading, H1–H4, Text, P, Lead, Large, Small, Muted, BlockQuote, Label, Link, Code, Markdown, Kbd
Card
Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter
Data Display
DataTable, col, Badge, Dot, Metric, Ring, Progress, Separator, Loader, Icon
Table
Table, TableHead, TableBody, TableFooter, TableRow, TableHeader, TableCell, TableCaption, ExpandableRow
Form
Form, Input, Textarea, Button, ButtonGroup, Select, SelectOption, SelectGroup, SelectLabel, SelectSeparator, Checkbox, Switch, Slider, Radio, RadioGroup, Combobox, ComboboxOption, ComboboxGroup, ComboboxLabel, ComboboxSeparator, Calendar, DatePicker, Field, FieldTitle, FieldDescription, FieldContent, FieldError, ChoiceCard
Interactive
Tabs, Tab, Accordion, AccordionItem, Dialog, Popover, Tooltip, HoverCard, Carousel
Charts
BarChart, LineChart, AreaChart, PieChart, RadarChart, ScatterChart, Sparkline, RadialChart, Histogram
Chart Formatting (Pipe Integration)
TS-only extension — these props are not yet supported by the Python
prefab-uilibrary. The renderer gracefully ignores them if absent, so Python-generated charts still render fine.
Charts use the same pipe system as {{ value | pipe }} expressions — all formatting is declarative JSON:
| Prop | Level | Effect |
|---|---|---|
| xAxisFormat | chart | Pipe applied to x-axis tick labels |
| tooltipXFormat | chart | Pipe applied to tooltip category label |
| tooltipXKey | chart | Read tooltip label from a different data key |
| tooltipFormat | per-series | Pipe applied to that series' value in tooltip |
// Same timestamp field, two presentations:
LineChart({
data: timeseries,
xAxis: 'timestamp',
xAxisFormat: 'date', // axis: "4/25/2026"
tooltipXFormat: 'datetime', // tooltip: "4/25/2026, 2:30:00 PM"
series: [
{ dataKey: 'revenue', label: 'Revenue', tooltipFormat: 'currency' },
{ dataKey: 'growth', label: 'Growth', tooltipFormat: 'percent' },
],
})
All built-in pipes work: upper, lower, truncate, currency, percent, compact, date, time, datetime, number, round, plus custom wire pipes.
Media
Image, Audio, Video, Embed, Svg, DropZone, Mermaid
Alert
Alert, AlertTitle, AlertDescription
Control Flow
ForEach, If, Elif, Else, Define, Use, Slot
Reactive Expressions
Use rx() to create reactive expressions that update when state changes:
import { rx, STATE } from '@maxhealth.tech/prefab'
// Simple state reference
Text(rx('count')) // → "{{ count }}"
// Arithmetic
Text(rx('count').add(1)) // → "{{ count + 1 }}"
// Dot-path access
Text(rx('user').dot('name')) // → "{{ user.name }}"
// Direct template string
Text('Hello, {{ user.name }}!') // interpolated at render time
// Ternary
Badge(rx('status').eq('active').then('Online', 'Offline'))
// Pipes (filters)
Text(rx('amount').currency()) // → "{{ amount | currency }}"
Text(rx('items').length()) // → "{{ items | length }}"
Text(rx('name').upper().truncate(20)) // → "{{ name | upper | truncate:20 }}"
// STATE proxy (single-level shorthand: STATE.key → rx('key'))
Text(STATE.count) // → "{{ count }}"
Built-in pipes: upper, lower, capitalize, truncate, currency, number, percent, date, time, datetime, length, default, json, keys, values, first, last, find, dot, join, abs, round, compact, pluralize, selectattr, rejectattr
Signals, Collections & Selection
Type-safe reactive primitives for master-detail patterns:
import {
signal, collection, DataTable, col, Detail, MasterDetail,
Heading, Text, Badge, PrefabApp,
} from '@maxhealth.tech/prefab'
const patients = collection('patients', data, { key: 'id' })
const sel = signal('selectedPatientId', patients.firstKey())
const ref = patients.by(sel)
const app = new PrefabApp({
title: 'Patient Browser',
view: MasterDetail({
masterWidth: '350px',
children: [
DataTable({
from: patients,
selected: sel,
columns: [
col({ key: 'name', header: 'Name', format: 'humanName' }),
col('gender'),
],
}),
Detail({
of: ref,
empty: Text('Select a patient'),
children: [
Heading(ref.dot('name')),
Badge(ref.dot('gender')),
],
}),
],
}),
// state auto-collected from signal() and collection() — no manual wiring
})
signal(key, initial)— named reactive scalar, auto-registers statecollection(key, rows, { key })— named keyed array with O(1) lookupref.dot(field)— typed property access (Ref<T[K]>)ref.formatted(field, pipe)— dot + pipe shorthand for codegen- Auto state collection —
PrefabAppgathers state from signal/collection factories
Custom Pipes
Extend the pipe system for domain-specific formatting:
import { registerPipe } from '@maxhealth.tech/prefab'
registerPipe('humanName', (names) => {
const hn = (names as { family: string; given: string[] }[])[0]
return hn ? `${hn.family}, ${hn.given.join(' ')}` : ''
})
registerPipe('quantity', (v, unit) => `${v} ${unit ?? ''}`)
// Now usable in expressions: {{ patient.name | humanName }}
// And in col descriptors: col({ key: 'name', format: 'humanName' })
Built-in pipes always take precedence. Re-registration warns and overwrites (HMR-friendly).
Actions
Actions are triggered by user interactions (onClick, onChange, onSubmit) or lifecycle events (onMount).
onClick works on all components — not just Button. Containers like Div, Span, Column, and Row automatically get role="button", tabindex="0", and keyboard (Enter/Space) support:
import { SetState, ToggleState, CallTool, ShowToast, OpenLink, rx } from '@maxhealth.tech/prefab'
// Client-side state mutation
Button('Increment', { onClick: new SetState('count', rx('count').add(1)) })
// Toggle boolean
Button('Toggle', { onClick: new ToggleState('expanded') })
// MCP tool call
Button('Refresh', { onClick: new CallTool('get_data', { arguments: { id: '{{ selectedId }}' } }) })
// Toast notification
Button('Save', { onClick: new ShowToast('Saved!', { variant: 'success' }) })
Client actions: SetState, ToggleState, AppendState, PopState, ShowToast, CloseOverlay, OpenLink, SetInterval, Fetch, OpenFilePicker, CallHandler
MCP actions: CallTool, SendMessage, UpdateContext, RequestDisplayMode
Real-time: Subscribe, Unsubscribe — resource subscriptions with automatic polling fallback
import { Subscribe, Unsubscribe, ShowToast } from '@maxhealth.tech/prefab'
// Live updates — uses native push when available, polls otherwise
new Subscribe('chess://game/abc123', {
stateKey: '$game',
fallbackInterval: 2000,
fallbackTool: '_action',
fallbackArgs: { action: 'refresh' },
onData: new ShowToast('Game updated'),
})
// Cleanup
Button('Leave', { onClick: new Unsubscribe('chess://game/abc123') })
Auto-Renderers
Generate complete UIs from raw data — no manual component wiring:
import { autoTable, autoChart, autoForm, autoMetrics } from '@maxhealth.tech/prefab'
// Table from array of objects
autoTable(users, { title: 'Users', search: true })
// Chart from data + series definitions
autoChart(
salesData,
[{ dataKey: 'revenue', label: 'Revenue', color: '#3b82f6' }],
{ title: 'Revenue', chartType: 'bar', xAxis: 'month' },
)
// Form that submits to an MCP tool
autoForm(
[
{ name: 'email', type: 'email', required: true },
{ name: 'name', label: 'Full Name', required: true },
],
'create_user',
{ title: 'New User', submitLabel: 'Create' },
)
// KPI metric cards
autoMetrics([
{ label: 'Revenue', value: '$42K', delta: '+12%', trend: 'up', trendSentiment: 'positive' },
{ label: 'Us
Truncated for display — read the full file on GitHub.
Related Skills
Agent-Reach
86.1kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu — one CLI, zero API fees.
headroom
74.1kCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.
ruflo
73.5k🌊 The original agent harness. Deploy intelligent multi-player swarms, coordinate autonomous workflows, and build conversational AI systems. Features adaptive memory, self-learning intelligence, federation, vector RAG integration, and native Claude Code / Codex / Hermes and many more Integrated
CowAgent
47.2kOpen-source super AI assistant & Agent Harness. Plans tasks, runs tools and skills, self-evolves with memory and knowledge. Multi-agent, multi-model, multi-channel. Lightweight, extensible, one-line install.
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
