This is the assistant-ui MCP starter project. It connects the chat to a Model Context Protocol server for tools and renders MCP Apps (sandboxed UI widgets attached to tool calls) inline.
Getting Started#
Add your OpenAI API key to .env.local:
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Point the MCP client at your server in app/api/mcp-client.ts (default: http://localhost:8000/mcp).
Run the dev server:
npm run dev
# or
pnpm dev
Open http://localhost:3000.
How it's wired#
app/api/mcp-client.ts— lazy-creates a single@ai-sdk/mcpclient used by both routes below.app/api/chat/route.ts— chat route. Pulls tools from the MCP server (client.tools()) and forwards them to the model.app/api/mcp-apps/route.ts— the MCP Apps host route. The renderer POSTs{ method, params }here formcp-apps/read-resource,tools/call,resources/read, andresources/list.app/assistant.tsx— composesMcpAppRenderer({ host: McpAppsRemoteHost({ url: "/api/mcp-apps" }) })into theToolsresource so any tool call whose part carriesmcp.appmetadata renders its widget inline.
When the MCP server attaches a _meta.ui.resourceUri (text/html;profile=mcp-app) to a tool, AI SDK forwards it through callProviderMetadata.mcp.app; @assistant-ui/react-ai-sdk lifts it onto ToolCallMessagePart.mcp.app; the renderer picks it up and mounts the widget in a sandboxed iframe with a JSON-RPC bridge. See the MCP Apps guide for the full protocol.