@mcp-web/app
v0.1.3
Published
Build tooling for MCP Apps - bundle React components into single HTML files for AI UI rendering
Readme
MCP Web App
Tooling for simplify creating MCP Apps from UI components. The packages bundles components into single HTML files that AI agents can render inline in chat interfaces like Claude Desktop.
[!IMPORTANT] We currently only support React. Support for more frameworks will be added in the future.
Overview
MCP Apps combine a tool (that AI can call) with a visual React component. When the AI calls the tool, the handler returns props which are passed to your component via the ext-apps protocol. A Vite plugin handles bundling each app into a self-contained HTML file.
Quick Start
Installation
npm install @mcp-web/app1. Define an App
Create a file that exports your apps (e.g. src/mcp-apps.ts):
import { createApp } from '@mcp-web/app';
import { Statistics } from './components/Statistics';
export const statsApp = createApp({
name: 'show_stats',
description: 'Display statistics visualization',
component: Statistics,
handler: () => ({
completionRate: 0.75,
totalTasks: 100,
}),
});2. Add the Vite Build Config
Create a separate Vite config for building apps (e.g. vite.apps.config.ts):
import react from '@vitejs/plugin-react';
import { defineMCPAppsConfig } from '@mcp-web/app/vite';
export default defineMCPAppsConfig({
plugins: [react()],
});Build with:
vite build --config vite.apps.config.tsThis auto-discovers apps in src/mcp-apps.ts and outputs bundled HTML files to public/mcp-web-apps/.
3. Register with MCPWeb
In your web app, register the app so the AI agent can call it:
import { statsApp } from './mcp-apps';
mcp.addApp(statsApp);Input Schemas
Apps can accept input from the AI agent using Zod schemas:
import { createApp } from '@mcp-web/app';
import { z } from 'zod';
import { Chart } from './components/Chart';
export const chartApp = createApp({
name: 'show_chart',
description: 'Display a chart with the given data',
component: Chart,
inputSchema: z.object({
chartType: z.enum(['bar', 'line', 'pie']).describe('Type of chart'),
title: z.string().describe('Chart title'),
}),
handler: ({ chartType, title }) => ({
chartType,
title,
data: getChartData(),
}),
});Host Theming
MCP Apps automatically inherit the host's theme. Use these hooks to access it:
import { useMCPHostTheme, useMCPHostContext } from '@mcp-web/app';
function MyApp(props: MyProps) {
const theme = useMCPHostTheme(); // "light" or "dark"
const hostContext = useMCPHostContext(); // full context (theme, locale, display mode, etc.)
return <div className={theme === 'dark' ? 'dark' : ''}>{/* ... */}</div>;
}Receiving Props
Use the useMCPAppProps hook to receive props from the tool handler:
import { useMCPAppProps } from '@mcp-web/app';
function Statistics() {
const props = useMCPAppProps<{ completionRate: number; totalTasks: number }>();
if (!props) return <div>Loading...</div>;
return (
<div>
<p>Completion: {Math.round(props.completionRate * 100)}%</p>
<p>Total tasks: {props.totalTasks}</p>
</div>
);
}Vite Plugin Options
defineMCPAppsConfig(
{ plugins: [react()] },
{
appsConfig: 'src/mcp-apps.ts', // Path to apps config (auto-detected by default)
outDir: 'public/mcp-web-apps', // Output directory (default)
silenceOverrideWarnings: false, // Suppress build setting override warnings
}
);Exports
| Export | Description |
|--------|-------------|
| createApp | Define an app with a handler and component |
| useMCPAppProps | React hook to receive props from the tool handler |
| useMCPApp | Access the ext-apps App instance |
| useMCPHostTheme | Get the current host theme ("light" or "dark") |
| useMCPHostContext | Get the full host context |
| renderMCPApp | Manually render a component (auto-generated by Vite plugin) |
| MCPAppProvider | Context provider (set up automatically by renderMCPApp) |
| defineMCPAppsConfig | Create a Vite config for building MCP Apps (via @mcp-web/app/vite) |
Learn More
For full documentation, guides, and examples, visit mcp-web.dev.
