@assistant-ui/mcp-docs-server 0.1.32 → 0.1.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/.docs/organized/code-examples/waterfall.md +15 -17
  2. package/.docs/organized/code-examples/with-a2a.md +19 -19
  3. package/.docs/organized/code-examples/with-ag-ui.md +25 -20
  4. package/.docs/organized/code-examples/with-ai-sdk-v6.md +6 -4
  5. package/.docs/organized/code-examples/with-artifacts.md +34 -28
  6. package/.docs/organized/code-examples/with-assistant-transport.md +59 -47
  7. package/.docs/organized/code-examples/with-browser-extension.md +17 -5
  8. package/.docs/organized/code-examples/with-chain-of-thought.md +376 -78
  9. package/.docs/organized/code-examples/with-cloud-standalone.md +20 -19
  10. package/.docs/organized/code-examples/with-cloud.md +6 -4
  11. package/.docs/organized/code-examples/with-custom-thread-list.md +9 -7
  12. package/.docs/organized/code-examples/with-elevenlabs-conversational.md +18 -16
  13. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +9 -8
  14. package/.docs/organized/code-examples/with-expo.md +23 -17
  15. package/.docs/organized/code-examples/with-external-store.md +4 -2
  16. package/.docs/organized/code-examples/with-ffmpeg.md +317 -280
  17. package/.docs/organized/code-examples/with-generative-ui.md +1018 -214
  18. package/.docs/organized/code-examples/with-google-adk.md +4 -2
  19. package/.docs/organized/code-examples/with-heat-graph.md +8 -6
  20. package/.docs/organized/code-examples/with-image-generation.md +19 -17
  21. package/.docs/organized/code-examples/with-interactables.md +312 -234
  22. package/.docs/organized/code-examples/with-langchain.md +9 -7
  23. package/.docs/organized/code-examples/with-langgraph.md +82 -78
  24. package/.docs/organized/code-examples/with-livekit.md +19 -17
  25. package/.docs/organized/code-examples/with-mcp.md +13 -7
  26. package/.docs/organized/code-examples/with-opencode.md +61 -61
  27. package/.docs/organized/code-examples/with-react-hook-form.md +14 -12
  28. package/.docs/organized/code-examples/with-react-ink.md +2 -2
  29. package/.docs/organized/code-examples/with-react-router.md +11 -9
  30. package/.docs/organized/code-examples/with-resumable-stream.md +10 -9
  31. package/.docs/organized/code-examples/with-store.md +14 -12
  32. package/.docs/organized/code-examples/with-tanstack.md +8 -9
  33. package/.docs/organized/code-examples/with-tap-runtime.md +21 -19
  34. package/.docs/raw/docs/(docs)/architecture.mdx +43 -2
  35. package/.docs/raw/docs/(docs)/cli.mdx +1 -2
  36. package/.docs/raw/docs/(docs)/copilots/model-context.mdx +34 -26
  37. package/.docs/raw/docs/(docs)/copilots/motivation.mdx +32 -26
  38. package/.docs/raw/docs/(docs)/installation.mdx +1 -1
  39. package/.docs/raw/docs/(reference)/api-reference/adapters/persistence.mdx +5 -1
  40. package/.docs/raw/docs/(reference)/api-reference/external-store/message-conversion.mdx +14 -14
  41. package/.docs/raw/docs/(reference)/api-reference/external-store/runtime.mdx +11 -1
  42. package/.docs/raw/docs/(reference)/api-reference/generative-ui/index.mdx +18 -0
  43. package/.docs/raw/docs/(reference)/api-reference/generative-ui/rendering.mdx +33 -0
  44. package/.docs/raw/docs/(reference)/api-reference/generative-ui/spec.mdx +45 -0
  45. package/.docs/raw/docs/(reference)/api-reference/hooks/composer-triggers.mdx +41 -41
  46. package/.docs/raw/docs/(reference)/api-reference/hooks/model-context.mdx +19 -1
  47. package/.docs/raw/docs/(reference)/api-reference/hooks/primitives.mdx +122 -122
  48. package/.docs/raw/docs/(reference)/api-reference/integrations/react-ai-sdk.mdx +32 -2
  49. package/.docs/raw/docs/(reference)/api-reference/model-context/context.mdx +6 -0
  50. package/.docs/raw/docs/(reference)/api-reference/overview.mdx +4 -6
  51. package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +30 -0
  52. package/.docs/raw/docs/(reference)/api-reference/tools/component-tools.mdx +20 -3
  53. package/.docs/raw/docs/(reference)/api-reference/tools/index.mdx +8 -8
  54. package/.docs/raw/docs/(reference)/api-reference/tools/rendering.mdx +52 -4
  55. package/.docs/raw/docs/(reference)/api-reference/tools/toolkits.mdx +6 -7
  56. package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +58 -46
  57. package/.docs/raw/docs/cloud/ai-sdk.mdx +0 -2
  58. package/.docs/raw/docs/guides/chain-of-thought.mdx +7 -9
  59. package/.docs/raw/docs/guides/context-api.mdx +2 -1
  60. package/.docs/raw/docs/guides/index.mdx +3 -12
  61. package/.docs/raw/docs/guides/mentions.mdx +4 -4
  62. package/.docs/raw/docs/guides/slash-commands.mdx +1 -1
  63. package/.docs/raw/docs/guides/suggestions.mdx +1 -1
  64. package/.docs/raw/docs/ink/hooks.mdx +98 -85
  65. package/.docs/raw/docs/ink/migration.mdx +1 -1
  66. package/.docs/raw/docs/ink/primitives.mdx +2 -2
  67. package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +1 -1
  68. package/.docs/raw/docs/integrations/index.mdx +2 -2
  69. package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +17 -2
  70. package/.docs/raw/docs/migrations/toolkit-tools.mdx +226 -0
  71. package/.docs/raw/docs/primitives/chain-of-thought.mdx +10 -16
  72. package/.docs/raw/docs/primitives/message.mdx +9 -10
  73. package/.docs/raw/docs/react-native/hooks.mdx +57 -82
  74. package/.docs/raw/docs/react-native/migration.mdx +1 -1
  75. package/.docs/raw/docs/react-native/primitives.mdx +2 -2
  76. package/.docs/raw/docs/runtimes/a2a/client-and-hooks.mdx +3 -0
  77. package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +122 -1
  78. package/.docs/raw/docs/runtimes/concepts/threads.mdx +7 -1
  79. package/.docs/raw/docs/runtimes/custom/local-runtime.mdx +18 -7
  80. package/.docs/raw/docs/runtimes/google-adk/hooks.mdx +108 -38
  81. package/.docs/raw/docs/runtimes/langgraph/generative-ui.mdx +2 -2
  82. package/.docs/raw/docs/runtimes/langgraph/streaming.mdx +1 -1
  83. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +64 -50
  84. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-3.mdx +98 -86
  85. package/.docs/raw/docs/tools/backend.mdx +136 -0
  86. package/.docs/raw/docs/tools/defining-tools.mdx +413 -0
  87. package/.docs/raw/docs/tools/dynamic-tools.mdx +110 -0
  88. package/.docs/raw/docs/tools/generative-ui.mdx +214 -0
  89. package/.docs/raw/docs/tools/index.mdx +76 -0
  90. package/.docs/raw/docs/{guides → tools}/interactables.mdx +1 -1
  91. package/.docs/raw/docs/{integrations/tools → tools}/mcp.mdx +77 -50
  92. package/.docs/raw/docs/{guides → tools}/multi-agent.mdx +17 -19
  93. package/.docs/raw/docs/tools/tool-ui.mdx +967 -0
  94. package/.docs/raw/docs/{integrations/tools/react-mcp.mdx → tools/user-managed-mcp.mdx} +3 -3
  95. package/.docs/raw/docs/ui/directive-text.mdx +3 -3
  96. package/.docs/raw/docs/ui/mcp-config.mdx +4 -4
  97. package/.docs/raw/docs/ui/part-grouping.mdx +84 -50
  98. package/.docs/raw/docs/ui/reasoning.mdx +4 -5
  99. package/.docs/raw/docs/ui/tool-group.mdx +5 -6
  100. package/.docs/raw/docs/utilities/heat-graph.mdx +1 -1
  101. package/dist/index.d.ts.map +1 -1
  102. package/dist/prepare-docs/code-examples.d.ts.map +1 -1
  103. package/dist/prepare-docs/copy-raw.d.ts.map +1 -1
  104. package/dist/utils/paths.d.ts.map +1 -1
  105. package/package.json +3 -3
  106. package/.docs/organized/code-examples/with-parent-id-grouping.md +0 -596
  107. package/.docs/raw/docs/(docs)/copilots/make-assistant-tool-ui.mdx +0 -151
  108. package/.docs/raw/docs/(docs)/copilots/make-assistant-tool.mdx +0 -230
  109. package/.docs/raw/docs/guides/generative-ui.mdx +0 -142
  110. package/.docs/raw/docs/guides/tool-ui.mdx +0 -858
  111. package/.docs/raw/docs/guides/tools.mdx +0 -736
  112. /package/.docs/raw/docs/{guides → tools}/mcp-apps.mdx +0 -0
@@ -0,0 +1,214 @@
1
+ ---
2
+ title: Generative UI (JSON spec)
3
+ description: Render agent-described React UI from a JSON spec with a consumer-provided component allowlist.
4
+ ---
5
+
6
+ `MessagePrimitive.GenerativeUI` is a first-class primitive for rendering UI
7
+ described by the agent at runtime as a JSON spec. Instead of hard-coding a
8
+ component per tool, the agent emits a `generative-ui` message part containing
9
+ a tree of components by name. assistant-ui resolves each name against a
10
+ **consumer-provided allowlist** and renders the result.
11
+
12
+ > The allowlist controls **which** components the agent may render: any name
13
+ > not in it throws a typed `GenerativeUIRenderError` (no implicit fallback). It
14
+ > does not constrain the props passed to those components; see [Security](#security).
15
+
16
+ > **Opt-in feature:** The default shadcn `Thread` does **not** render
17
+ > `generative-ui` parts. You must wire the primitive explicitly — see
18
+ > [Opt-in wiring](#opt-in-wiring).
19
+
20
+ ## Which generative UI pattern?
21
+
22
+ assistant-ui uses "generative UI" in three different places. Pick the one that
23
+ matches your integration:
24
+
25
+ | Pattern | API | Best for | Streaming |
26
+ |---------|-----|----------|-----------|
27
+ | **Generative UI primitive** | `MessagePrimitive.GenerativeUI` + allowlist | Composing dashboards, cards, and layouts from a component vocabulary you ship | Native `generative-ui` parts update progressively when the part spec changes incrementally |
28
+ | **Tool UI** | `Tools({ toolkit })` with `render` | Interactive widgets tied to a known tool (forms, pickers, charts) | Tool **args** stream while the model fills them in |
29
+ | **LangGraph data UI** | `makeAssistantDataUI` + `ui_message` | LangGraph agents emitting UI via the LangGraph stream | UI messages arrive on the LangGraph custom channel |
30
+
31
+ See also: [Tool UI guide](/docs/tools/tool-ui), [LangGraph generative UI](/docs/runtimes/langgraph/generative-ui).
32
+
33
+ ## When not to use the primitive
34
+
35
+ - **User input and two-way interaction** → [Tool UI](/docs/tools/tool-ui) or [Interactables](/docs/tools/interactables)
36
+ - **LangGraph `push_ui_message`** → [LangGraph data UI](/docs/runtimes/langgraph/generative-ui)
37
+ - **Untrusted HTML or third-party widgets** → [MCP Apps](/docs/tools/mcp-apps) (sandboxed frames)
38
+
39
+ ## Quick start
40
+
41
+ ### 1. Define your component allowlist
42
+
43
+ ```tsx title="components/gui.tsx"
44
+ const Card = ({ title, children }) => (
45
+ <div className="rounded-xl border bg-card p-4 shadow-sm">
46
+ <div className="text-base font-semibold">{title}</div>
47
+ <div className="mt-2">{children}</div>
48
+ </div>
49
+ );
50
+
51
+ const Button = ({ label }) => (
52
+ <button className="rounded-md bg-primary px-3 py-1.5 text-primary-foreground">
53
+ {label}
54
+ </button>
55
+ );
56
+
57
+ export const componentsAllowlist = { Card, Button };
58
+ ```
59
+
60
+ ### 2. Wire the primitive into your message renderer
61
+
62
+ See [Opt-in wiring](#opt-in-wiring) for all three integration patterns.
63
+
64
+ ### 3. Have the agent emit UI
65
+
66
+ **ExternalStore / manual messages** attach a native part:
67
+
68
+ ```ts
69
+ {
70
+ type: "generative-ui",
71
+ spec: {
72
+ root: {
73
+ component: "Card",
74
+ props: { title: "Welcome" },
75
+ children: [
76
+ { component: "Button", props: { label: "Get started" } },
77
+ ],
78
+ },
79
+ },
80
+ }
81
+ ```
82
+
83
+ **AI SDK (`useChatRuntime`)** — the adapter maps tool results to `tool-call`
84
+ parts, not `generative-ui` parts. Use the [AI SDK interim bridge](#pattern-3--ai-sdk-interim-bridge) until a native emission helper ships.
85
+
86
+ Live examples in [`examples/with-generative-ui`](https://github.com/assistant-ui/assistant-ui/tree/main/examples/with-generative-ui): Tool UI demo (`/`), static primitive (`/primitive`), GUI chat (`/gui-chat`).
87
+
88
+ ## Opt-in wiring
89
+
90
+ The stock `@assistant-ui/ui` `Thread` switch returns `null` for unknown part
91
+ types — including `generative-ui`. Add one of these patterns in **your**
92
+ assistant message renderer (~15 lines).
93
+
94
+ ### Pattern 1 — `MessagePrimitive.Parts`
95
+
96
+ ```tsx
97
+ <MessagePrimitive.Parts
98
+ components={{
99
+ generativeUI: {
100
+ components: componentsAllowlist,
101
+ Fallback: UnknownComponentFallback,
102
+ },
103
+ }}
104
+ />
105
+ ```
106
+
107
+ ### Pattern 2 — `GroupedParts` case (shadcn Thread fork)
108
+
109
+ ```tsx
110
+ case "generative-ui":
111
+ return (
112
+ <MessagePrimitive.GenerativeUI
113
+ components={componentsAllowlist}
114
+ Fallback={UnknownComponentFallback}
115
+ />
116
+ );
117
+ ```
118
+
119
+ Also exclude `render_gui` from tool-group chrome in `groupBy` if you use the
120
+ AI SDK bridge (return `null` for that tool name).
121
+
122
+ ### Pattern 3 — AI SDK interim bridge
123
+
124
+ When using `useChatRuntime`, map a dedicated tool result to the renderer:
125
+
126
+ ```tsx
127
+ case "tool-call":
128
+ if (part.toolName === "render_gui") {
129
+ const spec = parseRenderGuiResult(part.result);
130
+ if (spec) {
131
+ return (
132
+ <MessagePrimitive.GenerativeUI
133
+ spec={spec}
134
+ components={componentsAllowlist}
135
+ Fallback={UnknownComponentFallback}
136
+ />
137
+ );
138
+ }
139
+ }
140
+ return part.toolUI ?? <ToolFallback {...part} />;
141
+ ```
142
+
143
+ The message store still holds a `tool-call` on this path — not a
144
+ `generative-ui` part. See `examples/with-generative-ui/app/gui-chat` for a
145
+ working reference.
146
+
147
+ Bare strings act as inline text leaves.
148
+
149
+ ## Spec shape
150
+
151
+ ```ts
152
+ type GenerativeUINode =
153
+ | string
154
+ | {
155
+ component: string; // resolved against the allowlist
156
+ props?: Record<string, unknown>;
157
+ children?: GenerativeUINode[];
158
+ key?: string; // optional stable React key
159
+ };
160
+
161
+ type GenerativeUISpec = {
162
+ root: GenerativeUINode | GenerativeUINode[];
163
+ };
164
+ ```
165
+
166
+ The spec is plain JSON — easy for any agent to emit, and easy to validate
167
+ on the server before delivery.
168
+
169
+ ## Streaming
170
+
171
+ When a message contains native `generative-ui` parts whose `spec` updates
172
+ incrementally (for example via ExternalStore), the primitive renders
173
+ progressively as nodes and props arrive.
174
+
175
+ The AI SDK `render_gui` tool path returns the full spec at **tool completion**
176
+ — not incrementally during the tool execute step. For args streaming during
177
+ generation, use [Tool UI](/docs/tools/tool-ui) instead.
178
+
179
+ ## Security
180
+
181
+ The allowlist is the boundary on **which** components render: a spec can only instantiate components you put in the registry, with no `eval` and no dynamic import (names are looked up in the registry and nothing else). An unknown name throws `GenerativeUIRenderError` or invokes your `Fallback`.
182
+
183
+ It does **not** constrain the `props` the agent supplies. Spec props are spread directly onto your allowlisted components, so treat every allowlisted component as receiving untrusted input: never forward agent-supplied props into `dangerouslySetInnerHTML`, validate or reject `href` / `src` values (for example block `javascript:` URLs), and avoid passing spec props anywhere they become executable. The safest allowlisted components accept only primitive, display-oriented props.
184
+
185
+ ## Error handling
186
+
187
+ Unknown component names throw `GenerativeUIRenderError` with a typed
188
+ `componentName` field. Catch it with a React error boundary, or pass a
189
+ `Fallback` component to opt into a soft-fail UX:
190
+
191
+ ```tsx
192
+ <MessagePrimitive.GenerativeUI
193
+ components={componentsAllowlist}
194
+ Fallback={({ component }) => (
195
+ <span className="rounded bg-muted px-1.5 py-0.5 font-mono text-xs">
196
+ unknown component: {component}
197
+ </span>
198
+ )}
199
+ />
200
+ ```
201
+
202
+ ## Composing with other primitives
203
+
204
+ `generative-ui` is a regular `MessagePart` type, so it composes cleanly with
205
+ `MessagePrimitive.Parts`, `MessagePrimitive.PartByIndex`, and
206
+ `MessagePrimitive.GroupedParts`. Render it alongside text, tool calls, and
207
+ reasoning in the same message.
208
+
209
+ ## Why a primitive (not just a tool)
210
+
211
+ Tool-call UI is great when the agent already invoked a known tool. Generative
212
+ UI flips it: the agent _composes_ UI from a vocabulary you ship. Useful for
213
+ dashboards, status panels, and structured layouts — not for collecting user
214
+ input (use Tool UI for that).
@@ -0,0 +1,76 @@
1
+ ---
2
+ title: Tools
3
+ description: Give the model callable capabilities with assistant-ui toolkits — define frontend, backend, human, and provider tools, render tool calls as interactive UI, and connect MCP servers.
4
+ platforms: ["react"]
5
+ ---
6
+
7
+ Tools are how the model takes action: fetch data, call an API, query a database, drive your UI, or run a workflow. In assistant-ui you declare tools in a **toolkit** — a named map where each key is the tool name the model sees and each value describes the tool's schema, where it runs, and how its call renders in the chat.
8
+
9
+ ## Start here
10
+
11
+ <Cards>
12
+ <Card title="Defining Tools" href="/docs/tools/defining-tools">
13
+ Author a toolkit with the `"use generative"` directive — frontend, backend, human, and provider tools, with the schema, executor, and renderer in one file.
14
+ </Card>
15
+ <Card title="Backend Tools" href="/docs/tools/backend">
16
+ Wire a toolkit into your AI SDK route with `generativeTools` / `frontendTools`, mix client and server tools, and round-trip multi-modal results.
17
+ </Card>
18
+ <Card title="Tool UI" href="/docs/tools/tool-ui">
19
+ Render tool calls as custom components — loading and result states, human-in-the-loop, approvals, and streaming.
20
+ </Card>
21
+ <Card title="Dynamic Tools" href="/docs/tools/dynamic-tools">
22
+ Tools whose executor closes over React state, via `stubTool()` + `useAuiToolOverrides`.
23
+ </Card>
24
+ </Cards>
25
+
26
+ ## Two ways to define a toolkit
27
+
28
+ <Callout type="info">
29
+ **`"use generative"` + `defineToolkit`** — for tools you author yourself
30
+ (browser or your own backend). The compiler co-locates the schema, executor,
31
+ and renderer in one file and splits them across the client/server boundary.
32
+
33
+ **Plain `satisfies Toolkit`** — for tools that already execute elsewhere (an
34
+ MCP server, a separate backend route, a LangGraph node) where you only attach a
35
+ renderer.
36
+ </Callout>
37
+
38
+ In a `"use generative"` file every tool declares an `execute` and the kind is
39
+ **inferred** from it (you never write `type`). In a plain toolkit you author
40
+ `type` and write render-only `{ type: "backend", render }` entries. See
41
+ [Defining Tools](/docs/tools/defining-tools#two-ways-to-define-a-toolkit).
42
+
43
+ ## Rendering AI output as UI
44
+
45
+ assistant-ui has a few ways to turn model output into React UI. Pick by **who decides what renders**:
46
+
47
+ | You want… | Use | The decider |
48
+ | --- | --- | --- |
49
+ | A custom component for a known tool call (form, picker, chart, status) | [Tool UI](/docs/tools/tool-ui) — `render` on a toolkit entry | the **model**, by calling the tool |
50
+ | Persistent, out-of-thread state the AI can read and write | [Interactables](/docs/tools/interactables) | the **model + the user**, bidirectionally |
51
+ | UI composed from a component vocabulary you ship, described as a JSON spec | [Generative UI (JSON spec)](/docs/tools/generative-ui) — `MessagePrimitive.GenerativeUI` | the **model**, composing a tree |
52
+ | UI pushed by a LangGraph node alongside messages | [LangGraph Generative UI](/docs/runtimes/langgraph/generative-ui) — `makeAssistantDataUI` | the **backend / orchestrator** |
53
+
54
+ ## Connect external tools
55
+
56
+ <Cards>
57
+ <Card title="MCP (server-side)" href="/docs/tools/mcp">
58
+ Wire one or more MCP servers into your API route as a tool catalog.
59
+ </Card>
60
+ <Card title="User-managed MCP" href="/docs/tools/user-managed-mcp">
61
+ Let end users add and authenticate MCP servers from the browser.
62
+ </Card>
63
+ <Card title="MCP Apps" href="/docs/tools/mcp-apps">
64
+ Render MCP UI resources (`ui://`) inline in sandboxed frames.
65
+ </Card>
66
+ <Card title="Multi-Agent" href="/docs/tools/multi-agent">
67
+ Render sub-agent conversations inside a tool call.
68
+ </Card>
69
+ </Cards>
70
+
71
+ ## Reference & components
72
+
73
+ - [Tools API Reference](/docs/api-reference/tools) — `tool`, `Toolkit`, `Tools`, and the tool-status hooks.
74
+ - [`ToolFallback`](/docs/ui/tool-fallback) — a default tool card for tools with no custom UI.
75
+ - [`ToolGroup`](/docs/ui/tool-group) — collapse consecutive tool calls into one container.
76
+ - [Migrating Tools to Toolkits](/docs/migrations/toolkit-tools) — move off the deprecated `makeAssistantTool` / `useAssistantToolUI` APIs.
@@ -399,5 +399,5 @@ See the complete [with-interactables example](https://github.com/assistant-ui/as
399
399
 
400
400
  ## Related
401
401
 
402
- - [Generative UI](/docs/guides/tool-ui) — Inline tool call UIs rendered inside messages
402
+ - [Tool UI](/docs/tools/tool-ui) — Inline tool call UIs rendered inside messages
403
403
  - [LangGraph Generative UI](/docs/runtimes/langgraph/generative-ui) — Structured UI components emitted by a LangGraph graph alongside messages
@@ -13,7 +13,7 @@ client ──► /api/chat ──► MCP client ──► MCP server (HTTP
13
13
  └─ tools() ──► passed to streamText({ tools })
14
14
  ```
15
15
 
16
- The MCP client lives on the server inside your AI SDK route handler. It connects to one or more MCP servers, calls `tools()` to get a tool map, and hands that map to `streamText`. assistant-ui's existing tool-call UI (`ToolFallback`, `makeAssistantToolUI`) renders the results.
16
+ The MCP client lives on the server inside your AI SDK route handler. It connects to one or more MCP servers, calls `tools()` to get a tool map, and hands that map to `streamText`. assistant-ui's existing tool-call UI (`ToolFallback`, or toolkit entries with `render`) renders the results.
17
17
 
18
18
  ## Setup
19
19
 
@@ -141,7 +141,7 @@ If two servers expose tools with the same name, the later spread wins. Rename or
141
141
 
142
142
  ### Render results in the UI
143
143
 
144
- Tool calls flow through the existing assistant-ui tool-call rendering. With no setup, the bundled `<ToolFallback>` component renders the call name, arguments, and result. To customize the appearance for a specific tool, use `makeAssistantToolUI`:
144
+ Tool calls flow through the existing assistant-ui tool-call rendering. With no setup, the bundled `<ToolFallback>` component renders the call name, arguments, and result. To customize the appearance for a specific tool, add a backend entry to your toolkit:
145
145
 
146
146
  <PlatformTabs>
147
147
  <Tab value="React">
@@ -149,86 +149,113 @@ Tool calls flow through the existing assistant-ui tool-call rendering. With no s
149
149
  ```tsx title="app/components/GitHubIssueToolUI.tsx"
150
150
  "use client";
151
151
 
152
- import { makeAssistantToolUI } from "@assistant-ui/react";
152
+ import type { Toolkit } from "@assistant-ui/react";
153
153
 
154
154
  type Args = { repo: string; number: number };
155
155
  type Result = { title: string; state: string; url: string };
156
156
 
157
- export const GitHubIssueToolUI = makeAssistantToolUI<Args, Result>({
158
- toolName: "github_get_issue",
159
- render: ({ args, result }) => (
160
- <div className="rounded border p-3">
161
- <div className="font-mono text-sm">{args.repo}#{args.number}</div>
162
- {result && (
163
- <a href={result.url} className="underline">
164
- {result.title} ({result.state})
165
- </a>
166
- )}
167
- </div>
168
- ),
169
- });
157
+ export const toolkit = {
158
+ github_get_issue: {
159
+ type: "backend",
160
+ render: ({ args, result }: { args: Args; result?: Result }) => (
161
+ <div className="rounded border p-3">
162
+ <div className="font-mono text-sm">{args.repo}#{args.number}</div>
163
+ {result && (
164
+ <a href={result.url} className="underline">
165
+ {result.title} ({result.state})
166
+ </a>
167
+ )}
168
+ </div>
169
+ ),
170
+ },
171
+ } satisfies Toolkit;
170
172
  ```
171
173
 
172
174
  </Tab>
173
175
  <Tab value="React Native">
174
176
 
175
177
  ```tsx title="components/GitHubIssueToolUI.tsx"
176
- import { makeAssistantToolUI } from "@assistant-ui/react-native";
178
+ import type { Toolkit } from "@assistant-ui/react-native";
177
179
  import { Linking, Pressable, Text, View } from "react-native";
178
180
 
179
181
  type Args = { repo: string; number: number };
180
182
  type Result = { title: string; state: string; url: string };
181
183
 
182
- export const GitHubIssueToolUI = makeAssistantToolUI<Args, Result>({
183
- toolName: "github_get_issue",
184
- render: ({ args, result }) => (
185
- <View style={{ borderWidth: 1, borderRadius: 6, padding: 12 }}>
186
- <Text style={{ fontFamily: "Menlo", fontSize: 13 }}>
187
- {args.repo}#{args.number}
188
- </Text>
189
- {result && (
190
- <Pressable onPress={() => Linking.openURL(result.url)}>
191
- <Text style={{ textDecorationLine: "underline" }}>
192
- {result.title} ({result.state})
193
- </Text>
194
- </Pressable>
195
- )}
196
- </View>
197
- ),
198
- });
184
+ export const toolkit = {
185
+ github_get_issue: {
186
+ type: "backend",
187
+ render: ({ args, result }: { args: Args; result?: Result }) => (
188
+ <View style={{ borderWidth: 1, borderRadius: 6, padding: 12 }}>
189
+ <Text style={{ fontFamily: "Menlo", fontSize: 13 }}>
190
+ {args.repo}#{args.number}
191
+ </Text>
192
+ {result && (
193
+ <Pressable onPress={() => Linking.openURL(result.url)}>
194
+ <Text style={{ textDecorationLine: "underline" }}>
195
+ {result.title} ({result.state})
196
+ </Text>
197
+ </Pressable>
198
+ )}
199
+ </View>
200
+ ),
201
+ },
202
+ } satisfies Toolkit;
199
203
  ```
200
204
 
201
205
  </Tab>
202
206
  <Tab value="React Ink">
203
207
 
204
208
  ```tsx title="components/GitHubIssueToolUI.tsx"
205
- import { makeAssistantToolUI } from "@assistant-ui/react-ink";
209
+ import type { Toolkit } from "@assistant-ui/react-ink";
206
210
  import { Box, Text } from "ink";
207
211
 
208
212
  type Args = { repo: string; number: number };
209
213
  type Result = { title: string; state: string; url: string };
210
214
 
211
- export const GitHubIssueToolUI = makeAssistantToolUI<Args, Result>({
212
- toolName: "github_get_issue",
213
- render: ({ args, result }) => (
214
- <Box borderStyle="round" paddingX={1} flexDirection="column">
215
- <Text>
216
- {args.repo}#{args.number}
217
- </Text>
218
- {result && (
215
+ export const toolkit = {
216
+ github_get_issue: {
217
+ type: "backend",
218
+ render: ({ args, result }: { args: Args; result?: Result }) => (
219
+ <Box borderStyle="round" paddingX={1} flexDirection="column">
219
220
  <Text>
220
- {result.title} ({result.state}) — {result.url}
221
+ {args.repo}#{args.number}
221
222
  </Text>
222
- )}
223
- </Box>
224
- ),
225
- });
223
+ {result && (
224
+ <Text>
225
+ {result.title} ({result.state}) — {result.url}
226
+ </Text>
227
+ )}
228
+ </Box>
229
+ ),
230
+ },
231
+ } satisfies Toolkit;
226
232
  ```
227
233
 
228
234
  </Tab>
229
235
  </PlatformTabs>
230
236
 
231
- Mount it once anywhere inside `<AssistantRuntimeProvider>`. The `toolName` must match the name your MCP server publishes.
237
+ Register the toolkit once with `Tools({ toolkit })`. The toolkit key must match the name your MCP server publishes.
238
+
239
+ ```tsx title="app/components/RuntimeProvider.tsx"
240
+ "use client";
241
+
242
+ import { AssistantRuntimeProvider, Tools, useAui } from "@assistant-ui/react";
243
+ import { useChatRuntime } from "@assistant-ui/react-ai-sdk";
244
+ import type { ReactNode } from "react";
245
+
246
+ import { toolkit } from "./GitHubIssueToolUI";
247
+
248
+ export function MyRuntimeProvider({ children }: { children: ReactNode }) {
249
+ const runtime = useChatRuntime({ api: "/api/chat" });
250
+ const aui = useAui({ tools: Tools({ toolkit }) });
251
+
252
+ return (
253
+ <AssistantRuntimeProvider aui={aui} runtime={runtime}>
254
+ {children}
255
+ </AssistantRuntimeProvider>
256
+ );
257
+ }
258
+ ```
232
259
 
233
260
  </Step>
234
261
  <Step>
@@ -262,6 +289,6 @@ Start the app and trigger a tool call (e.g., ask the assistant to do something t
262
289
  <Card
263
290
  title="Tools and tool UI"
264
291
  description="Build custom renderers for tool calls and approvals."
265
- href="/docs/guides/tools"
292
+ href="/docs/tools/defining-tools"
266
293
  />
267
294
  </Cards>
@@ -12,7 +12,7 @@ When a tool call includes a `messages` field (`ToolCallMessagePart.messages`), i
12
12
 
13
13
  Key behaviors:
14
14
 
15
- - **Scope inheritance** — Parent tool UI registrations are available in sub-agent messages. A `makeAssistantToolUI` registered at the top level works inside sub-agent conversations too.
15
+ - **Scope inheritance** — Parent toolkit renderers are available in sub-agent messages. A `Tools({ toolkit })` registration at the top level works inside sub-agent conversations too.
16
16
  - **Recursive** — Sub-agent messages can contain tool calls that themselves have nested messages. Just use `MessagePartPrimitive.Messages` again.
17
17
  - **Read-only** — Sub-agent messages are rendered in a readonly context. No editing, branching, or composing.
18
18
 
@@ -25,13 +25,15 @@ Key behaviors:
25
25
 
26
26
  ```tsx
27
27
  import {
28
- makeAssistantToolUI,
28
+ Tools,
29
+ type Toolkit,
29
30
  MessagePartPrimitive,
30
31
  } from "@assistant-ui/react";
31
32
 
32
- const ResearchAgentToolUI = makeAssistantToolUI({
33
- toolName: "invoke_researcher",
34
- render: ({ args, status }) => (
33
+ const toolkit = {
34
+ invoke_researcher: {
35
+ type: "backend",
36
+ render: ({ args, status }) => (
35
37
  <div className="my-2 rounded-lg border p-4">
36
38
  <div className="mb-2 text-sm font-medium text-gray-500">
37
39
  Researcher Agent {status.type === "running" && "(working...)"}
@@ -44,7 +46,8 @@ const ResearchAgentToolUI = makeAssistantToolUI({
44
46
  </MessagePartPrimitive.Messages>
45
47
  </div>
46
48
  ),
47
- });
49
+ },
50
+ } satisfies Toolkit;
48
51
  ```
49
52
 
50
53
  </Step>
@@ -144,23 +147,17 @@ function App() {
144
147
 
145
148
  ## Subgraph Namespace Events
146
149
 
147
- When using LangGraph, subgraph events carry a `namespace` that identifies which sub-agent emitted them. This lets you attribute messages and state to specific sub-agents without polling or manual coordination.
148
-
149
- - `onSubgraphValues(namespace, values)` fires when a subgraph emits a full state snapshot. Use the `values.messages` array to populate `ToolCallMessagePart.messages` for that sub-agent.
150
- - `onSubgraphUpdates(namespace, updates)` fires for incremental state patches from a subgraph.
151
- - `onSubgraphError(namespace, error)` fires when a subgraph fails. The parent message is not marked incomplete; only top-level errors trigger that.
152
- - `onMessageChunk(chunk, metadata)` includes `metadata.namespace` when the chunk originates from a subgraph. Use this to display per-sub-agent streaming indicators.
153
-
154
- The `namespace` value mirrors the pipe-separated suffix on the LangGraph event name (e.g. `values|tools:call_abc` gives `"tools:call_abc"`).
150
+ When using LangGraph, subgraph events (`onSubgraphValues` / `onSubgraphUpdates` / `onSubgraphError`, plus the `namespace` on `onMessageChunk`) carry a `namespace` that identifies which sub-agent emitted them, letting you attribute messages and state to specific sub-agents. See [LangGraph Streaming](/docs/runtimes/langgraph/streaming) for the full reference.
155
151
 
156
152
  ## Recursive Sub-Agents
157
153
 
158
154
  If a sub-agent's tool calls also have nested messages, the same pattern applies recursively:
159
155
 
160
156
  ```tsx
161
- const OuterAgentToolUI = makeAssistantToolUI({
162
- toolName: "invoke_planner",
163
- render: () => (
157
+ const toolkit = {
158
+ invoke_planner: {
159
+ type: "backend",
160
+ render: () => (
164
161
  <div className="rounded border p-3">
165
162
  <h4>Planner Agent</h4>
166
163
  <MessagePartPrimitive.Messages>
@@ -191,7 +188,8 @@ const OuterAgentToolUI = makeAssistantToolUI({
191
188
  </MessagePartPrimitive.Messages>
192
189
  </div>
193
190
  ),
194
- });
191
+ },
192
+ } satisfies Toolkit;
195
193
  ```
196
194
 
197
195
  ## ReadonlyThreadProvider
@@ -227,7 +225,7 @@ function SubConversation({
227
225
 
228
226
  ## Related
229
227
 
230
- - [Generative UI](/docs/guides/tool-ui) — Creating tool call UIs
228
+ - [Generative UI](/docs/tools/tool-ui) — Creating tool call UIs
231
229
  - [MessagePartPrimitive](/docs/api-reference/primitives/message-part) — API reference for message part primitives
232
230
  - [Sub-Agent Model Tracking](/docs/cloud/ai-sdk#sub-agent-model-tracking) — Track delegated model usage and costs in the Cloud dashboard
233
231
  - [LangGraph Streaming](/docs/runtimes/langgraph/streaming) — Event handlers, subgraph events, and message metadata