MCP server and library for rendering dynamic React UI components in AI conversations
npm install dynamic-ui-mcpA 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.
- 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
``bash`
npm install dynamic-ui-mcp
`bash`
npm install react sucraseOptional for charts and syntax highlighting:
npm install recharts prismjs
`typescript
// 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();
}
`
`tsx
// 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 (
{part.text}
; if (part.type.startsWith("tool-")) {
const toolName = part.type.replace("tool-", "");
return (
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;
})}
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:
`tsx
import Pager from 'pager';
import MultiChoice from 'multi-choice';export default function Quiz({ onSubmit }) {
return (
pages={[
{
title: "Question 1",
content: 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:
`bash
npx dynamic-ui-mcp
`Configure in Claude Desktop's
claude_desktop_config.json:`json
{
"mcpServers": {
"dynamic-ui": {
"command": "npx",
"args": ["dynamic-ui-mcp"]
}
}
}
`Publishing
To publish your own version:
`bash
npm login
npm publish
`Development
`bash
Install dependencies
npm installBuild
npm run buildType check
npm run typecheckLint
npm run lintRun demo
cd demo && npm install && npm run dev
``MIT