@assistant-ui/mcp-docs-server 0.1.29 → 0.1.31

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 (214) hide show
  1. package/.docs/organized/code-examples/waterfall.md +15 -7
  2. package/.docs/organized/code-examples/with-a2a.md +9 -21
  3. package/.docs/organized/code-examples/with-ag-ui.md +11 -8
  4. package/.docs/organized/code-examples/with-ai-sdk-v6.md +10 -10
  5. package/.docs/organized/code-examples/with-artifacts.md +12 -10
  6. package/.docs/organized/code-examples/with-assistant-transport.md +11 -12
  7. package/.docs/organized/code-examples/with-chain-of-thought.md +83 -54
  8. package/.docs/organized/code-examples/with-cloud-standalone.md +14 -11
  9. package/.docs/organized/code-examples/with-cloud.md +9 -10
  10. package/.docs/organized/code-examples/with-custom-thread-list.md +61 -16
  11. package/.docs/organized/code-examples/with-elevenlabs-conversational.md +17 -12
  12. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +13 -13
  13. package/.docs/organized/code-examples/with-expo.md +25 -21
  14. package/.docs/organized/code-examples/with-external-store.md +8 -8
  15. package/.docs/organized/code-examples/with-ffmpeg.md +17 -12
  16. package/.docs/organized/code-examples/with-generative-ui.md +9 -9
  17. package/.docs/organized/code-examples/with-google-adk.md +8 -8
  18. package/.docs/organized/code-examples/with-heat-graph.md +5 -5
  19. package/.docs/organized/code-examples/with-interactables.md +10 -25
  20. package/.docs/organized/code-examples/with-langchain.md +437 -0
  21. package/.docs/organized/code-examples/with-langgraph.md +16 -16
  22. package/.docs/organized/code-examples/with-livekit.md +18 -13
  23. package/.docs/organized/code-examples/with-opencode.md +105 -62
  24. package/.docs/organized/code-examples/with-parent-id-grouping.md +10 -10
  25. package/.docs/organized/code-examples/with-react-hook-form.md +220 -148
  26. package/.docs/organized/code-examples/with-react-ink.md +2 -2
  27. package/.docs/organized/code-examples/with-react-router.md +12 -12
  28. package/.docs/organized/code-examples/with-store.md +8 -5
  29. package/.docs/organized/code-examples/with-tanstack.md +10 -10
  30. package/.docs/organized/code-examples/with-tap-runtime.md +10 -6
  31. package/.docs/raw/docs/(docs)/cli.mdx +2 -1
  32. package/.docs/raw/docs/(docs)/copilots/assistant-frame.mdx +1 -0
  33. package/.docs/raw/docs/(docs)/copilots/make-assistant-tool-ui.mdx +10 -3
  34. package/.docs/raw/docs/(docs)/copilots/make-assistant-tool.mdx +8 -3
  35. package/.docs/raw/docs/(docs)/copilots/make-assistant-visible.mdx +1 -0
  36. package/.docs/raw/docs/(docs)/copilots/model-context.mdx +1 -0
  37. package/.docs/raw/docs/(docs)/copilots/motivation.mdx +1 -0
  38. package/.docs/raw/docs/(docs)/copilots/use-assistant-instructions.mdx +1 -0
  39. package/.docs/raw/docs/(docs)/devtools.mdx +1 -0
  40. package/.docs/raw/docs/(docs)/index.mdx +1 -0
  41. package/.docs/raw/docs/(docs)/installation.mdx +1 -0
  42. package/.docs/raw/docs/(docs)/rtl.mdx +80 -0
  43. package/.docs/raw/docs/(reference)/api-reference/adapters/attachments.mdx +34 -0
  44. package/.docs/raw/docs/(reference)/api-reference/adapters/feedback-speech.mdx +41 -0
  45. package/.docs/raw/docs/(reference)/api-reference/adapters/index.mdx +26 -0
  46. package/.docs/raw/docs/(reference)/api-reference/adapters/persistence.mdx +34 -0
  47. package/.docs/raw/docs/(reference)/api-reference/adapters/runtime.mdx +31 -0
  48. package/.docs/raw/docs/(reference)/api-reference/context-providers/index.mdx +20 -0
  49. package/.docs/raw/docs/(reference)/api-reference/hooks/index.mdx +26 -0
  50. package/.docs/raw/docs/(reference)/api-reference/hooks/model-context.mdx +72 -0
  51. package/.docs/raw/docs/(reference)/api-reference/hooks/runtimes.mdx +41 -0
  52. package/.docs/raw/docs/(reference)/api-reference/hooks/state.mdx +48 -0
  53. package/.docs/raw/docs/(reference)/api-reference/hooks/utilities.mdx +30 -0
  54. package/.docs/raw/docs/(reference)/api-reference/integrations/index.mdx +23 -0
  55. package/.docs/raw/docs/(reference)/api-reference/overview.mdx +21 -0
  56. package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-if.mdx +7 -0
  57. package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +149 -40
  58. package/.docs/raw/docs/(reference)/api-reference/primitives/index.mdx +65 -0
  59. package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +2 -0
  60. package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +50 -6
  61. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list.mdx +15 -0
  62. package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +36 -1
  63. package/.docs/raw/docs/(reference)/api-reference/runtimes/index.mdx +38 -0
  64. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-runtime.mdx +9 -0
  65. package/.docs/raw/docs/(reference)/migrations/v0-14.mdx +144 -6
  66. package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +231 -3
  67. package/.docs/raw/docs/cloud/ai-sdk.mdx +221 -3
  68. package/.docs/raw/docs/cloud/langgraph.mdx +274 -2
  69. package/.docs/raw/docs/{(docs)/guides → guides}/attachments.mdx +41 -36
  70. package/.docs/raw/docs/guides/branching.mdx +76 -0
  71. package/.docs/raw/docs/guides/chain-of-thought.mdx +166 -0
  72. package/.docs/raw/docs/{(docs)/guides → guides}/context-api.mdx +50 -22
  73. package/.docs/raw/docs/{(docs)/guides → guides}/dictation.mdx +2 -0
  74. package/.docs/raw/docs/guides/editing.mdx +102 -0
  75. package/.docs/raw/docs/guides/index.mdx +103 -0
  76. package/.docs/raw/docs/{(docs)/guides → guides}/interactables.mdx +49 -0
  77. package/.docs/raw/docs/{(docs)/guides → guides}/latex.mdx +51 -8
  78. package/.docs/raw/docs/guides/mentions.mdx +520 -0
  79. package/.docs/raw/docs/{(docs)/guides → guides}/message-timing.mdx +8 -2
  80. package/.docs/raw/docs/{(docs)/guides → guides}/multi-agent.mdx +64 -4
  81. package/.docs/raw/docs/{(docs)/guides → guides}/quoting.mdx +10 -17
  82. package/.docs/raw/docs/guides/slash-commands.mdx +361 -0
  83. package/.docs/raw/docs/guides/speech.mdx +156 -0
  84. package/.docs/raw/docs/{(docs)/guides → guides}/suggestions.mdx +21 -83
  85. package/.docs/raw/docs/{(docs)/guides → guides}/tool-ui.mdx +108 -36
  86. package/.docs/raw/docs/{(docs)/guides → guides}/tools.mdx +131 -35
  87. package/.docs/raw/docs/{(docs)/guides → guides}/voice.mdx +39 -0
  88. package/.docs/raw/docs/ink/index.mdx +1 -3
  89. package/.docs/raw/docs/ink/migration.mdx +1 -3
  90. package/.docs/raw/docs/ink/primitives.mdx +37 -1
  91. package/.docs/raw/docs/integrations/attachments/custom-adapter.mdx +520 -0
  92. package/.docs/raw/docs/integrations/auth/better-auth.mdx +191 -0
  93. package/.docs/raw/docs/integrations/auth/clerk.mdx +172 -0
  94. package/.docs/raw/docs/integrations/auth/next-auth.mdx +196 -0
  95. package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +79 -0
  96. package/.docs/raw/docs/integrations/frameworks/mastra/full-stack.mdx +188 -0
  97. package/.docs/raw/docs/integrations/frameworks/mastra/overview.mdx +57 -0
  98. package/.docs/raw/docs/integrations/frameworks/mastra/separate-server.mdx +201 -0
  99. package/.docs/raw/docs/integrations/gateways/index.mdx +157 -0
  100. package/.docs/raw/docs/integrations/index.mdx +173 -0
  101. package/.docs/raw/docs/integrations/observability/helicone.mdx +130 -0
  102. package/.docs/raw/docs/integrations/observability/langfuse.mdx +156 -0
  103. package/.docs/raw/docs/integrations/observability/langsmith.mdx +146 -0
  104. package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +712 -0
  105. package/.docs/raw/docs/integrations/tools/mcp.mdx +267 -0
  106. package/.docs/raw/docs/primitives/action-bar.mdx +1 -0
  107. package/.docs/raw/docs/primitives/assistant-modal.mdx +1 -0
  108. package/.docs/raw/docs/primitives/attachment.mdx +1 -0
  109. package/.docs/raw/docs/primitives/branch-picker.mdx +1 -0
  110. package/.docs/raw/docs/primitives/chain-of-thought.mdx +90 -85
  111. package/.docs/raw/docs/primitives/composer.mdx +96 -63
  112. package/.docs/raw/docs/primitives/error.mdx +1 -0
  113. package/.docs/raw/docs/primitives/index.mdx +2 -1
  114. package/.docs/raw/docs/primitives/message.mdx +68 -5
  115. package/.docs/raw/docs/primitives/selection-toolbar.mdx +1 -0
  116. package/.docs/raw/docs/primitives/suggestion.mdx +1 -0
  117. package/.docs/raw/docs/primitives/thread-list.mdx +39 -0
  118. package/.docs/raw/docs/primitives/thread.mdx +16 -13
  119. package/.docs/raw/docs/react-native/index.mdx +1 -3
  120. package/.docs/raw/docs/react-native/migration.mdx +1 -3
  121. package/.docs/raw/docs/runtimes/a2a/client-and-hooks.mdx +396 -0
  122. package/.docs/raw/docs/runtimes/a2a/overview.mdx +60 -0
  123. package/.docs/raw/docs/runtimes/a2a/quickstart.mdx +216 -0
  124. package/.docs/raw/docs/runtimes/ag-ui/overview.mdx +70 -0
  125. package/.docs/raw/docs/runtimes/ag-ui/quickstart.mdx +243 -0
  126. package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +123 -0
  127. package/.docs/raw/docs/runtimes/ai-sdk/overview.mdx +52 -0
  128. package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +71 -131
  129. package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +69 -63
  130. package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +365 -101
  131. package/.docs/raw/docs/runtimes/concepts/adapters.mdx +265 -0
  132. package/.docs/raw/docs/runtimes/concepts/architecture.mdx +125 -0
  133. package/.docs/raw/docs/runtimes/concepts/stability.mdx +67 -0
  134. package/.docs/raw/docs/runtimes/concepts/threads.mdx +428 -0
  135. package/.docs/raw/docs/runtimes/custom/assistant-transport.mdx +703 -0
  136. package/.docs/raw/docs/runtimes/custom/data-stream.mdx +323 -0
  137. package/.docs/raw/docs/runtimes/custom/external-store.mdx +253 -1236
  138. package/.docs/raw/docs/runtimes/custom/local-runtime.mdx +746 -0
  139. package/.docs/raw/docs/runtimes/custom/overview.mdx +71 -0
  140. package/.docs/raw/docs/runtimes/google-adk/api.mdx +256 -0
  141. package/.docs/raw/docs/runtimes/google-adk/hooks.mdx +717 -0
  142. package/.docs/raw/docs/runtimes/google-adk/overview.mdx +69 -0
  143. package/.docs/raw/docs/runtimes/google-adk/quickstart.mdx +229 -0
  144. package/.docs/raw/docs/runtimes/langchain.mdx +533 -0
  145. package/.docs/raw/docs/runtimes/langgraph/generative-ui.mdx +305 -0
  146. package/.docs/raw/docs/runtimes/langgraph/interrupts.mdx +104 -0
  147. package/.docs/raw/docs/runtimes/langgraph/overview.mdx +84 -0
  148. package/.docs/raw/docs/runtimes/langgraph/quickstart.mdx +496 -0
  149. package/.docs/raw/docs/runtimes/langgraph/streaming.mdx +127 -0
  150. package/.docs/raw/docs/runtimes/langgraph/threads.mdx +113 -0
  151. package/.docs/raw/docs/runtimes/langgraph/tutorial/introduction.mdx +3 -3
  152. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-1.mdx +0 -23
  153. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +1 -1
  154. package/.docs/raw/docs/runtimes/opencode/hooks.mdx +191 -0
  155. package/.docs/raw/docs/runtimes/opencode/overview.mdx +48 -0
  156. package/.docs/raw/docs/runtimes/opencode/quickstart.mdx +119 -0
  157. package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +74 -198
  158. package/.docs/raw/docs/ui/accordion.mdx +1 -0
  159. package/.docs/raw/docs/ui/assistant-modal.mdx +1 -0
  160. package/.docs/raw/docs/ui/assistant-sidebar.mdx +1 -0
  161. package/.docs/raw/docs/ui/attachment.mdx +1 -0
  162. package/.docs/raw/docs/ui/badge.mdx +1 -0
  163. package/.docs/raw/docs/ui/composer-trigger-popover.mdx +200 -0
  164. package/.docs/raw/docs/ui/context-display.mdx +1 -0
  165. package/.docs/raw/docs/ui/diff-viewer.mdx +1 -0
  166. package/.docs/raw/docs/ui/directive-text.mdx +114 -0
  167. package/.docs/raw/docs/ui/file.mdx +1 -0
  168. package/.docs/raw/docs/ui/image.mdx +1 -0
  169. package/.docs/raw/docs/ui/markdown.mdx +2 -14
  170. package/.docs/raw/docs/ui/mermaid.mdx +1 -0
  171. package/.docs/raw/docs/ui/message-timing.mdx +3 -2
  172. package/.docs/raw/docs/ui/model-selector.mdx +1 -0
  173. package/.docs/raw/docs/ui/part-grouping.mdx +325 -313
  174. package/.docs/raw/docs/ui/quote.mdx +1 -0
  175. package/.docs/raw/docs/ui/reasoning.mdx +69 -32
  176. package/.docs/raw/docs/ui/scrollbar.mdx +1 -0
  177. package/.docs/raw/docs/ui/select.mdx +1 -0
  178. package/.docs/raw/docs/ui/sources.mdx +1 -0
  179. package/.docs/raw/docs/ui/streamdown.mdx +1 -0
  180. package/.docs/raw/docs/ui/syntax-highlighting.mdx +1 -0
  181. package/.docs/raw/docs/ui/tabs.mdx +1 -0
  182. package/.docs/raw/docs/ui/thread-list.mdx +17 -0
  183. package/.docs/raw/docs/ui/thread.mdx +56 -1
  184. package/.docs/raw/docs/ui/tool-fallback.mdx +1 -0
  185. package/.docs/raw/docs/ui/tool-group.mdx +39 -11
  186. package/.docs/raw/docs/ui/voice.mdx +1 -0
  187. package/.docs/raw/docs/utilities/heat-graph.mdx +1 -0
  188. package/.docs/raw/docs/utilities/react-o11y.mdx +278 -0
  189. package/.docs/raw/docs/utilities/tw-shimmer.mdx +1 -0
  190. package/dist/utils/logger.js +1 -1
  191. package/dist/utils/logger.js.map +1 -1
  192. package/package.json +4 -4
  193. package/src/tools/tests/path-traversal.test.ts +1 -1
  194. package/src/utils/logger.ts +1 -1
  195. package/.docs/raw/docs/(docs)/guides/branching.mdx +0 -65
  196. package/.docs/raw/docs/(docs)/guides/chain-of-thought.mdx +0 -164
  197. package/.docs/raw/docs/(docs)/guides/editing.mdx +0 -66
  198. package/.docs/raw/docs/(docs)/guides/mentions.mdx +0 -406
  199. package/.docs/raw/docs/(docs)/guides/slash-commands.mdx +0 -275
  200. package/.docs/raw/docs/(docs)/guides/speech.mdx +0 -38
  201. package/.docs/raw/docs/runtimes/a2a/index.mdx +0 -298
  202. package/.docs/raw/docs/runtimes/assistant-transport.mdx +0 -1033
  203. package/.docs/raw/docs/runtimes/custom/custom-thread-list.mdx +0 -268
  204. package/.docs/raw/docs/runtimes/custom/local.mdx +0 -1464
  205. package/.docs/raw/docs/runtimes/data-stream.mdx +0 -422
  206. package/.docs/raw/docs/runtimes/google-adk/index.mdx +0 -686
  207. package/.docs/raw/docs/runtimes/helicone.mdx +0 -61
  208. package/.docs/raw/docs/runtimes/langgraph/index.mdx +0 -607
  209. package/.docs/raw/docs/runtimes/langgraph/tutorial/index.mdx +0 -12
  210. package/.docs/raw/docs/runtimes/langserve.mdx +0 -116
  211. package/.docs/raw/docs/runtimes/mastra/full-stack-integration.mdx +0 -218
  212. package/.docs/raw/docs/runtimes/mastra/overview.mdx +0 -18
  213. package/.docs/raw/docs/runtimes/mastra/separate-server-integration.mdx +0 -217
  214. package/.docs/raw/docs/ui/mention.mdx +0 -168
@@ -0,0 +1,267 @@
1
+ ---
2
+ title: Model Context Protocol (MCP)
3
+ description: Connect MCP servers as a tool catalog in your assistant-ui app.
4
+ ---
5
+
6
+ [MCP](https://modelcontextprotocol.io/) is an open protocol for exposing tools, resources, and prompts to LLMs. One MCP server can publish many tools (file system, GitHub, Slack, your own service) and any MCP-aware client can use them. The AI SDK has a built-in MCP client; this page is the wiring guide for plugging it into an assistant-ui app.
7
+
8
+ ## How it works
9
+
10
+ ```
11
+ client ──► /api/chat ──► MCP client ──► MCP server (HTTP, SSE, stdio)
12
+ │
13
+ └─ tools() ──► passed to streamText({ tools })
14
+ ```
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.
17
+
18
+ ## Setup
19
+
20
+ <Steps>
21
+ <Step>
22
+
23
+ ### Install the MCP client
24
+
25
+ <InstallCommand npm={["@ai-sdk/mcp"]} />
26
+
27
+ For stdio transports (local dev only), also install the official MCP SDK:
28
+
29
+ <InstallCommand npm={["@modelcontextprotocol/sdk"]} />
30
+
31
+ </Step>
32
+ <Step>
33
+
34
+ ### Connect to an MCP server
35
+
36
+ Set the server URL and any auth token your server requires:
37
+
38
+ ```sh title=".env.local"
39
+ MCP_SERVER_URL=https://your-mcp-server.example/mcp
40
+ MCP_TOKEN=...
41
+ ```
42
+
43
+ Then inside your AI SDK route handler, create the client with the transport that matches your server. **HTTP** is the production transport; **SSE** is the legacy streaming transport; **stdio** spawns a local process and is dev-only.
44
+
45
+ ```ts title="app/api/chat/route.ts"
46
+ import { createMCPClient } from "@ai-sdk/mcp";
47
+
48
+ const mcpClient = await createMCPClient({
49
+ transport: {
50
+ type: "http",
51
+ url: process.env.MCP_SERVER_URL!,
52
+ headers: { Authorization: `Bearer ${process.env.MCP_TOKEN}` },
53
+ },
54
+ });
55
+ ```
56
+
57
+ For stdio:
58
+
59
+ ```ts
60
+ import { createMCPClient } from "@ai-sdk/mcp";
61
+ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
62
+
63
+ const mcpClient = await createMCPClient({
64
+ transport: new StdioClientTransport({
65
+ command: "node",
66
+ args: ["./mcp-server/dist/index.js"],
67
+ }),
68
+ });
69
+ ```
70
+
71
+ </Step>
72
+ <Step>
73
+
74
+ ### Wire the tools into the route
75
+
76
+ `mcpClient.tools()` returns an object shaped exactly like the `tools` argument of `streamText`. Spread it in alongside any of your own tools, and close the client when the response finishes:
77
+
78
+ ```ts title="app/api/chat/route.ts"
79
+ import { createMCPClient } from "@ai-sdk/mcp";
80
+ import { openai } from "@ai-sdk/openai";
81
+ import { streamText, convertToModelMessages } from "ai";
82
+ import type { UIMessage } from "ai";
83
+
84
+ export const maxDuration = 60;
85
+
86
+ export async function POST(req: Request) {
87
+ const { messages }: { messages: UIMessage[] } = await req.json();
88
+
89
+ const mcpClient = await createMCPClient({
90
+ transport: {
91
+ type: "http",
92
+ url: process.env.MCP_SERVER_URL!,
93
+ headers: { Authorization: `Bearer ${process.env.MCP_TOKEN}` },
94
+ },
95
+ });
96
+
97
+ const tools = await mcpClient.tools();
98
+
99
+ const result = streamText({
100
+ model: openai("gpt-5.4-mini"),
101
+ messages: await convertToModelMessages(messages),
102
+ tools,
103
+ onFinish: async () => {
104
+ await mcpClient.close();
105
+ },
106
+ });
107
+
108
+ return result.toUIMessageStreamResponse();
109
+ }
110
+ ```
111
+
112
+ `onFinish` is the right place to call `close()`: it fires after the stream completes, so the connection stays open as long as the model is still calling tools.
113
+
114
+ </Step>
115
+ <Step>
116
+
117
+ ### Combine multiple MCP servers
118
+
119
+ Each server has its own client. Spread their tool maps together:
120
+
121
+ ```ts
122
+ const githubClient = await createMCPClient({
123
+ transport: { type: "http", url: process.env.GITHUB_MCP_URL! },
124
+ });
125
+ const filesClient = await createMCPClient({
126
+ transport: { type: "http", url: process.env.FILES_MCP_URL! },
127
+ });
128
+
129
+ const tools = {
130
+ ...(await githubClient.tools()),
131
+ ...(await filesClient.tools()),
132
+ };
133
+
134
+ // remember to close both in onFinish
135
+ ```
136
+
137
+ If two servers expose tools with the same name, the later spread wins. Rename or scope as needed.
138
+
139
+ </Step>
140
+ <Step>
141
+
142
+ ### Render results in the UI
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`:
145
+
146
+ <PlatformTabs>
147
+ <Tab value="React">
148
+
149
+ ```tsx title="app/components/GitHubIssueToolUI.tsx"
150
+ "use client";
151
+
152
+ import { makeAssistantToolUI } from "@assistant-ui/react";
153
+
154
+ type Args = { repo: string; number: number };
155
+ type Result = { title: string; state: string; url: string };
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
+ });
170
+ ```
171
+
172
+ </Tab>
173
+ <Tab value="React Native">
174
+
175
+ ```tsx title="components/GitHubIssueToolUI.tsx"
176
+ import { makeAssistantToolUI } from "@assistant-ui/react-native";
177
+ import { Linking, Pressable, Text, View } from "react-native";
178
+
179
+ type Args = { repo: string; number: number };
180
+ type Result = { title: string; state: string; url: string };
181
+
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
+ });
199
+ ```
200
+
201
+ </Tab>
202
+ <Tab value="React Ink">
203
+
204
+ ```tsx title="components/GitHubIssueToolUI.tsx"
205
+ import { makeAssistantToolUI } from "@assistant-ui/react-ink";
206
+ import { Box, Text } from "ink";
207
+
208
+ type Args = { repo: string; number: number };
209
+ type Result = { title: string; state: string; url: string };
210
+
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 && (
219
+ <Text>
220
+ {result.title} ({result.state}) — {result.url}
221
+ </Text>
222
+ )}
223
+ </Box>
224
+ ),
225
+ });
226
+ ```
227
+
228
+ </Tab>
229
+ </PlatformTabs>
230
+
231
+ Mount it once anywhere inside `<AssistantRuntimeProvider>`. The `toolName` must match the name your MCP server publishes.
232
+
233
+ </Step>
234
+ <Step>
235
+
236
+ ### Run and verify
237
+
238
+ Start the app and trigger a tool call (e.g., ask the assistant to do something the MCP server can do). Confirm:
239
+
240
+ - The tool call appears in the chat with the expected arguments.
241
+ - The result renders (either via your custom `ToolUI` or the fallback).
242
+ - No connection leaks: the MCP client closes after each response. If you see open connections accumulating, check `onFinish`.
243
+
244
+ </Step>
245
+ </Steps>
246
+
247
+ ## Notes
248
+
249
+ - **Server-side only.** The MCP client uses Node APIs (sockets, optionally child processes). Never instantiate it in client code.
250
+ - **Per-request lifecycle.** A fresh client per request keeps connection state simple. For high-throughput servers, pool clients yourself with care: the AI SDK's `tools()` call assumes the connection is alive when `streamText` runs.
251
+ - **Sampling.** If your MCP server uses `sampling/createMessage` (lets the server ask the LLM mid-call), assistant-cloud users can instrument it via [`instrumentMcpSampling`](/docs/cloud) for observability. This is independent of the wiring above.
252
+ - **Transport choice.** HTTP for any networked server. SSE only if the server doesn't speak HTTP. stdio is for local development against an MCP server in your monorepo.
253
+
254
+ ## Related
255
+
256
+ <Cards>
257
+ <Card
258
+ title="AI SDK runtime"
259
+ description="The runtime that ferries MCP tool calls to the chat UI."
260
+ href="/docs/runtimes/ai-sdk/v6"
261
+ />
262
+ <Card
263
+ title="Tools and tool UI"
264
+ description="Build custom renderers for tool calls and approvals."
265
+ href="/docs/guides/tools"
266
+ />
267
+ </Cards>
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  title: ActionBar
3
3
  description: Build message action buttons with auto-hide, copy state, and intelligent disabling.
4
+ platforms: ["react"]
4
5
  ---
5
6
 
6
7
  import { ActionBarPrimitiveSample } from "@/components/docs/samples/action-bar-primitive";
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  title: AssistantModal
3
3
  description: A floating chat popover with a fixed-position trigger button that opens a chat panel.
4
+ platforms: ["react"]
4
5
  ---
5
6
 
6
7
  import { AssistantModalSample } from "@/components/docs/samples/assistant-modal";
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  title: Attachment
3
3
  description: File and image attachment rendering for the composer and messages.
4
+ platforms: ["react"]
4
5
  ---
5
6
 
6
7
  import { AttachmentSample } from "@/components/docs/samples/attachment";
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  title: BranchPicker
3
3
  description: Navigate between message branches, which are alternative responses the user can flip through.
4
+ platforms: ["react"]
4
5
  ---
5
6
 
6
7
  import { BranchPickerPrimitiveSample } from "@/components/docs/samples/branch-picker-primitive";
@@ -1,15 +1,19 @@
1
1
  ---
2
2
  title: ChainOfThought
3
3
  description: Collapsible accordion for grouping reasoning steps and tool calls.
4
+ platforms: ["react"]
4
5
  ---
5
6
 
6
7
  import { ChainOfThoughtPrimitiveSample } from "@/components/docs/samples/chain-of-thought-primitive";
7
- import { ChainOfThoughtPrimitive as ChainOfThoughtPrimitiveDocs } from "@/generated/primitiveDocs";
8
+ import {
9
+ ChainOfThoughtPrimitive as ChainOfThoughtPrimitiveDocs,
10
+ MessagePrimitive as MessagePrimitiveDocs,
11
+ } from "@/generated/primitiveDocs";
8
12
 
9
- The ChainOfThought primitive groups consecutive reasoning and tool-call parts into a collapsible accordion. Reasoning models emit reasoning tokens and tool calls before producing a final answer. This primitive lets you collapse those intermediate steps behind a "Thinking" toggle.
13
+ The ChainOfThought primitive is the legacy accordion API for grouped reasoning and tool-call parts. Reasoning models emit reasoning tokens and tool calls before producing a final answer.
10
14
 
11
- <Callout type="info">
12
- Grouped Chain of Thought currently plugs into `MessagePrimitive.Parts` via `components.ChainOfThought`. If you're wiring grouped CoT, use that API.
15
+ <Callout type="warn">
16
+ For new grouped reasoning/tool-call UI, use `MessagePrimitive.GroupedParts`. `ChainOfThoughtPrimitive` and `components.ChainOfThought` remain available for maintaining existing code.
13
17
  </Callout>
14
18
 
15
19
  <Tabs items={["Preview", "Code"]}>
@@ -18,105 +22,106 @@ Grouped Chain of Thought currently plugs into `MessagePrimitive.Parts` via `comp
18
22
  </Tab>
19
23
  <Tab>
20
24
  ```tsx
21
- import {
22
- AuiIf,
23
- ChainOfThoughtPrimitive,
24
- MessagePrimitive,
25
- } from "@assistant-ui/react";
25
+ import { MessagePrimitive } from "@assistant-ui/react";
26
26
 
27
27
  function AssistantMessage() {
28
28
  return (
29
29
  <MessagePrimitive.Root>
30
- <MessagePrimitive.Parts>
31
- {({ part }) => {
32
- if (part.type === "text") return <MyText />;
30
+ <MessagePrimitive.GroupedParts
31
+ groupBy={(part) => {
32
+ if (part.type === "reasoning")
33
+ return ["group-chainOfThought", "group-reasoning"];
34
+ if (part.type === "tool-call")
35
+ return ["group-chainOfThought", "group-tool"];
33
36
  return null;
34
37
  }}
35
- </MessagePrimitive.Parts>
36
- <ChainOfThought />
38
+ >
39
+ {({ part, children }) => {
40
+ switch (part.type) {
41
+ case "group-chainOfThought":
42
+ return <ThinkingAccordion>{children}</ThinkingAccordion>;
43
+ case "group-reasoning":
44
+ return <ReasoningGroup>{children}</ReasoningGroup>;
45
+ case "group-tool":
46
+ return <ToolGroup>{children}</ToolGroup>;
47
+ case "text":
48
+ return <MyText />;
49
+ case "reasoning":
50
+ return <MyReasoning {...part} />;
51
+ case "tool-call":
52
+ return part.toolUI ?? <MyToolFallback {...part} />;
53
+ default:
54
+ return null;
55
+ }
56
+ }}
57
+ </MessagePrimitive.GroupedParts>
37
58
  </MessagePrimitive.Root>
38
59
  );
39
60
  }
40
-
41
- function ChainOfThought() {
42
- return (
43
- <ChainOfThoughtPrimitive.Root className="my-2 rounded-lg border">
44
- <ChainOfThoughtPrimitive.AccordionTrigger className="flex w-full cursor-pointer items-center gap-2 px-4 py-2.5 font-medium text-sm hover:bg-muted/50">
45
- Thinking
46
- </ChainOfThoughtPrimitive.AccordionTrigger>
47
- <AuiIf condition={(s) => !s.chainOfThought.collapsed}>
48
- <ChainOfThoughtPrimitive.Parts
49
- components={{
50
- Reasoning: ({ text }) => (
51
- <p className="whitespace-pre-wrap px-4 py-2 text-muted-foreground text-sm italic">
52
- {text}
53
- </p>
54
- ),
55
- tools: {
56
- Fallback: ({ toolName, status }) => (
57
- <div className="flex items-center gap-2 px-4 py-2 text-sm">
58
- <span className="font-medium">{toolName}</span>
59
- <span className="text-muted-foreground">
60
- {status.type === "running" ? "running..." : "done"}
61
- </span>
62
- </div>
63
- ),
64
- },
65
- }}
66
- />
67
- </AuiIf>
68
- </ChainOfThoughtPrimitive.Root>
69
- );
70
- }
71
61
  ```
72
62
  </Tab>
73
63
  </Tabs>
74
64
 
75
- ## Quick Start
65
+ ## Recommended: GroupedParts
76
66
 
77
- Render your normal message parts with `MessagePrimitive.Parts`, then place a `ChainOfThought` component alongside them inside the same `MessagePrimitive.Root`:
67
+ Group reasoning and tool-call parts directly in your assistant message:
78
68
 
79
69
  ```tsx
80
- import {
81
- ChainOfThoughtPrimitive,
82
- MessagePrimitive,
83
- } from "@assistant-ui/react";
70
+ import { MessagePrimitive } from "@assistant-ui/react";
84
71
 
85
72
  <MessagePrimitive.Root>
86
- <MessagePrimitive.Parts>
87
- {({ part }) => {
88
- if (part.type === "text") return <MyText />;
73
+ <MessagePrimitive.GroupedParts
74
+ groupBy={(part) => {
75
+ if (part.type === "reasoning")
76
+ return ["group-chainOfThought", "group-reasoning"];
77
+ if (part.type === "tool-call")
78
+ return ["group-chainOfThought", "group-tool"];
89
79
  return null;
90
80
  }}
91
- </MessagePrimitive.Parts>
92
- <MyChainOfThought />
81
+ >
82
+ {({ part, children }) => {
83
+ switch (part.type) {
84
+ case "group-chainOfThought":
85
+ return <ThinkingAccordion>{children}</ThinkingAccordion>;
86
+ case "group-reasoning":
87
+ return <ReasoningGroup>{children}</ReasoningGroup>;
88
+ case "group-tool":
89
+ return <ToolGroup>{children}</ToolGroup>;
90
+ case "text":
91
+ return <MyText />;
92
+ case "reasoning":
93
+ return <MyReasoning {...part} />;
94
+ case "tool-call":
95
+ return part.toolUI ?? <MyToolFallback {...part} />;
96
+ default:
97
+ return null;
98
+ }
99
+ }}
100
+ </MessagePrimitive.GroupedParts>
93
101
  </MessagePrimitive.Root>
94
-
95
- function MyChainOfThought() {
96
- return (
97
- <ChainOfThoughtPrimitive.Root>
98
- <ChainOfThoughtPrimitive.AccordionTrigger>
99
- Thinking
100
- </ChainOfThoughtPrimitive.AccordionTrigger>
101
- <ChainOfThoughtPrimitive.Parts />
102
- </ChainOfThoughtPrimitive.Root>
103
- );
104
- }
105
102
  ```
106
103
 
107
- `Root` renders a `<div>`, `AccordionTrigger` renders a `<button>` that toggles the collapsed state, and `Parts` renders the grouped reasoning and tool-call parts.
104
+ ### GroupedParts API Reference
105
+
106
+ <PrimitivesTypeTable type="MessagePrimitiveGroupedPartsProps" parameters={MessagePrimitiveDocs.GroupedParts.props} />
107
+
108
+ ## Legacy: ChainOfThoughtPrimitive
109
+
110
+ ### Quick Start
111
+
112
+ Render your normal message parts with `MessagePrimitive.Parts`, then place a `ChainOfThought` component alongside them inside the same `MessagePrimitive.Root` only when maintaining older code that already uses the ChainOfThought primitive.
108
113
 
109
114
  <Callout type="info">
110
115
  Runtime setup: primitives require runtime context. Wrap your UI in `AssistantRuntimeProvider` with a runtime (for example `useLocalRuntime(...)`). See [Pick a Runtime](/docs/runtimes/pick-a-runtime).
111
116
  </Callout>
112
117
 
113
- ## Core Concepts
118
+ ### Concepts
114
119
 
115
- ### How Grouping Works
120
+ #### How Grouping Works
116
121
 
117
- `ChainOfThoughtPrimitive.Parts` reads the current message's grouped reasoning and tool-call context. In practice, render your normal text/image/data parts with `MessagePrimitive.Parts`, and render `ChainOfThoughtPrimitive` separately where you want the collapsible reasoning block to appear.
122
+ `ChainOfThoughtPrimitive.Parts` reads the current message's grouped reasoning and tool-call context from the legacy `components.ChainOfThought` path. New code should use `MessagePrimitive.GroupedParts` instead.
118
123
 
119
- ### Collapsed State
124
+ #### Collapsed State
120
125
 
121
126
  The accordion starts collapsed by default. `AccordionTrigger` toggles between collapsed and expanded. Use `AuiIf` to conditionally render parts based on the collapsed state:
122
127
 
@@ -135,7 +140,7 @@ import { AuiIf, ChainOfThoughtPrimitive } from "@assistant-ui/react";
135
140
  </ChainOfThoughtPrimitive.Root>
136
141
  ```
137
142
 
138
- ### Chevron Indicators
143
+ #### Chevron Indicators
139
144
 
140
145
  Use `AuiIf` to show directional icons that reflect the current state:
141
146
 
@@ -154,9 +159,9 @@ import { ChevronDownIcon, ChevronRightIcon } from "lucide-react";
154
159
  </ChainOfThoughtPrimitive.AccordionTrigger>
155
160
  ```
156
161
 
157
- ### Parts Components
162
+ #### Parts Components
158
163
 
159
- `ChainOfThoughtPrimitive.Parts` accepts a `components` prop to control how each part type renders:
164
+ `ChainOfThoughtPrimitive.Parts` accepts a deprecated `components` prop to control how each part type renders:
160
165
 
161
166
  ```tsx
162
167
  <ChainOfThoughtPrimitive.Parts
@@ -186,9 +191,9 @@ import { ChevronDownIcon, ChevronRightIcon } from "lucide-react";
186
191
  | `components.tools.Fallback` | `ToolCallMessagePartComponent` | Fallback for tool-call parts |
187
192
  | `components.Layout` | `ComponentType<PropsWithChildren>` | Wrapper around each rendered part |
188
193
 
189
- ## Parts
194
+ ### Parts API Reference
190
195
 
191
- ### Root
196
+ #### Root
192
197
 
193
198
  Container for the chain-of-thought disclosure UI. Renders a `<div>` element unless `asChild` is set.
194
199
 
@@ -198,7 +203,7 @@ Container for the chain-of-thought disclosure UI. Renders a `<div>` element unle
198
203
  </ChainOfThoughtPrimitive.Root>
199
204
  ```
200
205
 
201
- ### AccordionTrigger
206
+ #### AccordionTrigger
202
207
 
203
208
  Trigger that toggles the collapsed state. Renders a `<button>` element unless `asChild` is set.
204
209
 
@@ -208,7 +213,7 @@ Trigger that toggles the collapsed state. Renders a `<button>` element unless `a
208
213
  </ChainOfThoughtPrimitive.AccordionTrigger>
209
214
  ```
210
215
 
211
- ### Parts
216
+ #### Parts
212
217
 
213
218
  Renders reasoning and tool-call parts. This component does not track collapsed state internally, so control visibility with `AuiIf` as shown in the patterns below.
214
219
 
@@ -233,9 +238,9 @@ Renders reasoning and tool-call parts. This component does not track collapsed s
233
238
 
234
239
  <PrimitivesTypeTable type="ChainOfThoughtPrimitivePartsProps" parameters={ChainOfThoughtPrimitiveDocs.Parts.props} />
235
240
 
236
- ## Patterns
241
+ ### Patterns
237
242
 
238
- ### Minimal Accordion
243
+ #### Minimal Accordion
239
244
 
240
245
  ```tsx
241
246
  function ChainOfThought() {
@@ -260,7 +265,7 @@ function ChainOfThought() {
260
265
  }
261
266
  ```
262
267
 
263
- ### With Tool Calls
268
+ #### With Tool Calls
264
269
 
265
270
  ```tsx
266
271
  function ChainOfThought() {
@@ -298,11 +303,11 @@ function ChainOfThought() {
298
303
  }
299
304
  ```
300
305
 
301
- ## Relationship to Components
306
+ ### Relationship to Components
302
307
 
303
- The [Chain of Thought guide](/docs/guides/chain-of-thought) covers end-to-end setup including backend configuration with reasoning models. See the complete [with-chain-of-thought example](https://github.com/assistant-ui/assistant-ui/tree/main/examples/with-chain-of-thought) for a full working implementation.
308
+ The [Chain of Thought guide](/docs/guides/chain-of-thought) covers end-to-end setup with `MessagePrimitive.GroupedParts`, including backend configuration with reasoning models. See the complete [with-chain-of-thought example](https://github.com/assistant-ui/assistant-ui/tree/main/examples/with-chain-of-thought) for a full working implementation.
304
309
 
305
- ## API Reference
310
+ ### API Reference
306
311
 
307
312
  For the complete guide including backend configuration, see [Chain of Thought](/docs/guides/chain-of-thought). For prop details, see the [ChainOfThoughtPrimitive source](https://github.com/assistant-ui/assistant-ui/tree/main/packages/react/src/primitives/chainOfThought).
308
313