@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.
- package/.docs/organized/code-examples/waterfall.md +15 -7
- package/.docs/organized/code-examples/with-a2a.md +9 -21
- package/.docs/organized/code-examples/with-ag-ui.md +11 -8
- package/.docs/organized/code-examples/with-ai-sdk-v6.md +10 -10
- package/.docs/organized/code-examples/with-artifacts.md +12 -10
- package/.docs/organized/code-examples/with-assistant-transport.md +11 -12
- package/.docs/organized/code-examples/with-chain-of-thought.md +83 -54
- package/.docs/organized/code-examples/with-cloud-standalone.md +14 -11
- package/.docs/organized/code-examples/with-cloud.md +9 -10
- package/.docs/organized/code-examples/with-custom-thread-list.md +61 -16
- package/.docs/organized/code-examples/with-elevenlabs-conversational.md +17 -12
- package/.docs/organized/code-examples/with-elevenlabs-scribe.md +13 -13
- package/.docs/organized/code-examples/with-expo.md +25 -21
- package/.docs/organized/code-examples/with-external-store.md +8 -8
- package/.docs/organized/code-examples/with-ffmpeg.md +17 -12
- package/.docs/organized/code-examples/with-generative-ui.md +9 -9
- package/.docs/organized/code-examples/with-google-adk.md +8 -8
- package/.docs/organized/code-examples/with-heat-graph.md +5 -5
- package/.docs/organized/code-examples/with-interactables.md +10 -25
- package/.docs/organized/code-examples/with-langchain.md +437 -0
- package/.docs/organized/code-examples/with-langgraph.md +16 -16
- package/.docs/organized/code-examples/with-livekit.md +18 -13
- package/.docs/organized/code-examples/with-opencode.md +105 -62
- package/.docs/organized/code-examples/with-parent-id-grouping.md +10 -10
- package/.docs/organized/code-examples/with-react-hook-form.md +220 -148
- package/.docs/organized/code-examples/with-react-ink.md +2 -2
- package/.docs/organized/code-examples/with-react-router.md +12 -12
- package/.docs/organized/code-examples/with-store.md +8 -5
- package/.docs/organized/code-examples/with-tanstack.md +10 -10
- package/.docs/organized/code-examples/with-tap-runtime.md +10 -6
- package/.docs/raw/docs/(docs)/cli.mdx +2 -1
- package/.docs/raw/docs/(docs)/copilots/assistant-frame.mdx +1 -0
- package/.docs/raw/docs/(docs)/copilots/make-assistant-tool-ui.mdx +10 -3
- package/.docs/raw/docs/(docs)/copilots/make-assistant-tool.mdx +8 -3
- package/.docs/raw/docs/(docs)/copilots/make-assistant-visible.mdx +1 -0
- package/.docs/raw/docs/(docs)/copilots/model-context.mdx +1 -0
- package/.docs/raw/docs/(docs)/copilots/motivation.mdx +1 -0
- package/.docs/raw/docs/(docs)/copilots/use-assistant-instructions.mdx +1 -0
- package/.docs/raw/docs/(docs)/devtools.mdx +1 -0
- package/.docs/raw/docs/(docs)/index.mdx +1 -0
- package/.docs/raw/docs/(docs)/installation.mdx +1 -0
- package/.docs/raw/docs/(docs)/rtl.mdx +80 -0
- package/.docs/raw/docs/(reference)/api-reference/adapters/attachments.mdx +34 -0
- package/.docs/raw/docs/(reference)/api-reference/adapters/feedback-speech.mdx +41 -0
- package/.docs/raw/docs/(reference)/api-reference/adapters/index.mdx +26 -0
- package/.docs/raw/docs/(reference)/api-reference/adapters/persistence.mdx +34 -0
- package/.docs/raw/docs/(reference)/api-reference/adapters/runtime.mdx +31 -0
- package/.docs/raw/docs/(reference)/api-reference/context-providers/index.mdx +20 -0
- package/.docs/raw/docs/(reference)/api-reference/hooks/index.mdx +26 -0
- package/.docs/raw/docs/(reference)/api-reference/hooks/model-context.mdx +72 -0
- package/.docs/raw/docs/(reference)/api-reference/hooks/runtimes.mdx +41 -0
- package/.docs/raw/docs/(reference)/api-reference/hooks/state.mdx +48 -0
- package/.docs/raw/docs/(reference)/api-reference/hooks/utilities.mdx +30 -0
- package/.docs/raw/docs/(reference)/api-reference/integrations/index.mdx +23 -0
- package/.docs/raw/docs/(reference)/api-reference/overview.mdx +21 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-if.mdx +7 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +149 -40
- package/.docs/raw/docs/(reference)/api-reference/primitives/index.mdx +65 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +2 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +50 -6
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list.mdx +15 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +36 -1
- package/.docs/raw/docs/(reference)/api-reference/runtimes/index.mdx +38 -0
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-runtime.mdx +9 -0
- package/.docs/raw/docs/(reference)/migrations/v0-14.mdx +144 -6
- package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +231 -3
- package/.docs/raw/docs/cloud/ai-sdk.mdx +221 -3
- package/.docs/raw/docs/cloud/langgraph.mdx +274 -2
- package/.docs/raw/docs/{(docs)/guides → guides}/attachments.mdx +41 -36
- package/.docs/raw/docs/guides/branching.mdx +76 -0
- package/.docs/raw/docs/guides/chain-of-thought.mdx +166 -0
- package/.docs/raw/docs/{(docs)/guides → guides}/context-api.mdx +50 -22
- package/.docs/raw/docs/{(docs)/guides → guides}/dictation.mdx +2 -0
- package/.docs/raw/docs/guides/editing.mdx +102 -0
- package/.docs/raw/docs/guides/index.mdx +103 -0
- package/.docs/raw/docs/{(docs)/guides → guides}/interactables.mdx +49 -0
- package/.docs/raw/docs/{(docs)/guides → guides}/latex.mdx +51 -8
- package/.docs/raw/docs/guides/mentions.mdx +520 -0
- package/.docs/raw/docs/{(docs)/guides → guides}/message-timing.mdx +8 -2
- package/.docs/raw/docs/{(docs)/guides → guides}/multi-agent.mdx +64 -4
- package/.docs/raw/docs/{(docs)/guides → guides}/quoting.mdx +10 -17
- package/.docs/raw/docs/guides/slash-commands.mdx +361 -0
- package/.docs/raw/docs/guides/speech.mdx +156 -0
- package/.docs/raw/docs/{(docs)/guides → guides}/suggestions.mdx +21 -83
- package/.docs/raw/docs/{(docs)/guides → guides}/tool-ui.mdx +108 -36
- package/.docs/raw/docs/{(docs)/guides → guides}/tools.mdx +131 -35
- package/.docs/raw/docs/{(docs)/guides → guides}/voice.mdx +39 -0
- package/.docs/raw/docs/ink/index.mdx +1 -3
- package/.docs/raw/docs/ink/migration.mdx +1 -3
- package/.docs/raw/docs/ink/primitives.mdx +37 -1
- package/.docs/raw/docs/integrations/attachments/custom-adapter.mdx +520 -0
- package/.docs/raw/docs/integrations/auth/better-auth.mdx +191 -0
- package/.docs/raw/docs/integrations/auth/clerk.mdx +172 -0
- package/.docs/raw/docs/integrations/auth/next-auth.mdx +196 -0
- package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +79 -0
- package/.docs/raw/docs/integrations/frameworks/mastra/full-stack.mdx +188 -0
- package/.docs/raw/docs/integrations/frameworks/mastra/overview.mdx +57 -0
- package/.docs/raw/docs/integrations/frameworks/mastra/separate-server.mdx +201 -0
- package/.docs/raw/docs/integrations/gateways/index.mdx +157 -0
- package/.docs/raw/docs/integrations/index.mdx +173 -0
- package/.docs/raw/docs/integrations/observability/helicone.mdx +130 -0
- package/.docs/raw/docs/integrations/observability/langfuse.mdx +156 -0
- package/.docs/raw/docs/integrations/observability/langsmith.mdx +146 -0
- package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +712 -0
- package/.docs/raw/docs/integrations/tools/mcp.mdx +267 -0
- package/.docs/raw/docs/primitives/action-bar.mdx +1 -0
- package/.docs/raw/docs/primitives/assistant-modal.mdx +1 -0
- package/.docs/raw/docs/primitives/attachment.mdx +1 -0
- package/.docs/raw/docs/primitives/branch-picker.mdx +1 -0
- package/.docs/raw/docs/primitives/chain-of-thought.mdx +90 -85
- package/.docs/raw/docs/primitives/composer.mdx +96 -63
- package/.docs/raw/docs/primitives/error.mdx +1 -0
- package/.docs/raw/docs/primitives/index.mdx +2 -1
- package/.docs/raw/docs/primitives/message.mdx +68 -5
- package/.docs/raw/docs/primitives/selection-toolbar.mdx +1 -0
- package/.docs/raw/docs/primitives/suggestion.mdx +1 -0
- package/.docs/raw/docs/primitives/thread-list.mdx +39 -0
- package/.docs/raw/docs/primitives/thread.mdx +16 -13
- package/.docs/raw/docs/react-native/index.mdx +1 -3
- package/.docs/raw/docs/react-native/migration.mdx +1 -3
- package/.docs/raw/docs/runtimes/a2a/client-and-hooks.mdx +396 -0
- package/.docs/raw/docs/runtimes/a2a/overview.mdx +60 -0
- package/.docs/raw/docs/runtimes/a2a/quickstart.mdx +216 -0
- package/.docs/raw/docs/runtimes/ag-ui/overview.mdx +70 -0
- package/.docs/raw/docs/runtimes/ag-ui/quickstart.mdx +243 -0
- package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +123 -0
- package/.docs/raw/docs/runtimes/ai-sdk/overview.mdx +52 -0
- package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +71 -131
- package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +69 -63
- package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +365 -101
- package/.docs/raw/docs/runtimes/concepts/adapters.mdx +265 -0
- package/.docs/raw/docs/runtimes/concepts/architecture.mdx +125 -0
- package/.docs/raw/docs/runtimes/concepts/stability.mdx +67 -0
- package/.docs/raw/docs/runtimes/concepts/threads.mdx +428 -0
- package/.docs/raw/docs/runtimes/custom/assistant-transport.mdx +703 -0
- package/.docs/raw/docs/runtimes/custom/data-stream.mdx +323 -0
- package/.docs/raw/docs/runtimes/custom/external-store.mdx +253 -1236
- package/.docs/raw/docs/runtimes/custom/local-runtime.mdx +746 -0
- package/.docs/raw/docs/runtimes/custom/overview.mdx +71 -0
- package/.docs/raw/docs/runtimes/google-adk/api.mdx +256 -0
- package/.docs/raw/docs/runtimes/google-adk/hooks.mdx +717 -0
- package/.docs/raw/docs/runtimes/google-adk/overview.mdx +69 -0
- package/.docs/raw/docs/runtimes/google-adk/quickstart.mdx +229 -0
- package/.docs/raw/docs/runtimes/langchain.mdx +533 -0
- package/.docs/raw/docs/runtimes/langgraph/generative-ui.mdx +305 -0
- package/.docs/raw/docs/runtimes/langgraph/interrupts.mdx +104 -0
- package/.docs/raw/docs/runtimes/langgraph/overview.mdx +84 -0
- package/.docs/raw/docs/runtimes/langgraph/quickstart.mdx +496 -0
- package/.docs/raw/docs/runtimes/langgraph/streaming.mdx +127 -0
- package/.docs/raw/docs/runtimes/langgraph/threads.mdx +113 -0
- package/.docs/raw/docs/runtimes/langgraph/tutorial/introduction.mdx +3 -3
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-1.mdx +0 -23
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +1 -1
- package/.docs/raw/docs/runtimes/opencode/hooks.mdx +191 -0
- package/.docs/raw/docs/runtimes/opencode/overview.mdx +48 -0
- package/.docs/raw/docs/runtimes/opencode/quickstart.mdx +119 -0
- package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +74 -198
- package/.docs/raw/docs/ui/accordion.mdx +1 -0
- package/.docs/raw/docs/ui/assistant-modal.mdx +1 -0
- package/.docs/raw/docs/ui/assistant-sidebar.mdx +1 -0
- package/.docs/raw/docs/ui/attachment.mdx +1 -0
- package/.docs/raw/docs/ui/badge.mdx +1 -0
- package/.docs/raw/docs/ui/composer-trigger-popover.mdx +200 -0
- package/.docs/raw/docs/ui/context-display.mdx +1 -0
- package/.docs/raw/docs/ui/diff-viewer.mdx +1 -0
- package/.docs/raw/docs/ui/directive-text.mdx +114 -0
- package/.docs/raw/docs/ui/file.mdx +1 -0
- package/.docs/raw/docs/ui/image.mdx +1 -0
- package/.docs/raw/docs/ui/markdown.mdx +2 -14
- package/.docs/raw/docs/ui/mermaid.mdx +1 -0
- package/.docs/raw/docs/ui/message-timing.mdx +3 -2
- package/.docs/raw/docs/ui/model-selector.mdx +1 -0
- package/.docs/raw/docs/ui/part-grouping.mdx +325 -313
- package/.docs/raw/docs/ui/quote.mdx +1 -0
- package/.docs/raw/docs/ui/reasoning.mdx +69 -32
- package/.docs/raw/docs/ui/scrollbar.mdx +1 -0
- package/.docs/raw/docs/ui/select.mdx +1 -0
- package/.docs/raw/docs/ui/sources.mdx +1 -0
- package/.docs/raw/docs/ui/streamdown.mdx +1 -0
- package/.docs/raw/docs/ui/syntax-highlighting.mdx +1 -0
- package/.docs/raw/docs/ui/tabs.mdx +1 -0
- package/.docs/raw/docs/ui/thread-list.mdx +17 -0
- package/.docs/raw/docs/ui/thread.mdx +56 -1
- package/.docs/raw/docs/ui/tool-fallback.mdx +1 -0
- package/.docs/raw/docs/ui/tool-group.mdx +39 -11
- package/.docs/raw/docs/ui/voice.mdx +1 -0
- package/.docs/raw/docs/utilities/heat-graph.mdx +1 -0
- package/.docs/raw/docs/utilities/react-o11y.mdx +278 -0
- package/.docs/raw/docs/utilities/tw-shimmer.mdx +1 -0
- package/dist/utils/logger.js +1 -1
- package/dist/utils/logger.js.map +1 -1
- package/package.json +4 -4
- package/src/tools/tests/path-traversal.test.ts +1 -1
- package/src/utils/logger.ts +1 -1
- package/.docs/raw/docs/(docs)/guides/branching.mdx +0 -65
- package/.docs/raw/docs/(docs)/guides/chain-of-thought.mdx +0 -164
- package/.docs/raw/docs/(docs)/guides/editing.mdx +0 -66
- package/.docs/raw/docs/(docs)/guides/mentions.mdx +0 -406
- package/.docs/raw/docs/(docs)/guides/slash-commands.mdx +0 -275
- package/.docs/raw/docs/(docs)/guides/speech.mdx +0 -38
- package/.docs/raw/docs/runtimes/a2a/index.mdx +0 -298
- package/.docs/raw/docs/runtimes/assistant-transport.mdx +0 -1033
- package/.docs/raw/docs/runtimes/custom/custom-thread-list.mdx +0 -268
- package/.docs/raw/docs/runtimes/custom/local.mdx +0 -1464
- package/.docs/raw/docs/runtimes/data-stream.mdx +0 -422
- package/.docs/raw/docs/runtimes/google-adk/index.mdx +0 -686
- package/.docs/raw/docs/runtimes/helicone.mdx +0 -61
- package/.docs/raw/docs/runtimes/langgraph/index.mdx +0 -607
- package/.docs/raw/docs/runtimes/langgraph/tutorial/index.mdx +0 -12
- package/.docs/raw/docs/runtimes/langserve.mdx +0 -116
- package/.docs/raw/docs/runtimes/mastra/full-stack-integration.mdx +0 -218
- package/.docs/raw/docs/runtimes/mastra/overview.mdx +0 -18
- package/.docs/raw/docs/runtimes/mastra/separate-server-integration.mdx +0 -217
- 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,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 {
|
|
8
|
+
import {
|
|
9
|
+
ChainOfThoughtPrimitive as ChainOfThoughtPrimitiveDocs,
|
|
10
|
+
MessagePrimitive as MessagePrimitiveDocs,
|
|
11
|
+
} from "@/generated/primitiveDocs";
|
|
8
12
|
|
|
9
|
-
The ChainOfThought primitive
|
|
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="
|
|
12
|
-
|
|
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.
|
|
31
|
-
{(
|
|
32
|
-
if (part.type === "
|
|
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
|
-
|
|
36
|
-
|
|
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
|
-
##
|
|
65
|
+
## Recommended: GroupedParts
|
|
76
66
|
|
|
77
|
-
|
|
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.
|
|
87
|
-
{(
|
|
88
|
-
if (part.type === "
|
|
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
|
-
|
|
92
|
-
|
|
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
|
-
|
|
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
|
-
|
|
118
|
+
### Concepts
|
|
114
119
|
|
|
115
|
-
|
|
120
|
+
#### How Grouping Works
|
|
116
121
|
|
|
117
|
-
`ChainOfThoughtPrimitive.Parts` reads the current message's grouped reasoning and tool-call context
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
194
|
+
### Parts API Reference
|
|
190
195
|
|
|
191
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
241
|
+
### Patterns
|
|
237
242
|
|
|
238
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|