dynamic-ui-mcp
v0.1.0
Published
MCP server and library for rendering dynamic React UI components in AI conversations
Maintainers
Readme
dynamic-ui-mcp
A library that enables AI models to render interactive UI components inline during conversations. Works as both an MCP server and a direct library for Vercel AI SDK.
Features
- Built-in Components: Charts, forms, code blocks, image viewers, multi-choice questions, multi-page wizards
- Custom Components: Models can generate custom React components on-the-fly
- Two Deployment Modes:
- MCP Server: Run standalone for Claude Desktop or other MCP clients
- Library Mode: Import directly into Next.js/React apps with Vercel AI SDK
Installation
npm install dynamic-ui-mcpPeer Dependencies
npm install react sucrase
# Optional for charts and syntax highlighting:
npm install recharts prismjsQuick Start (Library Mode)
1. API Route
// app/api/chat/route.ts
import { anthropic } from "@ai-sdk/anthropic";
import { streamText, tool, convertToModelMessages } from "ai";
import {
renderSchema,
renderCustomSchema,
executeRender,
executeRenderCustom,
generateSystemPrompt,
getComponentIds,
} from "dynamic-ui-mcp";
const SYSTEM_PROMPT = generateSystemPrompt();
export async function POST(req: Request) {
const { messages } = await req.json();
const modelMessages = await convertToModelMessages(messages);
const result = streamText({
model: anthropic("claude-sonnet-4-20250514"),
system: SYSTEM_PROMPT,
messages: modelMessages,
tools: {
render: tool({
description: `Render a UI component. Available: ${getComponentIds().join(", ")}`,
inputSchema: renderSchema,
execute: async (args) => executeRender(args),
}),
renderCustom: tool({
description: "Render custom React TSX code",
inputSchema: renderCustomSchema,
execute: async (args) => executeRenderCustom(args),
}),
},
});
return result.toUIMessageStreamResponse();
}2. React Component
// app/page.tsx
"use client";
import { useChat } from "@ai-sdk/react";
import { DefaultChatTransport } from "ai";
import { DynamicUIRenderer } from "dynamic-ui-mcp/react";
import Prism from "prismjs";
import * as Recharts from "recharts";
// Load Prism languages you need
import "prismjs/components/prism-python";
import "prismjs/components/prism-typescript";
const libraries = { prismjs: Prism, recharts: Recharts };
const transport = new DefaultChatTransport({ api: "/api/chat" });
export default function Chat() {
const { messages, sendMessage, status } = useChat({ transport });
return (
<div>
{messages.map((message) => (
<div key={message.id}>
{message.parts.map((part, index) => {
if (part.type === "text") {
return <p key={index}>{part.text}</p>;
}
if (part.type.startsWith("tool-")) {
const toolName = part.type.replace("tool-", "");
return (
<DynamicUIRenderer
key={index}
toolInvocation={{
toolCallId: part.toolCallId,
toolName,
args: part.input,
state: part.state === "output-available" ? "result" : "call",
result: part.output,
}}
libraries={libraries}
onSubmit={(data) => sendMessage({ text: JSON.stringify(data) })}
/>
);
}
return null;
})}
</div>
))}
</div>
);
}Built-in Components
| Component | Type | Description |
|-----------|------|-------------|
| bar-chart | visualization | Bar, line, and pie charts |
| multi-choice | input | Single/multiple choice questions |
| code-block | display | Syntax-highlighted code |
| pager | input | Multi-page wizard with tabs |
| wizard-form | input | Multi-step forms with validation |
| feedback-form | input | Simple feedback collection |
| file-picker | input | File upload with drag & drop |
| image-viewer | media | Image display with zoom |
| web-view | media | Embed YouTube, Vimeo, websites |
Custom Components
Models can create custom components that import built-in ones:
import Pager from 'pager';
import MultiChoice from 'multi-choice';
export default function Quiz({ onSubmit }) {
return (
<Pager
pages={[
{
title: "Question 1",
content: <MultiChoice
question="What is 2 + 2?"
options={[{ value: "4", label: "4" }, { value: "5", label: "5" }]}
/>
},
]}
onSubmit={onSubmit}
/>
);
}MCP Server Mode
Run as a standalone MCP server:
npx dynamic-ui-mcpConfigure in Claude Desktop's claude_desktop_config.json:
{
"mcpServers": {
"dynamic-ui": {
"command": "npx",
"args": ["dynamic-ui-mcp"]
}
}
}Publishing
To publish your own version:
npm login
npm publishDevelopment
# Install dependencies
npm install
# Build
npm run build
# Type check
npm run typecheck
# Lint
npm run lint
# Run demo
cd demo && npm install && npm run devLicense
MIT
