MCP UI Kit
Build interactive React UIs for MCP tools.
The Model Context Protocol (MCP) enables AI assistants to interact with external tools. mcp-ui-kit simplifies building rich UI components that render directly in AI chat:
- Bundling on-demand — Write React components, bundled automatically when the tool is called
- Zero config — No webpack/vite setup, just
createUI()and point to your.tsxfile - Props from server — Pass data from your MCP tool directly to React via
useProps() - Two-way communication — Components can
sendPrompt()to the AI orcallTool()to invoke other MCP tools
MCP UI Inspector — Built on @mcp-ui/server
Installation
npm install mcp-ui-kit @modelcontextprotocol/sdk
Server Usage
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { createUI } from 'mcp-ui-kit/server';
const server = new McpServer({ name: 'my-server', version: '1.0.0' });
const dashboardUI = createUI('my-dashboard', import.meta.resolve('./Dashboard.tsx'));
server.registerTool(
'dashboard',
{ description: 'Interactive dashboard', _meta: dashboardUI.meta },
async () => ({
content: [
{ type: 'text', text: 'Dashboard loaded' },
await dashboardUI.component({ props: { title: 'Hello' }, frameSize: ['700px', '500px'] })
]
})
);
With Input Schema
import { z } from 'zod';
import { createUI } from 'mcp-ui-kit/server';
const stockUI = createUI('stocks', import.meta.resolve('./StockDashboard.tsx'));
server.registerTool(
'stock_portfolio',
{
description: 'View stock portfolio',
_meta: stockUI.meta,
inputSchema: {
symbols: z.array(z.string()).default(['AAPL', 'GOOGL']),
timeframe: z.enum(['1D', '1W', '1M', '1Y']).default('1M'),
},
},
async ({ symbols, timeframe }) => ({
content: [
{ type: 'text', text: `Showing ${symbols.join(', ')} for ${timeframe}` },
await stockUI.component({ props: { symbols, timeframe } })
]
})
);
Client Usage
The file passed to createUI() must render a component to the #root element:
// StockDashboard.tsx
import { createRoot } from 'react-dom/client';
import { sendPrompt, callTool, useProps } from 'mcp-ui-kit/ui';
function StockDashboard() {
const { symbols, timeframe } = useProps({ symbols: ['AAPL'], timeframe: '1M' });
return (
<div>
<h1>Stock Portfolio ({timeframe})</h1>
{symbols.map(symbol => (
<div key={symbol}>
<span>{symbol}</span>
<button onClick={() => sendPrompt(`Analyze ${symbol} over ${timeframe}`)}>
Analyze
</button>
<button onClick={() => callTool('get_stock_price', { symbol })}>
Refresh
</button>
</div>
))}
</div>
);
}
// Render to DOM
createRoot(document.getElementById('root')!).render(<StockDashboard />);
API
Server (mcp-ui-kit/server)
createUI(name, componentPath) — Creates a UI component
componentPath: Path to a.tsxfile that renders to#root- Returns
{ meta, component(opts?) } opts.props: Data passed to your React component viauseProps()opts.frameSize:[width, height]e.g.['700px', '500px']
createUI('dashboard', import.meta.resolve('./Dashboard.tsx')); // ESM
createUI('dashboard', require.resolve('./Dashboard.tsx')); // CommonJS
UI (mcp-ui-kit/ui)
useProps(defaults)— Get props passed from the serversendPrompt(message)— Send a message to the AI chatcallTool(name, params)— Invoke an MCP tool
Development
npm install
npm run dev:all # Start demo server + inspector
Description
Languages
TypeScript
73.8%
CSS
23.7%
JavaScript
2.2%
HTML
0.3%