Register React renderers for assistant-ui tool calls, tool results, and model data parts.
API Reference
DataRenderers
- length0
- toString() => string
- toLocaleString{ (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string; }
- pop() => undefined
- push(...items: never[]) => number
- concat{ (...items: ConcatArray<never>[]): never[]; (...items: ConcatArray<never>[]): never[]; }
- join(separator?: string) => string
- reverse() => never[]
- shift() => undefined
- slice(start?: number, end?: number) => never[]
- sort(compareFn?: ((a: never, b: never) => number) | undefined) => []
- splice{ (start: number, deleteCount?: number): never[]; (start: number, deleteCount: number, ...items: never[]): never[]; }
- unshift(...items: never[]) => number
- indexOf(searchElement: never, fromIndex?: number) => number
- lastIndexOf(searchElement: never, fromIndex?: number) => number
- every{ <S>(predicate: (value: never, index: number, array: never[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: never, index: number, array: never[]) => unknown, thisArg?: any): boolean; }
- some(predicate: (value: never, index: number, array: never[]) => unknown, thisArg?: any) => boolean
- forEach(callbackfn: (value: never, index: number, array: never[]) => void, thisArg?: any) => void
- map<U>(callbackfn: (value: never, index: number, array: never[]) => U, thisArg?: any) => U[]
- filter{ <S>(predicate: (value: never, index: number, array: never[]) => value is S, thisArg?: any): S[]; (predicate: (value: never, index: number, array: never[]) => unknown, thisArg?: any): never[]; }
- reduce{ (callbackfn: (previousValue: never, currentValue: never, currentIndex: number, array: never[]) => never): never; (callbackfn: (previousValue: never, currentValue: never, currentIndex: number, array: never[]) => never, initialValue: never): never; <U>(callbackfn: (previousValue: U, currentValue: never, currentIndex: number, array: never[]) => U, initialValue: U): U; }
- reduceRight{ (callbackfn: (previousValue: never, currentValue: never, currentIndex: number, array: never[]) => never): never; (callbackfn: (previousValue: never, currentValue: never, currentIndex: number, array: never[]) => never, initialValue: never): never; <U>(callbackfn: (previousValue: U, currentValue: never, currentIndex: number, array: never[]) => U, initialValue: U): U; }
- find{ <S>(predicate: (value: never, index: number, obj: never[]) => value is S, thisArg?: any): S | undefined; (predicate: (value: never, index: number, obj: never[]) => unknown, thisArg?: any): undefined; }
- findIndex(predicate: (value: never, index: number, obj: never[]) => unknown, thisArg?: any) => number
- fill(value: never, start?: number, end?: number) => []
- copyWithin(target: number, start: number, end?: number) => []
- entries() => ArrayIterator<[number, never]>
- keys() => ArrayIterator<number>
- values() => ArrayIterator<never>
- includes(searchElement: never, fromIndex?: number) => boolean
- flatMap<U, This>(callback: (this: This, value: never, index: number, array: never[]) => U | readonly U[], thisArg?: This | undefined) => U[]
- flat<A, D>(this: A, depth?: D | undefined) => FlatArray<A, D>[]
- at(index: number) => undefined
- findLast{ <S>(predicate: (value: never, index: number, array: never[]) => value is S, thisArg?: any): S | undefined; (predicate: (value: never, index: number, array: never[]) => unknown, thisArg?: any): undefined; }
- findLastIndex(predicate: (value: never, index: number, array: never[]) => unknown, thisArg?: any) => number
- toReversed() => never[]
- toSorted(compareFn?: ((a: never, b: never) => number) | undefined) => never[]
- toSpliced{ (start: number, deleteCount: number, ...items: never[]): never[]; (start: number, deleteCount?: number): never[]; }
- with(index: number, value: never) => never[]
getMcpAppFromToolPart
Returns MCP app metadata for a tool-call part that points at a ui://
resource.
Returns undefined when the part has no MCP app metadata or the metadata
does not reference an assistant-ui MCP app resource.
- partToolPartLike
- ToolPartLike
- mcp?ToolCallMessagePartMcpMetadata
MCP app metadata associated with this tool call, when present.
ToolCallMessagePartMcpMetadata- app?McpAppMetadata
- McpAppMetadata
- resourceUristring
- mimeType?string
- visibility?readonly ("model" | "app")[]
- serverId?string
Routable server identity emitted by the agent stack when multiple MCP servers back one agent; for
makeAssistantDataUI
Creates a React component that registers a named data-part renderer when rendered.
type AssistantDataUIProps = {
/** Data part name this renderer handles. */
name: string;
/** Component rendered for matching data message parts. */
render: DataMessagePartComponent<T>;
};
const makeAssistantDataUI: <T = any>(dataUI: AssistantDataUIProps<T>) => AssistantDataUI;McpAppRenderer
- 0McpAppRendererOptions
- McpAppRendererOptions
- sandbox?McpAppSandboxConfig
Sandbox + container styling. Passes through to SafeContentFrame.
SandboxHostConfig- sandbox?SandboxOption[]
- useShadowDom?boolean
- enableBrowserCaching?boolean
- salt?string
- product?string
- className?string
- style?CSSProperties
- unsafeDocumentWrite?boolean
- maxHeight?number
Upper bound (in pixels) applied to the widget-driven auto-resize height. Defaults to 800.
- hostInfo?McpAppHostInfo
Identifies the host to the widget in the `ui/initialize` response.
McpAppHostInfo- namestring
- versionstring
- hostContext?McpAppHostContext
Delivered to the widget on initialize and pushed via `notifications/host_context/changed` on change.
McpAppHostContext- theme?"light" | "dark"
- displayMode?McpAppDisplayMode
- availableDisplayModes?McpAppDisplayMode[]
- handlers?Omit< McpAppBridgeHandlers, "callTool" | "readResource" | "listResources" >
Optional widget interaction and lifecycle handlers. Data-plane handlers (`callTool`, `readResource`, `listResources`) always use `host`. Which handlers a widget may call is captured when its frame mounts, so a `forPart` resolver returns the same handler keys for a part on every render even when the implementations change.
Omit- onError?(error: Error) => void
- allowedTools?readonly string[]
- openLink?(params: { url: string }) => Promise<unknown> | unknown
- sendMessage?(params: unknown) => Promise<unknown> | unknown
- updateModelContext?(params: unknown) => Promise<unknown> | unknown
- requestDisplayMode?(params: { mode: McpAppDisplayMode; }) => Promise<{ mode: McpAppDisplayMode }> | { mode: McpAppDisplayMode }
- onSizeChange?(params: { width?: number; height?: number }) => void
- onInitialized?() => void
- onRequestTeardown?(params: unknown) => void
- onLog?(params: unknown) => void
- fallback?ReactNode
Rendered when no MCP app is on the part, or while load is in flight / failed (unless overridden).
- loadingFallback?ReactNode
Rendered while the resource is loading. Defaults to `fallback`.
- errorFallback?ReactNode | ((error: Error) => ReactNode)
Rendered when the resource load rejects. Defaults to `fallback`.
- hostResourceElement<McpAppsHost>
Provides the data-plane operations the widget can request (`loadResource`, `callTool`, `readResource`, `listResources`). Use `McpAppsRemoteHost({ url })` for the default HTTP-route convention.
ResourceElement- hook(...args: any[]) => V
- argsreadonly unknown[]
- key?string | number
- deps?readonly unknown[]
- forPart?(part: ToolCallMessagePart) => McpAppPartOptions
Resolves the options for one part. Each returned value replaces the thread-wide option of the same name, so a host can give every MCP app its own display mode and answer `requestDisplayMode` for the part that asked. `handlers` is the exception and merges per key. Its keys are capabilities negotiated with the widget rather than data, so replacing the whole bag to add one handler would withdraw the others from that part's widget with nothing to observe it by.
- length1
- toString() => string
- toLocaleString{ (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string; }
- pop() => McpAppRendererOptions
- push(...items: McpAppRendererOptions[]) => number
- concat{ (...items: ConcatArray<McpAppRendererOptions>[]): McpAppRendererOptions[]; (...items: (McpAppRendererOptions | ConcatArray<McpAppRendererOptions>)[]): McpAppRendererOptions[]; }
- join(separator?: string) => string
- reverse() => McpAppRendererOptions[]
- shift() => McpAppRendererOptions
- slice(start?: number, end?: number) => McpAppRendererOptions[]
- sort(compareFn?: ((a: McpAppRendererOptions, b: McpAppRendererOptions) => number) | undefined) => [options: McpAppRendererOptions]
- splice{ (start: number, deleteCount?: number): McpAppRendererOptions[]; (start: number, deleteCount: number, ...items: McpAppRendererOptions[]): McpAppRendererOptions[]; }
- unshift(...items: McpAppRendererOptions[]) => number
- indexOf(searchElement: McpAppRendererOptions, fromIndex?: number) => number
- lastIndexOf(searchElement: McpAppRendererOptions, fromIndex?: number) => number
- every{ <S>(predicate: (value: McpAppRendererOptions, index: number, array: McpAppRendererOptions[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: McpAppRendererOptions, index: number, array: McpAppRendererOptions[]) => unknown, thisArg?: any): boolean; }
- some(predicate: (value: McpAppRendererOptions, index: number, array: McpAppRendererOptions[]) => unknown, thisArg?: any) => boolean
- forEach(callbackfn: (value: McpAppRendererOptions, index: number, array: McpAppRendererOptions[]) => void, thisArg?: any) => void
- map<U>(callbackfn: (value: McpAppRendererOptions, index: number, array: McpAppRendererOptions[]) => U, thisArg?: any) => U[]
- filter{ <S>(predicate: (value: McpAppRendererOptions, index: number, array: McpAppRendererOptions[]) => value is S, thisArg?: any): S[]; (predicate: (value: McpAppRendererOptions, index: number, array: McpAppRendererOptions[]) => unknown, thisArg?: any): McpAppRendererOptions[]; }
- reduce{ (callbackfn: (previousValue: McpAppRendererOptions, currentValue: McpAppRendererOptions, currentIndex: number, array: McpAppRendererOptions[]) => McpAppRendererOptions): McpAppRendererOptions; (callbackfn: (previousValue: McpAppRendererOptions, currentValue: McpAppRendererOptions, currentIndex: number, array: McpAppRendererOptions[]) => McpAppRendererOptions, initialValue: McpAppRendererOptions): McpAppRendererOptions; <U>(callbackfn: (previousValue: U, currentValue: McpAppRendererOptions, currentIndex: number, array: McpAppRendererOptions[]) => U, initialValue: U): U; }
- reduceRight{ (callbackfn: (previousValue: McpAppRendererOptions, currentValue: McpAppRendererOptions, currentIndex: number, array: McpAppRendererOptions[]) => McpAppRendererOptions): McpAppRendererOptions; (callbackfn: (previousValue: McpAppRendererOptions, currentValue: McpAppRendererOptions, currentIndex: number, array: McpAppRendererOptions[]) => McpAppRendererOptions, initialValue: McpAppRendererOptions): McpAppRendererOptions; <U>(callbackfn: (previousValue: U, currentValue: McpAppRendererOptions, currentIndex: number, array: McpAppRendererOptions[]) => U, initialValue: U): U; }
- find{ <S>(predicate: (value: McpAppRendererOptions, index: number, obj: McpAppRendererOptions[]) => value is S, thisArg?: any): S | undefined; (predicate: (value: McpAppRendererOptions, index: number, obj: McpAppRendererOptions[]) => unknown, thisArg?: any): McpAppRendererOptions | undefined; }
- findIndex(predicate: (value: McpAppRendererOptions, index: number, obj: McpAppRendererOptions[]) => unknown, thisArg?: any) => number
- fill(value: McpAppRendererOptions, start?: number, end?: number) => [options: McpAppRendererOptions]
- copyWithin(target: number, start: number, end?: number) => [options: McpAppRendererOptions]
- entries() => ArrayIterator<[number, McpAppRendererOptions]>
- keys() => ArrayIterator<number>
- values() => ArrayIterator<McpAppRendererOptions>
- includes(searchElement: McpAppRendererOptions, fromIndex?: number) => boolean
- flatMap<U, This>(callback: (this: This, value: McpAppRendererOptions, index: number, array: McpAppRendererOptions[]) => U | readonly U[], thisArg?: This | undefined) => U[]
- flat<A, D>(this: A, depth?: D | undefined) => FlatArray<A, D>[]
- at(index: number) => McpAppRendererOptions
- findLast{ <S>(predicate: (value: McpAppRendererOptions, index: number, array: McpAppRendererOptions[]) => value is S, thisArg?: any): S | undefined; (predicate: (value: McpAppRendererOptions, index: number, array: McpAppRendererOptions[]) => unknown, thisArg?: any): McpAppRendererOptions | undefined; }
- findLastIndex(predicate: (value: McpAppRendererOptions, index: number, array: McpAppRendererOptions[]) => unknown, thisArg?: any) => number
- toReversed() => McpAppRendererOptions[]
- toSorted(compareFn?: ((a: McpAppRendererOptions, b: McpAppRendererOptions) => number) | undefined) => McpAppRendererOptions[]
- toSpliced{ (start: number, deleteCount: number, ...items: McpAppRendererOptions[]): McpAppRendererOptions[]; (start: number, deleteCount?: number): McpAppRendererOptions[]; }
- with(index: number, value: McpAppRendererOptions) => McpAppRendererOptions[]
McpAppsRemoteHost
- 0McpAppsRemoteHostOptions
- McpAppsRemoteHostOptions
- urlstring
- fetch?typeof fetch
- headers?Record<string, string> | (() => Record<string, string> | Promise<Record<string, string>>)
- length1
- toString() => string
- toLocaleString{ (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string; }
- pop() => McpAppsRemoteHostOptions
- push(...items: McpAppsRemoteHostOptions[]) => number
- concat{ (...items: ConcatArray<McpAppsRemoteHostOptions>[]): McpAppsRemoteHostOptions[]; (...items: (McpAppsRemoteHostOptions | ConcatArray<McpAppsRemoteHostOptions>)[]): McpAppsRemoteHostOptions[]; }
- join(separator?: string) => string
- reverse() => McpAppsRemoteHostOptions[]
- shift() => McpAppsRemoteHostOptions
- slice(start?: number, end?: number) => McpAppsRemoteHostOptions[]
- sort(compareFn?: ((a: McpAppsRemoteHostOptions, b: McpAppsRemoteHostOptions) => number) | undefined) => [options: McpAppsRemoteHostOptions]
- splice{ (start: number, deleteCount?: number): McpAppsRemoteHostOptions[]; (start: number, deleteCount: number, ...items: McpAppsRemoteHostOptions[]): McpAppsRemoteHostOptions[]; }
- unshift(...items: McpAppsRemoteHostOptions[]) => number
- indexOf(searchElement: McpAppsRemoteHostOptions, fromIndex?: number) => number
- lastIndexOf(searchElement: McpAppsRemoteHostOptions, fromIndex?: number) => number
- every{ <S>(predicate: (value: McpAppsRemoteHostOptions, index: number, array: McpAppsRemoteHostOptions[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: McpAppsRemoteHostOptions, index: number, array: McpAppsRemoteHostOptions[]) => unknown, thisArg?: any): boolean; }
- some(predicate: (value: McpAppsRemoteHostOptions, index: number, array: McpAppsRemoteHostOptions[]) => unknown, thisArg?: any) => boolean
- forEach(callbackfn: (value: McpAppsRemoteHostOptions, index: number, array: McpAppsRemoteHostOptions[]) => void, thisArg?: any) => void
- map<U>(callbackfn: (value: McpAppsRemoteHostOptions, index: number, array: McpAppsRemoteHostOptions[]) => U, thisArg?: any) => U[]
- filter{ <S>(predicate: (value: McpAppsRemoteHostOptions, index: number, array: McpAppsRemoteHostOptions[]) => value is S, thisArg?: any): S[]; (predicate: (value: McpAppsRemoteHostOptions, index: number, array: McpAppsRemoteHostOptions[]) => unknown, thisArg?: any): McpAppsRemoteHostOptions[]; }
- reduce{ (callbackfn: (previousValue: McpAppsRemoteHostOptions, currentValue: McpAppsRemoteHostOptions, currentIndex: number, array: McpAppsRemoteHostOptions[]) => McpAppsRemoteHostOptions): McpAppsRemoteHostOptions; (callbackfn: (previousValue: McpAppsRemoteHostOptions, currentValue: McpAppsRemoteHostOptions, currentIndex: number, array: McpAppsRemoteHostOptions[]) => McpAppsRemoteHostOptions, initialValue: McpAppsRemoteHostOptions): McpAppsRemoteHostOptions; <U>(callbackfn: (previousValue: U, currentValue: McpAppsRemoteHostOptions, currentIndex: number, array: McpAppsRemoteHostOptions[]) => U, initialValue: U): U; }
- reduceRight{ (callbackfn: (previousValue: McpAppsRemoteHostOptions, currentValue: McpAppsRemoteHostOptions, currentIndex: number, array: McpAppsRemoteHostOptions[]) => McpAppsRemoteHostOptions): McpAppsRemoteHostOptions; (callbackfn: (previousValue: McpAppsRemoteHostOptions, currentValue: McpAppsRemoteHostOptions, currentIndex: number, array: McpAppsRemoteHostOptions[]) => McpAppsRemoteHostOptions, initialValue: McpAppsRemoteHostOptions): McpAppsRemoteHostOptions; <U>(callbackfn: (previousValue: U, currentValue: McpAppsRemoteHostOptions, currentIndex: number, array: McpAppsRemoteHostOptions[]) => U, initialValue: U): U; }
- find{ <S>(predicate: (value: McpAppsRemoteHostOptions, index: number, obj: McpAppsRemoteHostOptions[]) => value is S, thisArg?: any): S | undefined; (predicate: (value: McpAppsRemoteHostOptions, index: number, obj: McpAppsRemoteHostOptions[]) => unknown, thisArg?: any): McpAppsRemoteHostOptions | undefined; }
- findIndex(predicate: (value: McpAppsRemoteHostOptions, index: number, obj: McpAppsRemoteHostOptions[]) => unknown, thisArg?: any) => number
- fill(value: McpAppsRemoteHostOptions, start?: number, end?: number) => [options: McpAppsRemoteHostOptions]
- copyWithin(target: number, start: number, end?: number) => [options: McpAppsRemoteHostOptions]
- entries() => ArrayIterator<[number, McpAppsRemoteHostOptions]>
- keys() => ArrayIterator<number>
- values() => ArrayIterator<McpAppsRemoteHostOptions>
- includes(searchElement: McpAppsRemoteHostOptions, fromIndex?: number) => boolean
- flatMap<U, This>(callback: (this: This, value: McpAppsRemoteHostOptions, index: number, array: McpAppsRemoteHostOptions[]) => U | readonly U[], thisArg?: This | undefined) => U[]
- flat<A, D>(this: A, depth?: D | undefined) => FlatArray<A, D>[]
- at(index: number) => McpAppsRemoteHostOptions
- findLast{ <S>(predicate: (value: McpAppsRemoteHostOptions, index: number, array: McpAppsRemoteHostOptions[]) => value is S, thisArg?: any): S | undefined; (predicate: (value: McpAppsRemoteHostOptions, index: number, array: McpAppsRemoteHostOptions[]) => unknown, thisArg?: any): McpAppsRemoteHostOptions | undefined; }
- findLastIndex(predicate: (value: McpAppsRemoteHostOptions, index: number, array: McpAppsRemoteHostOptions[]) => unknown, thisArg?: any) => number
- toReversed() => McpAppsRemoteHostOptions[]
- toSorted(compareFn?: ((a: McpAppsRemoteHostOptions, b: McpAppsRemoteHostOptions) => number) | undefined) => McpAppsRemoteHostOptions[]
- toSpliced{ (start: number, deleteCount: number, ...items: McpAppsRemoteHostOptions[]): McpAppsRemoteHostOptions[]; (start: number, deleteCount?: number): McpAppsRemoteHostOptions[]; }
- with(index: number, value: McpAppsRemoteHostOptions) => McpAppsRemoteHostOptions[]
useAssistantDataUI
Registers a renderer for named data message parts while the component is
mounted.
- dataUIAssistantDataUIProps<any> | null
- AssistantDataUIProps<any> | null
- namestring
Data part name this renderer handles.
- renderDataMessagePartComponent<T>
Component rendered for matching data message parts.
toolApprovalAcceptsText
Whether the request asks for a free-form answer, on its own or alongside its
options. Renderers read this to decide whether to offer a text affordance,
and the runtime reads it to reject a text response the host cannot record.
const toolApprovalAcceptsText: (approval: { readonly display?: ToolApprovalDisplay; readonly allowFreeform?: boolean; }) => boolean;makeAssistantToolUI
Warning
Deprecated. Put render/renderText on the matching toolkit entry, or use
MessagePrimitive.Parts inline tool render overrides for per-message UI.
See https://assistant-ui.com/docs/migrations/toolkit-tools.
Creates a React component that registers a tool-call renderer when rendered.
Use this to package reusable display components for tools whose definitions are registered elsewhere.
type AssistantToolUIProps = {
/** Name of the tool whose calls should use this renderer. */
toolName: string;
/** Component rendered for matching tool-call message parts. */
render: ToolCallMessagePartComponent<TArgs, TResult>;
/**
* How the UI is presented relative to the chain-of-thought trace. Set
* `"standalone"` to surface it on its own (e.g. human-in-the-loop or
* generative UI for a backend/MCP tool). Defaults to `"inline"`.
*/
display?: "standalone" | "inline";
};
const makeAssistantToolUI: <TArgs, TResult>(tool: AssistantToolUIProps<TArgs, TResult>) => AssistantToolUI;useAssistantToolUI
Warning
Deprecated. Put render/renderText on the matching toolkit entry, or use
MessagePrimitive.Parts inline tool render overrides for per-message UI.
See https://assistant-ui.com/docs/migrations/toolkit-tools.
Registers a tool-call renderer while the component is mounted.
This only affects rendering. Pair it with Tools or a backend tool registry to expose the actual tool definition to the model.
- toolAssistantToolUIProps<any, any> | null
- AssistantToolUIProps<any, any> | null
- toolNamestring
Name of the tool whose calls should use this renderer.
- renderToolCallMessagePartComponent<TArgs, TResult>
Component rendered for matching tool-call message parts.
- display?"standalone" | "inline"
How the UI is presented relative to the chain-of-thought trace. Set `"standalone"` to surface it on its own (e.g. human-in-the-loop or generative UI for a backend/MCP tool). Defaults to `"inline"`.