@assistant-ui/mcp-docs-server 0.1.35 → 0.1.38
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 +1 -1
- package/.docs/organized/code-examples/with-a2a.md +2 -2
- package/.docs/organized/code-examples/with-ag-ui.md +2 -2
- package/.docs/organized/code-examples/with-ai-sdk-v6.md +4 -4
- package/.docs/organized/code-examples/with-artifacts.md +4 -4
- package/.docs/organized/code-examples/with-assistant-transport.md +70 -54
- package/.docs/organized/code-examples/with-browser-extension.md +4 -4
- package/.docs/organized/code-examples/with-chain-of-thought.md +40 -89
- package/.docs/organized/code-examples/with-cloud-standalone.md +4 -4
- package/.docs/organized/code-examples/with-cloud.md +4 -4
- package/.docs/organized/code-examples/with-custom-thread-list.md +4 -4
- package/.docs/organized/code-examples/with-elevenlabs-conversational.md +7 -7
- package/.docs/organized/code-examples/with-elevenlabs-scribe.md +7 -7
- package/.docs/organized/code-examples/with-eve.md +343 -0
- package/.docs/organized/code-examples/with-expo.md +910 -933
- package/.docs/organized/code-examples/with-external-store.md +2 -2
- package/.docs/organized/code-examples/with-ffmpeg.md +5 -8
- package/.docs/organized/code-examples/with-generative-ui.md +6 -6
- package/.docs/organized/code-examples/with-google-adk.md +3 -3
- package/.docs/organized/code-examples/with-heat-graph.md +1 -1
- package/.docs/organized/code-examples/with-image-generation.md +4 -4
- package/.docs/organized/code-examples/with-interactables.md +166 -338
- package/.docs/organized/code-examples/with-langchain.md +4 -4
- package/.docs/organized/code-examples/with-langgraph.md +20 -157
- package/.docs/organized/code-examples/with-livekit.md +8 -8
- package/.docs/organized/code-examples/with-mcp.md +19 -10
- package/.docs/organized/code-examples/with-opencode.md +3 -3
- package/.docs/organized/code-examples/with-pi.md +9 -7
- package/.docs/organized/code-examples/with-react-hook-form.md +13 -6
- package/.docs/organized/code-examples/with-react-ink-web.md +5 -5
- package/.docs/organized/code-examples/with-react-ink.md +1 -1
- package/.docs/organized/code-examples/with-react-router.md +11 -11
- package/.docs/organized/code-examples/with-resumable-stream.md +5 -5
- package/.docs/organized/code-examples/with-store.md +1 -1
- package/.docs/organized/code-examples/with-tanstack.md +7 -7
- package/.docs/organized/code-examples/with-tap-runtime.md +2 -2
- package/.docs/organized/code-examples/with-virtualized-thread.md +44 -24
- package/.docs/raw/docs/(docs)/cli.mdx +5 -3
- package/.docs/raw/docs/(docs)/devtools.mdx +25 -2
- package/.docs/raw/docs/(docs)/index.mdx +5 -2
- package/.docs/raw/docs/(docs)/installation.mdx +5 -2
- package/.docs/raw/docs/(reference)/api-reference/external-store/message-conversion.mdx +16 -16
- package/.docs/raw/docs/(reference)/api-reference/hooks/composer-triggers.mdx +73 -42
- package/.docs/raw/docs/(reference)/api-reference/hooks/model-context.mdx +3 -20
- package/.docs/raw/docs/(reference)/api-reference/hooks/primitives.mdx +234 -166
- package/.docs/raw/docs/(reference)/api-reference/integrations/eve.mdx +51 -0
- package/.docs/raw/docs/(reference)/api-reference/integrations/index.mdx +4 -1
- package/.docs/raw/docs/(reference)/api-reference/integrations/react-ai-sdk.mdx +70 -38
- package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar.mdx +30 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/attachment.mdx +7 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/branch-picker.mdx +26 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/chain-of-thought.mdx +15 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +103 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +16 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +56 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/queue-item.mdx +12 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/selection-toolbar.mdx +12 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/suggestion.mdx +14 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +57 -1
- package/.docs/raw/docs/(reference)/api-reference/tools/index.mdx +6 -0
- package/.docs/raw/docs/(reference)/api-reference/tools/interactables-legacy.mdx +55 -0
- package/.docs/raw/docs/(reference)/api-reference/tools/interactables.mdx +151 -0
- package/.docs/raw/docs/(reference)/api-reference/tools/rendering.mdx +15 -15
- package/.docs/raw/docs/(reference)/api-reference/tools/toolkits.mdx +20 -20
- package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +25 -9
- package/.docs/raw/docs/cloud/langgraph.mdx +1 -1
- package/.docs/raw/docs/guides/headless-composer-input.mdx +113 -0
- package/.docs/raw/docs/guides/latex.mdx +28 -22
- package/.docs/raw/docs/guides/mentions.mdx +32 -7
- package/.docs/raw/docs/guides/slash-commands.mdx +3 -6
- package/.docs/raw/docs/guides/speech.mdx +5 -7
- package/.docs/raw/docs/guides/virtualization.mdx +77 -7
- package/.docs/raw/docs/guides/voice.mdx +3 -2
- package/.docs/raw/docs/integrations/attachments/custom-adapter.mdx +4 -12
- package/.docs/raw/docs/integrations/auth/better-auth.mdx +7 -10
- package/.docs/raw/docs/integrations/auth/clerk.mdx +3 -9
- package/.docs/raw/docs/integrations/auth/next-auth.mdx +3 -8
- package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +11 -8
- package/.docs/raw/docs/integrations/index.mdx +6 -13
- package/.docs/raw/docs/integrations/observability/helicone.mdx +3 -4
- package/.docs/raw/docs/integrations/observability/langfuse.mdx +3 -5
- package/.docs/raw/docs/integrations/observability/langsmith.mdx +5 -4
- package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +4 -3
- package/.docs/raw/docs/migrations/react-langgraph-v0-7.mdx +2 -2
- package/.docs/raw/docs/primitives/composer.mdx +8 -0
- package/.docs/raw/docs/primitives/thread-list.mdx +30 -6
- package/.docs/raw/docs/primitives/thread.mdx +24 -0
- package/.docs/raw/docs/runtimes/a2a/quickstart.mdx +1 -1
- package/.docs/raw/docs/runtimes/ag-ui/quickstart.mdx +1 -1
- package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +24 -1
- package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +1 -1
- package/.docs/raw/docs/runtimes/custom/external-store.mdx +54 -0
- package/.docs/raw/docs/runtimes/eve/overview.mdx +100 -0
- package/.docs/raw/docs/runtimes/eve/quickstart.mdx +143 -0
- package/.docs/raw/docs/runtimes/google-adk/quickstart.mdx +1 -1
- package/.docs/raw/docs/runtimes/langchain.mdx +388 -20
- package/.docs/raw/docs/runtimes/langgraph/quickstart.mdx +1 -1
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-1.mdx +1 -1
- package/.docs/raw/docs/runtimes/opencode/hooks.mdx +1 -1
- package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +6 -0
- package/.docs/raw/docs/tools/defining-tools.mdx +9 -0
- package/.docs/raw/docs/tools/generative-ui.mdx +37 -0
- package/.docs/raw/docs/tools/interactables-legacy.mdx +410 -0
- package/.docs/raw/docs/tools/interactables.mdx +892 -223
- package/.docs/raw/docs/tools/mcp-apps.mdx +12 -3
- package/.docs/raw/docs/tools/mcp.mdx +9 -4
- package/.docs/raw/docs/tools/multi-agent.mdx +5 -0
- package/.docs/raw/docs/tools/user-managed-mcp.mdx +17 -3
- package/.docs/raw/docs/ui/composer-trigger-popover.mdx +2 -0
- package/.docs/raw/docs/ui/file.mdx +1 -1
- package/.docs/raw/docs/ui/follow-up-suggestions.mdx +80 -0
- package/.docs/raw/docs/ui/model-selector.mdx +38 -5
- package/.docs/raw/docs/ui/part-grouping.mdx +38 -0
- package/.docs/raw/docs/utilities/react-o11y.mdx +92 -6
- package/README.md +1 -1
- package/dist/constants.d.ts +2 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +2 -1
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -2
- package/dist/index.js.map +1 -1
- package/dist/prepare-docs/copy-raw.d.ts.map +1 -1
- package/dist/prepare-docs/copy-raw.js +0 -4
- package/dist/prepare-docs/copy-raw.js.map +1 -1
- package/dist/tools/docs.d.ts.map +1 -1
- package/dist/tools/docs.js +18 -6
- package/dist/tools/docs.js.map +1 -1
- package/dist/tools/examples.d.ts +3 -1
- package/dist/tools/examples.d.ts.map +1 -1
- package/dist/tools/examples.js +1 -1
- package/dist/tools/examples.js.map +1 -1
- package/dist/tools/resources.d.ts +7 -0
- package/dist/tools/resources.d.ts.map +1 -0
- package/dist/tools/resources.js +74 -0
- package/dist/tools/resources.js.map +1 -0
- package/dist/tools/search.d.ts +33 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +39 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/tests/test-setup.d.ts.map +1 -1
- package/dist/tools/tests/test-setup.js +3 -1
- package/dist/tools/tests/test-setup.js.map +1 -1
- package/dist/utils/mdx.d.ts +2 -1
- package/dist/utils/mdx.d.ts.map +1 -1
- package/dist/utils/mdx.js +19 -2
- package/dist/utils/mdx.js.map +1 -1
- package/dist/utils/paths.d.ts +2 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +18 -1
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/search.d.ts +10 -0
- package/dist/utils/search.d.ts.map +1 -0
- package/dist/utils/search.js +97 -0
- package/dist/utils/search.js.map +1 -0
- package/package.json +4 -4
- package/src/constants.ts +2 -0
- package/src/index.ts +28 -6
- package/src/prepare-docs/copy-raw.ts +0 -5
- package/src/tools/docs.ts +30 -4
- package/src/tools/examples.ts +4 -2
- package/src/tools/resources.ts +114 -0
- package/src/tools/search.ts +46 -0
- package/src/tools/tests/completions.test.ts +46 -0
- package/src/tools/tests/directory-size-cap.test.ts +50 -0
- package/src/tools/tests/mcp-protocol.test.ts +21 -1
- package/src/tools/tests/resources.test.ts +102 -0
- package/src/tools/tests/search.test.ts +37 -0
- package/src/tools/tests/test-setup.ts +2 -0
- package/src/utils/mdx.ts +21 -1
- package/src/utils/paths.ts +22 -0
- package/src/utils/search.ts +131 -0
- package/.docs/raw/blog/2024-07-29-hello/index.mdx +0 -64
- package/.docs/raw/blog/2024-09-11/index.mdx +0 -10
- package/.docs/raw/blog/2024-12-15/index.mdx +0 -10
- package/.docs/raw/blog/2025-01-31-changelog/index.mdx +0 -127
- package/.docs/raw/blog/2026-03-launch-week/index.mdx +0 -258
|
@@ -24,6 +24,12 @@ Capability presence is determined at mount time by which handlers you provide. U
|
|
|
24
24
|
|
|
25
25
|
The renderer talks to a backend route you expose — the MCP client lives server-side so credentials and transport stay out of the browser. The route receives `{ method, params }` POSTs and dispatches to your MCP client.
|
|
26
26
|
|
|
27
|
+
### Install the MCP client
|
|
28
|
+
|
|
29
|
+
Install the AI SDK MCP client package used by the route handler:
|
|
30
|
+
|
|
31
|
+
<InstallCommand npm={["@ai-sdk/mcp"]} />
|
|
32
|
+
|
|
27
33
|
### Client
|
|
28
34
|
|
|
29
35
|
Compose `McpAppRenderer({...})` into your `Tools` resource. Provide `host.url` pointing at your route. Any tool-call part carrying `mcp.app` metadata renders the MCP App widget automatically.
|
|
@@ -61,12 +67,15 @@ The route accepts `POST` requests with `{ method, params }` JSON bodies. Dispatc
|
|
|
61
67
|
|
|
62
68
|
```ts
|
|
63
69
|
// app/api/mcp-apps/route.ts
|
|
64
|
-
import {
|
|
70
|
+
import { createMCPClient } from "@ai-sdk/mcp";
|
|
65
71
|
|
|
66
|
-
let clientPromise: ReturnType<typeof
|
|
72
|
+
let clientPromise: ReturnType<typeof createMCPClient> | undefined;
|
|
67
73
|
const getClient = () => {
|
|
68
|
-
clientPromise ??=
|
|
74
|
+
clientPromise ??= createMCPClient({
|
|
69
75
|
transport: { type: "sse", url: process.env.MCP_SERVER_URL! },
|
|
76
|
+
}).catch((error) => {
|
|
77
|
+
clientPromise = undefined;
|
|
78
|
+
throw error;
|
|
70
79
|
});
|
|
71
80
|
return clientPromise;
|
|
72
81
|
};
|
|
@@ -7,10 +7,10 @@ description: Connect MCP servers as a tool catalog in your assistant-ui app.
|
|
|
7
7
|
|
|
8
8
|
## How it works
|
|
9
9
|
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
```mermaid
|
|
11
|
+
flowchart LR
|
|
12
|
+
client["client"] --> api["/api/chat"] --> mcp["MCP client"] --> server["MCP server<br/>(HTTP, SSE, stdio)"]
|
|
13
|
+
mcp --> tools["tools()"] --> stream["passed to<br/>streamText({ tools })"]
|
|
14
14
|
```
|
|
15
15
|
|
|
16
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.
|
|
@@ -93,6 +93,7 @@ export default defineToolkit({
|
|
|
93
93
|
github: {
|
|
94
94
|
type: "http",
|
|
95
95
|
url: "https://mcp.example.com/mcp",
|
|
96
|
+
connectionTimeout: 10_000,
|
|
96
97
|
},
|
|
97
98
|
}),
|
|
98
99
|
});
|
|
@@ -101,6 +102,10 @@ export default defineToolkit({
|
|
|
101
102
|
Use `AISDKToolkit` in the route. It opens the MCP clients, merges their tools
|
|
102
103
|
with the rest of your toolkit, and closes them when you call `close()`:
|
|
103
104
|
|
|
105
|
+
`connectionTimeout` is optional and measured in milliseconds. Set it to fail
|
|
106
|
+
the server-side MCP readiness flow (`createMCPClient()` plus `tools()`) before
|
|
107
|
+
a bad URL or hanging local process can stall the route.
|
|
108
|
+
|
|
104
109
|
```ts title="app/api/chat/route.ts"
|
|
105
110
|
import { AISDKToolkit } from "@assistant-ui/react-ai-sdk";
|
|
106
111
|
import { openai } from "@ai-sdk/openai";
|
|
@@ -16,6 +16,10 @@ Key behaviors:
|
|
|
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
|
|
|
19
|
+
<Callout type="info">
|
|
20
|
+
This renders a sub-agent's **messages**. To visualize a sub-agent's **execution trace** instead (timing, span hierarchy, waterfalls), see [react-o11y](/docs/utilities/react-o11y), which renders observability spans as collapsible trees and timelines.
|
|
21
|
+
</Callout>
|
|
22
|
+
|
|
19
23
|
## Quick Start
|
|
20
24
|
|
|
21
25
|
<Steps>
|
|
@@ -226,6 +230,7 @@ function SubConversation({
|
|
|
226
230
|
## Related
|
|
227
231
|
|
|
228
232
|
- [Generative UI](/docs/tools/tool-ui) — Creating tool call UIs
|
|
233
|
+
- [react-o11y](/docs/utilities/react-o11y) — Visualize sub-agent execution as collapsible span trees, waterfalls, and call timelines
|
|
229
234
|
- [MessagePartPrimitive](/docs/api-reference/primitives/message-part) — API reference for message part primitives
|
|
230
235
|
- [Sub-Agent Model Tracking](/docs/cloud/ai-sdk#sub-agent-model-tracking) — Track delegated model usage and costs in the Cloud dashboard
|
|
231
236
|
- [LangGraph Streaming](/docs/runtimes/langgraph/streaming) — Event handlers, subgraph events, and message metadata
|
|
@@ -59,20 +59,28 @@ const connectors = [
|
|
|
59
59
|
name: "Weather",
|
|
60
60
|
url: "https://mcp.example.com/weather",
|
|
61
61
|
auth: { type: "none" },
|
|
62
|
+
connectionTimeout: 10_000,
|
|
62
63
|
}),
|
|
63
64
|
];
|
|
64
65
|
|
|
65
66
|
export function Providers({ children }: { children: React.ReactNode }) {
|
|
66
|
-
const aui = useAui({
|
|
67
|
+
const aui = useAui({
|
|
68
|
+
mcp: McpManagerResource({
|
|
69
|
+
connectors,
|
|
70
|
+
connectionTimeout: 15_000,
|
|
71
|
+
}),
|
|
72
|
+
});
|
|
67
73
|
return <AuiProvider value={aui}>{children}</AuiProvider>;
|
|
68
74
|
}
|
|
69
75
|
```
|
|
70
76
|
|
|
71
|
-
Defaults
|
|
77
|
+
Defaults and useful options:
|
|
72
78
|
|
|
73
79
|
- `storage` — `McpLocalStorage()` (override for production; see [Storage](#storage))
|
|
74
80
|
- `oauthRedirectUri` — `${window.location.origin}/mcp/callback`
|
|
75
81
|
- `autoConnect` — `true` (connect on mount when usable auth is persisted)
|
|
82
|
+
- `connectionTimeout` — optional timeout in milliseconds. Set it on the manager as a default or on a connector/custom server to bound the MCP readiness flow (`connect()` plus `listTools()`) with a clear error.
|
|
83
|
+
- Connector `id` values must be unique. The id is used for server lookup, OAuth routing, and model-visible tool names such as `linear__search`.
|
|
76
84
|
|
|
77
85
|
</Step>
|
|
78
86
|
<Step>
|
|
@@ -208,14 +216,20 @@ The callback reads `?state=...&code=...` from the URL, derives the target server
|
|
|
208
216
|
|
|
209
217
|
```tsx
|
|
210
218
|
"use client";
|
|
219
|
+
import { lastAssistantMessageIsCompleteWithToolCalls } from "ai";
|
|
211
220
|
import { useChatRuntime } from "@assistant-ui/react-ai-sdk";
|
|
212
221
|
|
|
213
222
|
export function Chat() {
|
|
214
|
-
const runtime = useChatRuntime({
|
|
223
|
+
const runtime = useChatRuntime({
|
|
224
|
+
api: "/api/chat",
|
|
225
|
+
sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls,
|
|
226
|
+
});
|
|
215
227
|
/* … */
|
|
216
228
|
}
|
|
217
229
|
```
|
|
218
230
|
|
|
231
|
+
`sendAutomaticallyWhen` sends completed frontend tool results back to the server so the model can continue after a tool call.
|
|
232
|
+
|
|
219
233
|
Tool names are prefixed `serverId__toolName` to avoid collisions across connected servers. The toolkit re-registers whenever a server connects / disconnects or its tool list changes.
|
|
220
234
|
|
|
221
235
|
If no chat runtime is mounted, `McpManagerResource` brings its own minimal `modelContext` along. Tools are still callable directly:
|
|
@@ -185,6 +185,8 @@ The popover implements the WAI-ARIA editable combobox pattern.
|
|
|
185
185
|
| `backLabel` | `string` | `"Back"` | Back button label |
|
|
186
186
|
| `emptyCategoriesLabel` | `string` | `"No items available"` | Shown when no categories are available |
|
|
187
187
|
| `emptyItemsLabel` | `string` | `"No matching items"` | Shown when no items match |
|
|
188
|
+
| `isLoading` | `boolean` | `false` | Whether the adapter is resolving items (async sources). Pair with `unstable_useLiveCompletionAdapter`. |
|
|
189
|
+
| `loadingLabel` | `string` | `"Loading…"` | Shown in place of `emptyItemsLabel` while `isLoading` and no items are present |
|
|
188
190
|
|
|
189
191
|
All other props (`className`, etc.) forward to the underlying popover `div`.
|
|
190
192
|
|
|
@@ -27,7 +27,7 @@ Pass `File` to `MessagePrimitive.Parts`:
|
|
|
27
27
|
```tsx title="/components/assistant-ui/thread.tsx" {1,8}
|
|
28
28
|
import { File } from "@/components/assistant-ui/file";
|
|
29
29
|
|
|
30
|
-
const
|
|
30
|
+
const UserMessage: FC = () => {
|
|
31
31
|
return (
|
|
32
32
|
<MessagePrimitive.Root className="...">
|
|
33
33
|
<MessagePrimitive.Parts>
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Follow-Up Suggestions
|
|
3
|
+
description: Render runtime-generated follow-up prompt chips after an assistant response.
|
|
4
|
+
platforms: ["react"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
import { FollowUpSuggestionsSample } from "@/components/docs/samples/follow-up-suggestions";
|
|
8
|
+
|
|
9
|
+
<FollowUpSuggestionsSample />
|
|
10
|
+
|
|
11
|
+
`ThreadFollowupSuggestions` renders the current thread's runtime suggestions as clickable prompt chips. Use it for follow-up prompts that arrive after a response, such as suggested next questions, refinements, or task shortcuts.
|
|
12
|
+
|
|
13
|
+
<Callout type="info">
|
|
14
|
+
This component reads from `thread.suggestions`. For static welcome-screen prompts, use `ThreadPrimitive.Suggestions` instead.
|
|
15
|
+
</Callout>
|
|
16
|
+
|
|
17
|
+
## Getting Started
|
|
18
|
+
|
|
19
|
+
<Steps>
|
|
20
|
+
<Step>
|
|
21
|
+
|
|
22
|
+
### Add `follow-up-suggestions`
|
|
23
|
+
|
|
24
|
+
<InstallCommand shadcn={["follow-up-suggestions"]} />
|
|
25
|
+
|
|
26
|
+
This adds a `/components/assistant-ui/follow-up-suggestions.tsx` file to your project.
|
|
27
|
+
|
|
28
|
+
</Step>
|
|
29
|
+
<Step>
|
|
30
|
+
|
|
31
|
+
### Provide runtime suggestions
|
|
32
|
+
|
|
33
|
+
Pass suggestions through your runtime. External-store runtimes, AI SDK runtimes, and local runtimes can all surface follow-up prompts through `thread.suggestions`.
|
|
34
|
+
|
|
35
|
+
```tsx title="/app/assistant.tsx" {7-10}
|
|
36
|
+
const runtime = useExternalStoreRuntime({
|
|
37
|
+
messages,
|
|
38
|
+
convertMessage,
|
|
39
|
+
onNew: async (message) => {
|
|
40
|
+
// append the message in your store
|
|
41
|
+
},
|
|
42
|
+
suggestions: [
|
|
43
|
+
{ prompt: "Summarize this as action items" },
|
|
44
|
+
{ prompt: "Write a shorter version" },
|
|
45
|
+
],
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
</Step>
|
|
50
|
+
<Step>
|
|
51
|
+
|
|
52
|
+
### Render after messages
|
|
53
|
+
|
|
54
|
+
Place `ThreadFollowupSuggestions` near the bottom of your thread viewport, after the assistant message list and before the composer.
|
|
55
|
+
|
|
56
|
+
```tsx title="/components/assistant-ui/thread.tsx" {1,10}
|
|
57
|
+
import { ThreadFollowupSuggestions } from "@/components/assistant-ui/follow-up-suggestions";
|
|
58
|
+
|
|
59
|
+
const ThreadViewportFooter = () => {
|
|
60
|
+
return (
|
|
61
|
+
<ThreadPrimitive.ViewportFooter>
|
|
62
|
+
<ThreadPrimitive.ScrollToBottom />
|
|
63
|
+
<ThreadFollowupSuggestions />
|
|
64
|
+
<Composer />
|
|
65
|
+
</ThreadPrimitive.ViewportFooter>
|
|
66
|
+
);
|
|
67
|
+
};
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
</Step>
|
|
71
|
+
</Steps>
|
|
72
|
+
|
|
73
|
+
## Behavior
|
|
74
|
+
|
|
75
|
+
The component only renders when the thread is not empty and not currently running. Each suggestion uses `ThreadPrimitive.Suggestion`, replaces the composer text with the prompt, and sends it immediately.
|
|
76
|
+
|
|
77
|
+
## Related Components
|
|
78
|
+
|
|
79
|
+
- [Thread](/docs/ui/thread) - Complete chat interface with message list and composer
|
|
80
|
+
- [Suggestions guide](/docs/guides/suggestions) - Runtime and static suggestion patterns
|
|
@@ -149,7 +149,7 @@ Search is opt-in. Pass `searchable` to the default component:
|
|
|
149
149
|
<ModelSelector models={models} searchable />
|
|
150
150
|
```
|
|
151
151
|
|
|
152
|
-
Or compose `ModelSelector.Search` into a custom layout. Matching runs against each model's `id`, `name`, and `keywords`; add the provider name to `keywords` so typing "openai" finds its models.
|
|
152
|
+
The same prop works on `ModelSelector.Content` when it renders its default children. Or compose `ModelSelector.Search` into a custom layout. Matching runs against each model's `id`, `name`, and `keywords`; add the provider name to `keywords` so typing "openai" finds its models.
|
|
153
153
|
|
|
154
154
|
## Composition
|
|
155
155
|
|
|
@@ -204,6 +204,7 @@ import {
|
|
|
204
204
|
| `ModelSelector.Value` | Selected model name, icon, and active effort |
|
|
205
205
|
| `ModelSelector.Content` | Popover content wrapping a Command |
|
|
206
206
|
| `ModelSelector.Search` | Search input that filters the list |
|
|
207
|
+
| `ModelSelector.FocusAnchor` | Visually hidden input that anchors keyboard navigation when there is no search box |
|
|
207
208
|
| `ModelSelector.List` | List of model items (renders all models by default) |
|
|
208
209
|
| `ModelSelector.Empty` | Empty state shown when search has no matches |
|
|
209
210
|
| `ModelSelector.Group` | Labeled group of items (e.g. by provider) |
|
|
@@ -213,12 +214,20 @@ import {
|
|
|
213
214
|
|
|
214
215
|
`ModelSelector.List` is a Command list, so filtering and keyboard navigation work across groups automatically. Custom sorting is plain code: order the models before rendering items.
|
|
215
216
|
|
|
217
|
+
Keyboard navigation needs a focused input to drive it. When content is unfiltered (`searchable={false}` on `ModelSelector.Content`, or the default children), `ModelSelector.Content` renders a visually hidden `ModelSelector.FocusAnchor` automatically, so custom layouts without a search box stay keyboard-operable. In a custom layout that renders neither `ModelSelector.Search` nor `searchable={false}`, place `ModelSelector.FocusAnchor` yourself to keep the list reachable from the keyboard.
|
|
218
|
+
|
|
216
219
|
<Callout type="warn">
|
|
217
220
|
`ModelSelector.Content` wraps a Command whose root keydown handler claims
|
|
218
|
-
<
|
|
219
|
-
composed inside it (filter chips,
|
|
220
|
-
|
|
221
|
-
|
|
221
|
+
<Kbd>Enter</Kbd> to select the highlighted model and the arrow keys to move
|
|
222
|
+
through the list. Interactive elements composed inside it (filter chips,
|
|
223
|
+
custom effort controls) should stop propagation for the keys they handle in
|
|
224
|
+
their own `onKeyDown` so the focused control responds instead.
|
|
225
|
+
`ModelSelector.Effort` does this for <Kbd>Home</Kbd> / <Kbd>End</Kbd> (which
|
|
226
|
+
cmdk would otherwise use to jump to the first / last model), lets its
|
|
227
|
+
radiogroup own <Kbd>ArrowLeft</Kbd> / <Kbd>ArrowRight</Kbd>, and hands
|
|
228
|
+
<Kbd>ArrowUp</Kbd> / <Kbd>ArrowDown</Kbd> back to the model list by
|
|
229
|
+
refocusing cmdk's input, so the highlight only moves while a following
|
|
230
|
+
<Kbd>Enter</Kbd> can act on it.
|
|
222
231
|
</Callout>
|
|
223
232
|
|
|
224
233
|
## Variants
|
|
@@ -247,6 +256,30 @@ Use the `size` prop to control the trigger dimensions.
|
|
|
247
256
|
<ModelSelector size="lg" /> // Large (h-10)
|
|
248
257
|
```
|
|
249
258
|
|
|
259
|
+
## Keyboard Navigation
|
|
260
|
+
|
|
261
|
+
The picker is fully operable from the keyboard, including when search is disabled.
|
|
262
|
+
|
|
263
|
+
| Key | Action |
|
|
264
|
+
| --- | --- |
|
|
265
|
+
| <Kbd>ArrowDown</Kbd> / <Kbd>ArrowUp</Kbd> | Open the popover from the focused trigger; move between models once open, returning focus to the list from the Thinking row |
|
|
266
|
+
| <Kbd>Enter</Kbd> | Select the highlighted model and close |
|
|
267
|
+
| <Kbd>Escape</Kbd> | Close the popover and return focus to the trigger |
|
|
268
|
+
| <Kbd>Tab</Kbd> | Move from the model list to the Thinking row |
|
|
269
|
+
| <Kbd>ArrowLeft</Kbd> / <Kbd>ArrowRight</Kbd> | Move between reasoning effort levels (Thinking row) |
|
|
270
|
+
| <Kbd>Home</Kbd> / <Kbd>End</Kbd> | Jump to the first / last model (list) or effort level (Thinking row) |
|
|
271
|
+
|
|
272
|
+
When `searchable` is set, typing filters the list; otherwise the keys above drive selection directly.
|
|
273
|
+
|
|
274
|
+
## Accessibility
|
|
275
|
+
|
|
276
|
+
The picker implements the WAI-ARIA combobox pattern over Popover + Command.
|
|
277
|
+
|
|
278
|
+
- The trigger is `role="combobox"` with `aria-haspopup="listbox"`; Radix Popover manages `aria-expanded` and `aria-controls`.
|
|
279
|
+
- The model list is a Command (cmdk) listbox: each item is `role="option"` with `aria-selected`, and the active item is tracked with `aria-activedescendant`.
|
|
280
|
+
- Keyboard navigation works without a visible search box: `ModelSelector.Content` renders a visually hidden input (`ModelSelector.FocusAnchor`) that anchors cmdk's focus so the list stays reachable. Pass `searchable` to surface a real search input instead.
|
|
281
|
+
- The Thinking row (`ModelSelector.Effort`) is a `role="radiogroup"` of `role="radio"` toggles with roving tabindex, so it is a single tab stop and <Kbd>ArrowLeft</Kbd> / <Kbd>ArrowRight</Kbd> move focus and select in one step. <Kbd>ArrowUp</Kbd> / <Kbd>ArrowDown</Kbd> return focus to the model list.
|
|
282
|
+
|
|
250
283
|
## How It Works
|
|
251
284
|
|
|
252
285
|
The default `ModelSelector` export registers the selection with assistant-ui's `ModelContext` system:
|
|
@@ -252,6 +252,44 @@ The synthetic `"standalone-tool-call"` key on `groupPartByType` matches all of t
|
|
|
252
252
|
The `"mcp-app"` key is deprecated in favor of `"standalone-tool-call"`, which is a superset (it also matches MCP-app tool calls). Existing `"mcp-app"` usage keeps working.
|
|
253
253
|
</Callout>
|
|
254
254
|
|
|
255
|
+
### Render Tool Calls as Flat Rows
|
|
256
|
+
|
|
257
|
+
The previous section keeps `"tool-call"` folded into the chain-of-thought and only lifts standalone tool UIs out. To keep reasoning collapsed in a group while every tool call renders as its own row in the message flow, map both tool keys to `[]`:
|
|
258
|
+
|
|
259
|
+
```tsx
|
|
260
|
+
<MessagePrimitive.GroupedParts
|
|
261
|
+
groupBy={groupPartByType({
|
|
262
|
+
reasoning: ["group-thought", "group-reasoning"],
|
|
263
|
+
"tool-call": [],
|
|
264
|
+
"standalone-tool-call": [],
|
|
265
|
+
})}
|
|
266
|
+
>
|
|
267
|
+
{({ part, children }) => {
|
|
268
|
+
switch (part.type) {
|
|
269
|
+
case "group-thought":
|
|
270
|
+
case "group-reasoning":
|
|
271
|
+
return <ReasoningBlock>{children}</ReasoningBlock>;
|
|
272
|
+
case "reasoning":
|
|
273
|
+
return <Reasoning {...part} />;
|
|
274
|
+
case "tool-call":
|
|
275
|
+
return part.toolUI ?? <ToolFallback {...part} />;
|
|
276
|
+
case "text":
|
|
277
|
+
return <MarkdownText />;
|
|
278
|
+
case "indicator":
|
|
279
|
+
return <LoadingDots />;
|
|
280
|
+
default:
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
}}
|
|
284
|
+
</MessagePrimitive.GroupedParts>
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Adjacent `reasoning` parts still coalesce into one `group-thought`, while each tool call is a leaf at the same level as text — the `"standalone-tool-call"` entry is mapped to `[]` too so human-in-the-loop and generative-UI tools stay flat alongside routine calls instead of falling through to `"tool-call"`. Tool-call leaves keep their stable identity keys across re-renders, so rows don't remount as the message streams.
|
|
288
|
+
|
|
289
|
+
<Callout type="warn">
|
|
290
|
+
This renders tool calls flat **in the message flow** — each leaf sits where the part appears, in order. It does not pin, portal, float, or otherwise move tool UIs out of the flow into a sidebar or fixed region. For out-of-flow placement you still own the layout outside `GroupedParts`.
|
|
291
|
+
</Callout>
|
|
292
|
+
|
|
255
293
|
### Group by Custom Metadata
|
|
256
294
|
|
|
257
295
|
Use any custom metadata in your parts for grouping:
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: react-o11y
|
|
3
|
-
description: Headless primitives for visualizing observability spans
|
|
3
|
+
description: Headless primitives for visualizing observability spans as collapsible trace trees, waterfalls, and agent and LLM call timelines.
|
|
4
4
|
platforms: ["react"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
import { WaterfallSample } from "@/components/docs/samples/o11y/waterfall";
|
|
8
|
+
import {
|
|
9
|
+
StatusSample,
|
|
10
|
+
CollapseSample,
|
|
11
|
+
StreamingSample,
|
|
12
|
+
} from "@/components/docs/samples/o11y/capability-samples";
|
|
13
|
+
|
|
7
14
|
<Callout type="warn">
|
|
8
|
-
`@assistant-ui/react-o11y` is
|
|
15
|
+
`@assistant-ui/react-o11y` is experimental. The API may change without notice.
|
|
9
16
|
</Callout>
|
|
10
17
|
|
|
11
18
|
`@assistant-ui/react-o11y` provides headless, Radix-style primitives for rendering observability spans as collapsible, indented hierarchical UIs. Use it to build trace inspectors, waterfall debug panels, or LLM call timelines on top of your own span data source.
|
|
@@ -15,6 +22,10 @@ platforms: ["react"]
|
|
|
15
22
|
- **Tree-aware** — Automatic depth, parent / child collapse, time range computation.
|
|
16
23
|
- **Reactive** — Built on the same reactive core as the runtimes, so spans stream into your UI as they change.
|
|
17
24
|
|
|
25
|
+
<div className="not-prose my-6">
|
|
26
|
+
<WaterfallSample />
|
|
27
|
+
</div>
|
|
28
|
+
|
|
18
29
|
## Installation
|
|
19
30
|
|
|
20
31
|
<InstallCommand npm={["@assistant-ui/react-o11y"]} />
|
|
@@ -43,13 +54,12 @@ function SpanRow() {
|
|
|
43
54
|
<SpanPrimitive.StatusIndicator className="size-2 rounded-full data-[span-status=running]:bg-yellow-500 data-[span-status=completed]:bg-green-500 data-[span-status=failed]:bg-red-500" />
|
|
44
55
|
<SpanPrimitive.TypeBadge className="rounded bg-muted px-1.5 text-xs" />
|
|
45
56
|
<SpanPrimitive.Name className="text-sm" />
|
|
46
|
-
<SpanPrimitive.Children components={{ Span: SpanRow }} />
|
|
47
57
|
</SpanPrimitive.Root>
|
|
48
58
|
);
|
|
49
59
|
}
|
|
50
60
|
|
|
51
61
|
export function TraceView({ spans }: { spans: SpanData[] }) {
|
|
52
|
-
const aui = useAui({
|
|
62
|
+
const aui = useAui({ span: SpanResource({ spans }) });
|
|
53
63
|
|
|
54
64
|
return (
|
|
55
65
|
<AuiProvider value={aui}>
|
|
@@ -61,6 +71,32 @@ export function TraceView({ spans }: { spans: SpanData[] }) {
|
|
|
61
71
|
|
|
62
72
|
`SpanData` is the input shape your code produces (see [SpanData](#spandata)). `SpanResource` enriches it with depth, child counts, time range, and collapse state.
|
|
63
73
|
|
|
74
|
+
## Examples
|
|
75
|
+
|
|
76
|
+
### Status states
|
|
77
|
+
|
|
78
|
+
`data-span-status` exposes each span's lifecycle, so running, completed, failed, and skipped are styled with pure CSS.
|
|
79
|
+
|
|
80
|
+
<div className="not-prose my-6">
|
|
81
|
+
<StatusSample />
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
### Collapsible subtrees
|
|
85
|
+
|
|
86
|
+
`SpanPrimitive.CollapseToggle` removes a span's descendants from the visible flat list, not just hides them. Click a chevron to collapse a subtree.
|
|
87
|
+
|
|
88
|
+
<div className="not-prose my-6">
|
|
89
|
+
<CollapseSample />
|
|
90
|
+
</div>
|
|
91
|
+
|
|
92
|
+
### Streaming spans
|
|
93
|
+
|
|
94
|
+
`SpanResource` re-derives the tree whenever the `spans` prop changes, so spans stream in and update live.
|
|
95
|
+
|
|
96
|
+
<div className="not-prose my-6">
|
|
97
|
+
<StreamingSample />
|
|
98
|
+
</div>
|
|
99
|
+
|
|
64
100
|
## Anatomy
|
|
65
101
|
|
|
66
102
|
```tsx
|
|
@@ -71,7 +107,7 @@ import {
|
|
|
71
107
|
} from "@assistant-ui/react-o11y";
|
|
72
108
|
|
|
73
109
|
// Top-level: mount SpanResource via useAui
|
|
74
|
-
const aui = useAui({
|
|
110
|
+
const aui = useAui({ span: SpanResource({ spans }) });
|
|
75
111
|
|
|
76
112
|
<AuiProvider value={aui}>
|
|
77
113
|
{/* Render visible spans (flat-list output respecting collapsed state) */}
|
|
@@ -104,7 +140,7 @@ Resource that ingests raw span data and exposes a tree-aware reactive state to p
|
|
|
104
140
|
SpanResource({ spans }: { spans: SpanData[] }): ClientOutput<"span">;
|
|
105
141
|
```
|
|
106
142
|
|
|
107
|
-
Mount through `useAui({
|
|
143
|
+
Mount through `useAui({ span: SpanResource({ spans }) })`.
|
|
108
144
|
|
|
109
145
|
The resource computes:
|
|
110
146
|
|
|
@@ -243,6 +279,56 @@ Convenience component that pairs `SpanByIndexProvider` with a render component:
|
|
|
243
279
|
|
|
244
280
|
Useful when you want explicit control over which child indices to render (e.g. for virtualization).
|
|
245
281
|
|
|
282
|
+
### SpanPrimitive.Timeline
|
|
283
|
+
|
|
284
|
+
A `<div>` that provides a timeline range to descendant `TimelineBar` primitives and exposes range CSS variables.
|
|
285
|
+
|
|
286
|
+
| Prop | Type | Default | Description |
|
|
287
|
+
| --- | --- | --- | --- |
|
|
288
|
+
| `timeRange` | `{ min: number; max: number }` | `span.timeRange` | Override the range used for positioning bars. |
|
|
289
|
+
| `paddingEnd` | `number` | `0` | Extends the max by this ratio of the range duration, useful for right-side breathing room. |
|
|
290
|
+
|
|
291
|
+
Exposes `data-span-timeline` and CSS variables:
|
|
292
|
+
|
|
293
|
+
| Variable | Description |
|
|
294
|
+
| --- | --- |
|
|
295
|
+
| `--span-timeline-min-ms` | Timeline start timestamp. |
|
|
296
|
+
| `--span-timeline-max-ms` | Timeline end timestamp after padding. |
|
|
297
|
+
| `--span-timeline-range-ms` | Timeline duration after padding. |
|
|
298
|
+
|
|
299
|
+
### SpanPrimitive.TimelineBar
|
|
300
|
+
|
|
301
|
+
A `<div>` that positions the current span within the nearest `SpanPrimitive.Timeline` range. It reads `startedAt`, `endedAt`, `status`, `type`, and `timeRange` from the current span scope.
|
|
302
|
+
|
|
303
|
+
```tsx
|
|
304
|
+
<SpanPrimitive.Timeline>
|
|
305
|
+
<SpanPrimitive.Children>
|
|
306
|
+
{() => (
|
|
307
|
+
<div className="relative h-8">
|
|
308
|
+
<SpanPrimitive.TimelineBar className="top-1 h-6 rounded bg-blue-500" />
|
|
309
|
+
</div>
|
|
310
|
+
)}
|
|
311
|
+
</SpanPrimitive.Children>
|
|
312
|
+
</SpanPrimitive.Timeline>
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
Running spans use the timeline range max when `now` is omitted, keeping SSR and hydration deterministic. For live ticking, update a timestamp from an effect or animation loop and pass it as `now`.
|
|
316
|
+
|
|
317
|
+
| Prop | Type | Default | Description |
|
|
318
|
+
| --- | --- | --- | --- |
|
|
319
|
+
| `now` | `number` | `undefined` | Explicit timestamp used as the end of running spans. |
|
|
320
|
+
| `timeRange` | `{ min: number; max: number }` | nearest `Timeline` range | Override the range used for this bar. |
|
|
321
|
+
|
|
322
|
+
Exposes `data-span-status`, `data-span-type`, `data-span-running`, and these CSS variables:
|
|
323
|
+
|
|
324
|
+
| Variable | Description |
|
|
325
|
+
| --- | --- |
|
|
326
|
+
| `--span-timeline-left` | Bar start position as a percentage. |
|
|
327
|
+
| `--span-timeline-end` | Bar end position as a percentage. |
|
|
328
|
+
| `--span-timeline-width` | Bar width as a percentage. |
|
|
329
|
+
| `--span-timeline-duration-ms` | Bar duration in milliseconds. |
|
|
330
|
+
| `--span-timeline-min-width` | Optional consumer-set minimum width used by the default inline size. |
|
|
331
|
+
|
|
246
332
|
## Styling
|
|
247
333
|
|
|
248
334
|
All primitives forward refs and accept standard DOM props (`className`, `style`, etc.). Use the data attributes for state-based styling:
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# `@assistant-ui/mcp-docs-server`
|
|
2
2
|
|
|
3
|
-
Model Context Protocol (MCP) server that gives AI assistants direct access to assistant-ui's documentation and example projects. Exposes `assistantUIDocs` (retrieve documentation by path)
|
|
3
|
+
Model Context Protocol (MCP) server that gives AI assistants direct access to assistant-ui's documentation and example projects. Exposes `assistantUIDocs` (retrieve documentation by path), `assistantUIExamples` (access complete example projects), and `assistantUISearch` (keyword search across the bundled docs), and serves the same docs and examples as readable MCP **resources** (`aui-docs:///{path}`, `aui-example:///{name}`).
|
|
4
4
|
|
|
5
5
|
> [!NOTE]
|
|
6
6
|
> Detailed installation, troubleshooting, and advanced usage at [assistant-ui.com/docs/llm#mcp](https://www.assistant-ui.com/docs/llm#mcp).
|
package/dist/constants.d.ts
CHANGED
|
@@ -7,7 +7,8 @@ declare const CODE_EXAMPLES_PATH: string;
|
|
|
7
7
|
declare const MDX_EXTENSION = ".mdx";
|
|
8
8
|
declare const MD_EXTENSION = ".md";
|
|
9
9
|
declare const MAX_FILE_SIZE: number;
|
|
10
|
+
declare const MAX_DIRECTORY_CONTENT_SIZE: number;
|
|
10
11
|
declare const IS_PREPARE_MODE: boolean | undefined;
|
|
11
12
|
//#endregion
|
|
12
|
-
export { CODE_EXAMPLES_PATH, DOCS_PATH, EXAMPLES_PATH, IS_PREPARE_MODE, MAX_FILE_SIZE, MDX_EXTENSION, MD_EXTENSION, PACKAGE_DIR, ROOT_DIR };
|
|
13
|
+
export { CODE_EXAMPLES_PATH, DOCS_PATH, EXAMPLES_PATH, IS_PREPARE_MODE, MAX_DIRECTORY_CONTENT_SIZE, MAX_FILE_SIZE, MDX_EXTENSION, MD_EXTENSION, PACKAGE_DIR, ROOT_DIR };
|
|
13
14
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","names":[],"sources":["../src/constants.ts"],"mappings":";cAKa,QAAA;AAAA,cACA,WAAA;AAAA,cAEA,aAAA;AAAA,cAGA,SAAA;AAAA,cACA,kBAAA;AAAA,cAEA,aAAA;AAAA,cACA,YAAA;AAAA,cAEA,aAAA;AAAA,cAEA,eAAA"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","names":[],"sources":["../src/constants.ts"],"mappings":";cAKa,QAAA;AAAA,cACA,WAAA;AAAA,cAEA,aAAA;AAAA,cAGA,SAAA;AAAA,cACA,kBAAA;AAAA,cAEA,aAAA;AAAA,cACA,YAAA;AAAA,cAEA,aAAA;AAAA,cAEA,0BAAA;AAAA,cAEA,eAAA"}
|
package/dist/constants.js
CHANGED
|
@@ -11,8 +11,9 @@ const CODE_EXAMPLES_PATH = join(DOCS_BASE, "organized/code-examples");
|
|
|
11
11
|
const MDX_EXTENSION = ".mdx";
|
|
12
12
|
const MD_EXTENSION = ".md";
|
|
13
13
|
const MAX_FILE_SIZE = 10 * 1024 * 1024;
|
|
14
|
+
const MAX_DIRECTORY_CONTENT_SIZE = 1024 * 1024;
|
|
14
15
|
const IS_PREPARE_MODE = process.argv[1]?.includes("prepare-docs/prepare");
|
|
15
16
|
//#endregion
|
|
16
|
-
export { CODE_EXAMPLES_PATH, DOCS_PATH, EXAMPLES_PATH, IS_PREPARE_MODE, MAX_FILE_SIZE, MDX_EXTENSION, MD_EXTENSION, PACKAGE_DIR, ROOT_DIR };
|
|
17
|
+
export { CODE_EXAMPLES_PATH, DOCS_PATH, EXAMPLES_PATH, IS_PREPARE_MODE, MAX_DIRECTORY_CONTENT_SIZE, MAX_FILE_SIZE, MDX_EXTENSION, MD_EXTENSION, PACKAGE_DIR, ROOT_DIR };
|
|
17
18
|
|
|
18
19
|
//# sourceMappingURL=constants.js.map
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","names":[],"sources":["../src/constants.ts"],"sourcesContent":["import { fileURLToPath } from \"node:url\";\nimport { dirname, join } from \"node:path\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nexport const ROOT_DIR = join(__dirname, \"../../../\");\nexport const PACKAGE_DIR = join(__dirname, \"../\");\n\nexport const EXAMPLES_PATH = join(ROOT_DIR, \"examples\");\n\nconst DOCS_BASE = join(PACKAGE_DIR, \".docs\");\nexport const DOCS_PATH = join(DOCS_BASE, \"raw/docs\");\nexport const CODE_EXAMPLES_PATH = join(DOCS_BASE, \"organized/code-examples\");\n\nexport const MDX_EXTENSION = \".mdx\";\nexport const MD_EXTENSION = \".md\";\n\nexport const MAX_FILE_SIZE = 10 * 1024 * 1024;\n\nexport const IS_PREPARE_MODE = process.argv[1]?.includes(\n \"prepare-docs/prepare\",\n);\n"],"mappings":";;;AAGA,MAAM,YAAY,QAAQ,cAAc,OAAO,KAAK,GAAG,CAAC;AAExD,MAAa,WAAW,KAAK,WAAW,WAAW;AACnD,MAAa,cAAc,KAAK,WAAW,KAAK;AAEhD,MAAa,gBAAgB,KAAK,UAAU,UAAU;AAEtD,MAAM,YAAY,KAAK,aAAa,OAAO;AAC3C,MAAa,YAAY,KAAK,WAAW,UAAU;AACnD,MAAa,qBAAqB,KAAK,WAAW,yBAAyB;AAE3E,MAAa,gBAAgB;AAC7B,MAAa,eAAe;AAE5B,MAAa,gBAAgB,KAAK,OAAO;AAEzC,MAAa,kBAAkB,QAAQ,KAAK,EAAE,EAAE,SAC9C,sBACF"}
|
|
1
|
+
{"version":3,"file":"constants.js","names":[],"sources":["../src/constants.ts"],"sourcesContent":["import { fileURLToPath } from \"node:url\";\nimport { dirname, join } from \"node:path\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nexport const ROOT_DIR = join(__dirname, \"../../../\");\nexport const PACKAGE_DIR = join(__dirname, \"../\");\n\nexport const EXAMPLES_PATH = join(ROOT_DIR, \"examples\");\n\nconst DOCS_BASE = join(PACKAGE_DIR, \".docs\");\nexport const DOCS_PATH = join(DOCS_BASE, \"raw/docs\");\nexport const CODE_EXAMPLES_PATH = join(DOCS_BASE, \"organized/code-examples\");\n\nexport const MDX_EXTENSION = \".mdx\";\nexport const MD_EXTENSION = \".md\";\n\nexport const MAX_FILE_SIZE = 10 * 1024 * 1024;\n\nexport const MAX_DIRECTORY_CONTENT_SIZE = 1024 * 1024;\n\nexport const IS_PREPARE_MODE = process.argv[1]?.includes(\n \"prepare-docs/prepare\",\n);\n"],"mappings":";;;AAGA,MAAM,YAAY,QAAQ,cAAc,OAAO,KAAK,GAAG,CAAC;AAExD,MAAa,WAAW,KAAK,WAAW,WAAW;AACnD,MAAa,cAAc,KAAK,WAAW,KAAK;AAEhD,MAAa,gBAAgB,KAAK,UAAU,UAAU;AAEtD,MAAM,YAAY,KAAK,aAAa,OAAO;AAC3C,MAAa,YAAY,KAAK,WAAW,UAAU;AACnD,MAAa,qBAAqB,KAAK,WAAW,yBAAyB;AAE3E,MAAa,gBAAgB;AAC7B,MAAa,eAAe;AAE5B,MAAa,gBAAgB,KAAK,OAAO;AAEzC,MAAa,6BAA6B,OAAO;AAEjD,MAAa,kBAAkB,QAAQ,KAAK,EAAE,EAAE,SAC9C,sBACF"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;cAgBa,MAAA,EAAM,SAGjB;AAAA,iBAmCoB,SAAA,IAAS,OAAA"}
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,8 @@ import { PACKAGE_DIR } from "./constants.js";
|
|
|
2
2
|
import { logger } from "./utils/logger.js";
|
|
3
3
|
import { docsTools } from "./tools/docs.js";
|
|
4
4
|
import { examplesTools } from "./tools/examples.js";
|
|
5
|
+
import { searchTools } from "./tools/search.js";
|
|
6
|
+
import { registerResources } from "./tools/resources.js";
|
|
5
7
|
import { join } from "node:path";
|
|
6
8
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
7
9
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
@@ -12,8 +14,34 @@ const server = new McpServer({
|
|
|
12
14
|
name: "assistant-ui-docs",
|
|
13
15
|
version: packageJson.version
|
|
14
16
|
});
|
|
15
|
-
server.
|
|
16
|
-
|
|
17
|
+
server.registerTool(docsTools.name, {
|
|
18
|
+
title: "assistant-ui Documentation",
|
|
19
|
+
description: docsTools.description,
|
|
20
|
+
inputSchema: docsTools.parameters,
|
|
21
|
+
annotations: {
|
|
22
|
+
readOnlyHint: true,
|
|
23
|
+
openWorldHint: false
|
|
24
|
+
}
|
|
25
|
+
}, docsTools.execute);
|
|
26
|
+
server.registerTool(examplesTools.name, {
|
|
27
|
+
title: "assistant-ui Examples",
|
|
28
|
+
description: examplesTools.description,
|
|
29
|
+
inputSchema: examplesTools.parameters,
|
|
30
|
+
annotations: {
|
|
31
|
+
readOnlyHint: true,
|
|
32
|
+
openWorldHint: false
|
|
33
|
+
}
|
|
34
|
+
}, examplesTools.execute);
|
|
35
|
+
server.registerTool(searchTools.name, {
|
|
36
|
+
title: "Search assistant-ui Documentation",
|
|
37
|
+
description: searchTools.description,
|
|
38
|
+
inputSchema: searchTools.parameters,
|
|
39
|
+
annotations: {
|
|
40
|
+
readOnlyHint: true,
|
|
41
|
+
openWorldHint: false
|
|
42
|
+
}
|
|
43
|
+
}, searchTools.execute);
|
|
44
|
+
registerResources(server);
|
|
17
45
|
async function runServer() {
|
|
18
46
|
try {
|
|
19
47
|
logger.info(`Starting assistant-ui MCP docs server v${packageJson.version}`);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { docsTools } from \"./tools/docs.js\";\nimport { examplesTools } from \"./tools/examples.js\";\nimport { logger } from \"./utils/logger.js\";\nimport { PACKAGE_DIR } from \"./constants.js\";\n\nimport { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nconst packageJson = JSON.parse(\n readFileSync(join(PACKAGE_DIR, \"package.json\"), \"utf-8\"),\n);\n\nexport const server = new McpServer({\n name: \"assistant-ui-docs\",\n version: packageJson.version,\n});\n\nserver.
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { docsTools } from \"./tools/docs.js\";\nimport { examplesTools } from \"./tools/examples.js\";\nimport { searchTools } from \"./tools/search.js\";\nimport { registerResources } from \"./tools/resources.js\";\nimport { logger } from \"./utils/logger.js\";\nimport { PACKAGE_DIR } from \"./constants.js\";\n\nimport { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nconst packageJson = JSON.parse(\n readFileSync(join(PACKAGE_DIR, \"package.json\"), \"utf-8\"),\n);\n\nexport const server = new McpServer({\n name: \"assistant-ui-docs\",\n version: packageJson.version,\n});\n\nserver.registerTool(\n docsTools.name,\n {\n title: \"assistant-ui Documentation\",\n description: docsTools.description,\n inputSchema: docsTools.parameters,\n annotations: { readOnlyHint: true, openWorldHint: false },\n },\n docsTools.execute,\n);\nserver.registerTool(\n examplesTools.name,\n {\n title: \"assistant-ui Examples\",\n description: examplesTools.description,\n inputSchema: examplesTools.parameters,\n annotations: { readOnlyHint: true, openWorldHint: false },\n },\n examplesTools.execute,\n);\nserver.registerTool(\n searchTools.name,\n {\n title: \"Search assistant-ui Documentation\",\n description: searchTools.description,\n inputSchema: searchTools.parameters,\n annotations: { readOnlyHint: true, openWorldHint: false },\n },\n searchTools.execute,\n);\n\nregisterResources(server);\n\nexport async function runServer() {\n try {\n logger.info(\n `Starting assistant-ui MCP docs server v${packageJson.version}`,\n );\n const transport = new StdioServerTransport();\n await server.connect(transport);\n } catch (error) {\n logger.error(\"Failed to start MCP server\", error);\n process.exit(1);\n }\n}\n\nif (import.meta.url === `file://${process.argv[1]}`) {\n void runServer().catch((error) => {\n console.error(\"Failed to start server:\", error);\n process.exit(1);\n });\n}\n"],"mappings":";;;;;;;;;;;AAYA,MAAM,cAAc,KAAK,MACvB,aAAa,KAAK,aAAa,cAAc,GAAG,OAAO,CACzD;AAEA,MAAa,SAAS,IAAI,UAAU;CAClC,MAAM;CACN,SAAS,YAAY;AACvB,CAAC;AAED,OAAO,aACL,UAAU,MACV;CACE,OAAO;CACP,aAAa,UAAU;CACvB,aAAa,UAAU;CACvB,aAAa;EAAE,cAAc;EAAM,eAAe;CAAM;AAC1D,GACA,UAAU,OACZ;AACA,OAAO,aACL,cAAc,MACd;CACE,OAAO;CACP,aAAa,cAAc;CAC3B,aAAa,cAAc;CAC3B,aAAa;EAAE,cAAc;EAAM,eAAe;CAAM;AAC1D,GACA,cAAc,OAChB;AACA,OAAO,aACL,YAAY,MACZ;CACE,OAAO;CACP,aAAa,YAAY;CACzB,aAAa,YAAY;CACzB,aAAa;EAAE,cAAc;EAAM,eAAe;CAAM;AAC1D,GACA,YAAY,OACd;AAEA,kBAAkB,MAAM;AAExB,eAAsB,YAAY;CAChC,IAAI;EACF,OAAO,KACL,0CAA0C,YAAY,SACxD;EACA,MAAM,YAAY,IAAI,qBAAqB;EAC3C,MAAM,OAAO,QAAQ,SAAS;CAChC,SAAS,OAAO;EACd,OAAO,MAAM,8BAA8B,KAAK;EAChD,QAAQ,KAAK,CAAC;CAChB;AACF;AAEA,IAAI,OAAO,KAAK,QAAQ,UAAU,QAAQ,KAAK,MAC7C,UAAe,CAAC,CAAC,OAAO,UAAU;CAChC,QAAQ,MAAM,2BAA2B,KAAK;CAC9C,QAAQ,KAAK,CAAC;AAChB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copy-raw.d.ts","names":[],"sources":["../../src/prepare-docs/copy-raw.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"copy-raw.d.ts","names":[],"sources":["../../src/prepare-docs/copy-raw.ts"],"mappings":";iBAiCsB,OAAA,IAAW,OAAO"}
|
|
@@ -4,7 +4,6 @@ import { extname, join } from "node:path";
|
|
|
4
4
|
import { copyFile, mkdir, readdir, rm } from "node:fs/promises";
|
|
5
5
|
//#region src/prepare-docs/copy-raw.ts
|
|
6
6
|
const DOCS_SOURCE = join(ROOT_DIR, "apps/docs/content/docs");
|
|
7
|
-
const BLOG_SOURCE = join(ROOT_DIR, "apps/docs/content/blog");
|
|
8
7
|
const DOCS_DEST = join(ROOT_DIR, "packages/mcp-docs-server/.docs/raw");
|
|
9
8
|
async function copyDir(src, dest) {
|
|
10
9
|
try {
|
|
@@ -38,9 +37,6 @@ async function copyRaw() {
|
|
|
38
37
|
const docsPath = join(DOCS_DEST, "docs");
|
|
39
38
|
await copyDir(DOCS_SOURCE, docsPath);
|
|
40
39
|
logger.info(`Copied documentation to ${docsPath}`);
|
|
41
|
-
const blogPath = join(DOCS_DEST, "blog");
|
|
42
|
-
await copyDir(BLOG_SOURCE, blogPath);
|
|
43
|
-
logger.info(`Copied blog posts to ${blogPath}`);
|
|
44
40
|
logger.info("Raw documentation copy complete");
|
|
45
41
|
} catch (error) {
|
|
46
42
|
logger.error("Failed to copy raw documentation", error);
|