experimental_MCPAppRenderer
experimental_MCPAppRenderer is experimental and may change in a future
release.
experimental_MCPAppRenderer renders an MCP App for an AI SDK tool UI part. It detects MCP App metadata on the tool part, loads the app resource, renders the app in a sandbox proxy iframe, and bridges MCP Apps JSON-RPC messages between the iframe and your host application.
For tool parts without MCP App metadata, the component renders the fallback.
Import
import { experimental_MCPAppRenderer as MCPAppRenderer } from "@ai-sdk/react"Example
'use client';
import { experimental_MCPAppRenderer as MCPAppRenderer, type MCPAppBridgeHandlers, type MCPAppMetadata, type MCPAppResource, type MCPAppSandboxConfig,} from '@ai-sdk/react';import { isToolUIPart } from 'ai';
const sandbox = { url: '/mcp-app-sandbox', className: 'h-80 w-full rounded-lg border', style: { border: 0 },} satisfies MCPAppSandboxConfig;
async function loadResource(app: MCPAppMetadata): Promise<MCPAppResource> { const response = await fetch('/api/mcp-app-host/read-resource', { method: 'POST', body: JSON.stringify({ uri: app.resourceUri }), });
if (!response.ok) { throw new Error('Failed to load MCP App resource'); }
return response.json();}
const handlers: MCPAppBridgeHandlers = { callTool: params => fetch('/api/mcp-app-host/call-tool', { method: 'POST', body: JSON.stringify(params), }).then(response => response.json()), openLink: ({ url }) => { window.open(url, '_blank', 'noopener,noreferrer'); return {}; },};
export function MessagePart({ part }: { part: unknown }) { if (!isToolUIPart(part)) { return null; }
return ( <MCPAppRenderer part={part} loadResource={loadResource} handlers={handlers} sandbox={sandbox} fallback={null} /> );}Props
part:
ToolUIPart<UITools> | DynamicToolUIPart
sandbox:
MCPAppSandboxConfig
resource?:
MCPAppResource
loadResource?:
(app: MCPAppMetadata) => Promise<MCPAppResource>
handlers?:
MCPAppBridgeHandlers
hostInfo?:
{ name: string; version: string }
hostContext?:
MCPAppHostContext
fallback?:
ReactNode
Sandbox Config
url:
string | URL
title?:
string
className?:
string
style?:
CSSProperties
targetOrigin?:
string
outerSandbox?:
string
innerSandbox?:
string
Bridge Handlers
experimental_MCPAppRenderer uses these handlers to respond to iframe requests. In production, server-backed handlers should validate authorization and MCP Apps tool visibility before calling the MCP server.
allowedTools?:
string[]
callTool?:
(params: MCPAppToolCallParams) => Promise<unknown> | unknown
readResource?:
(params: { uri: string }) => Promise<unknown> | unknown
listResources?:
(params?: unknown) => Promise<unknown> | unknown
openLink?:
(params: { url: string }) => Promise<unknown> | unknown
sendMessage?:
(params: unknown) => Promise<unknown> | unknown
updateModelContext?:
(params: unknown) => Promise<unknown> | unknown
requestDisplayMode?:
(params: { mode: 'inline' | 'fullscreen' | 'pip' }) => Promise<{ mode: MCPAppDisplayMode }> | { mode: MCPAppDisplayMode }
onSizeChange?:
(params: { width?: number; height?: number }) => void
onInitialized?:
() => void
onRequestTeardown?:
(params: unknown) => void
onLog?:
(params: unknown) => void
onError?:
(error: Error) => void