@assistant-ui/mcp-docs-server 0.1.27 → 0.1.28
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 +1 -1
- package/.docs/organized/code-examples/with-ag-ui.md +2 -2
- package/.docs/organized/code-examples/with-ai-sdk-v6.md +3 -3
- package/.docs/organized/code-examples/with-artifacts.md +3 -3
- package/.docs/organized/code-examples/with-assistant-transport.md +1 -1
- package/.docs/organized/code-examples/with-chain-of-thought.md +3 -3
- package/.docs/organized/code-examples/with-cloud-standalone.md +3 -3
- package/.docs/organized/code-examples/with-cloud.md +3 -3
- package/.docs/organized/code-examples/with-custom-thread-list.md +3 -3
- package/.docs/organized/code-examples/with-elevenlabs-conversational.md +5 -5
- package/.docs/organized/code-examples/with-elevenlabs-scribe.md +5 -5
- package/.docs/organized/code-examples/with-expo.md +3 -3
- package/.docs/organized/code-examples/with-external-store.md +1 -1
- package/.docs/organized/code-examples/with-ffmpeg.md +3 -3
- package/.docs/organized/code-examples/with-generative-ui.md +841 -0
- package/.docs/organized/code-examples/with-google-adk.md +1 -1
- package/.docs/organized/code-examples/with-heat-graph.md +1 -1
- package/.docs/organized/code-examples/with-interactables.md +3 -3
- package/.docs/organized/code-examples/with-langgraph.md +2 -2
- package/.docs/organized/code-examples/with-livekit.md +4 -4
- package/.docs/organized/code-examples/with-parent-id-grouping.md +2 -2
- package/.docs/organized/code-examples/with-react-hook-form.md +4 -4
- package/.docs/organized/code-examples/with-react-router.md +2 -2
- package/.docs/organized/code-examples/with-store.md +1 -1
- package/.docs/organized/code-examples/with-tanstack.md +2 -2
- package/.docs/organized/code-examples/with-tap-runtime.md +1 -1
- package/.docs/raw/docs/(docs)/guides/mentions.mdx +406 -0
- package/.docs/raw/docs/(docs)/guides/slash-commands.mdx +275 -0
- package/.docs/raw/docs/primitives/composer.mdx +27 -4
- package/package.json +3 -3
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Slash Commands
|
|
3
|
+
description: Let users type / in the composer to trigger predefined actions from a popover picker.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Slash commands let users type `/` in the composer to open a popover, browse available commands, and execute one. Unlike [mentions](/docs/guides/mentions) (which insert text into the message), slash commands trigger **actions** — the `/command` text is removed from the composer and a callback fires.
|
|
7
|
+
|
|
8
|
+
## How It Works
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
User types "/" → Trigger detected → Adapter provides commands
|
|
12
|
+
↓
|
|
13
|
+
Command executed ← User selects command from popover
|
|
14
|
+
↓
|
|
15
|
+
"/command" text removed from composer
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The slash command system is built on the same [trigger popover architecture](#trigger-popover-architecture) as mentions. It has two layers:
|
|
19
|
+
|
|
20
|
+
1. **Adapter** — provides the list of available commands (flat list by default, or categorized for advanced use)
|
|
21
|
+
2. **SlashCommandRoot** — a convenience wrapper that pre-configures the trigger character (`/`) and action-based select behavior
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
### 1. Define Commands
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
import {
|
|
29
|
+
unstable_useSlashCommandAdapter,
|
|
30
|
+
ComposerPrimitive,
|
|
31
|
+
} from "@assistant-ui/react";
|
|
32
|
+
|
|
33
|
+
// Define commands outside the component for a stable reference
|
|
34
|
+
const COMMANDS = [
|
|
35
|
+
{
|
|
36
|
+
name: "summarize",
|
|
37
|
+
description: "Summarize the conversation",
|
|
38
|
+
execute: () => console.log("Summarize!"),
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: "translate",
|
|
42
|
+
description: "Translate text to another language",
|
|
43
|
+
execute: () => console.log("Translate!"),
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: "help",
|
|
47
|
+
description: "List all available commands",
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
function MyComposer() {
|
|
52
|
+
const slashAdapter = unstable_useSlashCommandAdapter({
|
|
53
|
+
commands: COMMANDS,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<ComposerPrimitive.Unstable_SlashCommandRoot adapter={slashAdapter}>
|
|
58
|
+
<ComposerPrimitive.Root>
|
|
59
|
+
<ComposerPrimitive.Input placeholder="Type / for commands..." />
|
|
60
|
+
<ComposerPrimitive.Send>Send</ComposerPrimitive.Send>
|
|
61
|
+
|
|
62
|
+
<ComposerPrimitive.Unstable_TriggerPopoverPopover className="popover">
|
|
63
|
+
<ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
64
|
+
{(items) =>
|
|
65
|
+
items.map((item, index) => (
|
|
66
|
+
<ComposerPrimitive.Unstable_TriggerPopoverItem
|
|
67
|
+
key={item.id}
|
|
68
|
+
item={item}
|
|
69
|
+
index={index}
|
|
70
|
+
className="popover-item"
|
|
71
|
+
>
|
|
72
|
+
<strong>{item.label}</strong>
|
|
73
|
+
{item.description && <span>{item.description}</span>}
|
|
74
|
+
</ComposerPrimitive.Unstable_TriggerPopoverItem>
|
|
75
|
+
))
|
|
76
|
+
}
|
|
77
|
+
</ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
78
|
+
</ComposerPrimitive.Unstable_TriggerPopoverPopover>
|
|
79
|
+
</ComposerPrimitive.Root>
|
|
80
|
+
</ComposerPrimitive.Unstable_SlashCommandRoot>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 2. Handle Command Selection
|
|
86
|
+
|
|
87
|
+
There are two ways to handle command execution:
|
|
88
|
+
|
|
89
|
+
**Via `execute` on each item** — define the action inline in the command definition:
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
{ name: "summarize", execute: () => runSummarize() }
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Via `onSelect` prop** — handle all commands in one place:
|
|
96
|
+
|
|
97
|
+
```tsx
|
|
98
|
+
<ComposerPrimitive.Unstable_SlashCommandRoot
|
|
99
|
+
adapter={slashAdapter}
|
|
100
|
+
onSelect={(item) => {
|
|
101
|
+
switch (item.id) {
|
|
102
|
+
case "summarize": runSummarize(); break;
|
|
103
|
+
case "translate": runTranslate(); break;
|
|
104
|
+
}
|
|
105
|
+
}}
|
|
106
|
+
>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Both `execute` and `onSelect` fire when a command is selected. Use whichever pattern fits your code.
|
|
110
|
+
|
|
111
|
+
## Custom Adapter
|
|
112
|
+
|
|
113
|
+
The `unstable_useSlashCommandAdapter` hook uses a **flat list** — all commands show immediately when `/` is typed, with search filtering as the user types. This is the recommended UX for most cases.
|
|
114
|
+
|
|
115
|
+
For **categorized navigation** (drill-down into groups), build the adapter manually. Return categories from `categories()` and items from `categoryItems()`. The popover will show categories first, then items within the selected category:
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
import type { Unstable_SlashCommandAdapter } from "@assistant-ui/core";
|
|
119
|
+
|
|
120
|
+
const adapter: Unstable_SlashCommandAdapter = {
|
|
121
|
+
categories() {
|
|
122
|
+
return [
|
|
123
|
+
{ id: "actions", label: "Actions" },
|
|
124
|
+
{ id: "export", label: "Export" },
|
|
125
|
+
];
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
categoryItems(categoryId) {
|
|
129
|
+
if (categoryId === "actions") {
|
|
130
|
+
return [
|
|
131
|
+
{ id: "summarize", type: "command", label: "/summarize", description: "Summarize the conversation" },
|
|
132
|
+
{ id: "translate", type: "command", label: "/translate", description: "Translate text" },
|
|
133
|
+
];
|
|
134
|
+
}
|
|
135
|
+
if (categoryId === "export") {
|
|
136
|
+
return [
|
|
137
|
+
{ id: "pdf", type: "command", label: "/export pdf", description: "Export as PDF" },
|
|
138
|
+
{ id: "markdown", type: "command", label: "/export md", description: "Export as Markdown" },
|
|
139
|
+
];
|
|
140
|
+
}
|
|
141
|
+
return [];
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
// Optional — enables search across all categories
|
|
145
|
+
search(query) {
|
|
146
|
+
const lower = query.toLowerCase();
|
|
147
|
+
const all = [...this.categoryItems("actions"), ...this.categoryItems("export")];
|
|
148
|
+
return all.filter(
|
|
149
|
+
(item) => item.label.toLowerCase().includes(lower) || item.description?.toLowerCase().includes(lower),
|
|
150
|
+
);
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
When using a categorized adapter, add `TriggerPopoverCategories` to your popover UI:
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
<ComposerPrimitive.Unstable_TriggerPopoverPopover>
|
|
159
|
+
<ComposerPrimitive.Unstable_TriggerPopoverBack>← Back</ComposerPrimitive.Unstable_TriggerPopoverBack>
|
|
160
|
+
<ComposerPrimitive.Unstable_TriggerPopoverCategories>
|
|
161
|
+
{(categories) => categories.map((cat) => (
|
|
162
|
+
<ComposerPrimitive.Unstable_TriggerPopoverCategoryItem key={cat.id} categoryId={cat.id}>
|
|
163
|
+
{cat.label}
|
|
164
|
+
</ComposerPrimitive.Unstable_TriggerPopoverCategoryItem>
|
|
165
|
+
))}
|
|
166
|
+
</ComposerPrimitive.Unstable_TriggerPopoverCategories>
|
|
167
|
+
<ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
168
|
+
{(items) => items.map((item, index) => (
|
|
169
|
+
<ComposerPrimitive.Unstable_TriggerPopoverItem key={item.id} item={item} index={index}>
|
|
170
|
+
{item.label}
|
|
171
|
+
</ComposerPrimitive.Unstable_TriggerPopoverItem>
|
|
172
|
+
))}
|
|
173
|
+
</ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
174
|
+
</ComposerPrimitive.Unstable_TriggerPopoverPopover>
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Combining with Mentions
|
|
178
|
+
|
|
179
|
+
Slash commands and mentions can coexist on the same composer. Nest both roots — the [plugin protocol](#trigger-popover-architecture) ensures they don't conflict:
|
|
180
|
+
|
|
181
|
+
```tsx
|
|
182
|
+
<ComposerPrimitive.Unstable_MentionRoot adapter={mentionAdapter}>
|
|
183
|
+
<ComposerPrimitive.Unstable_SlashCommandRoot adapter={slashAdapter}>
|
|
184
|
+
<ComposerPrimitive.Root>
|
|
185
|
+
<ComposerPrimitive.Input placeholder="Type @ to mention, / for commands..." />
|
|
186
|
+
<ComposerPrimitive.Send>Send</ComposerPrimitive.Send>
|
|
187
|
+
|
|
188
|
+
{/* Mention popover — shows when @ is typed */}
|
|
189
|
+
<ComposerPrimitive.Unstable_MentionPopover>
|
|
190
|
+
<ComposerPrimitive.Unstable_MentionCategories>
|
|
191
|
+
{(categories) => categories.map((cat) => (
|
|
192
|
+
<ComposerPrimitive.Unstable_MentionCategoryItem key={cat.id} categoryId={cat.id}>
|
|
193
|
+
{cat.label}
|
|
194
|
+
</ComposerPrimitive.Unstable_MentionCategoryItem>
|
|
195
|
+
))}
|
|
196
|
+
</ComposerPrimitive.Unstable_MentionCategories>
|
|
197
|
+
<ComposerPrimitive.Unstable_MentionItems>
|
|
198
|
+
{(items) => items.map((item) => (
|
|
199
|
+
<ComposerPrimitive.Unstable_MentionItem key={item.id} item={item}>
|
|
200
|
+
{item.label}
|
|
201
|
+
</ComposerPrimitive.Unstable_MentionItem>
|
|
202
|
+
))}
|
|
203
|
+
</ComposerPrimitive.Unstable_MentionItems>
|
|
204
|
+
</ComposerPrimitive.Unstable_MentionPopover>
|
|
205
|
+
|
|
206
|
+
{/* Slash command popover — shows when / is typed */}
|
|
207
|
+
<ComposerPrimitive.Unstable_TriggerPopoverPopover>
|
|
208
|
+
<ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
209
|
+
{(items) => items.map((item, index) => (
|
|
210
|
+
<ComposerPrimitive.Unstable_TriggerPopoverItem key={item.id} item={item} index={index}>
|
|
211
|
+
{item.label}
|
|
212
|
+
</ComposerPrimitive.Unstable_TriggerPopoverItem>
|
|
213
|
+
))}
|
|
214
|
+
</ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
215
|
+
</ComposerPrimitive.Unstable_TriggerPopoverPopover>
|
|
216
|
+
</ComposerPrimitive.Root>
|
|
217
|
+
</ComposerPrimitive.Unstable_SlashCommandRoot>
|
|
218
|
+
</ComposerPrimitive.Unstable_MentionRoot>
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Each root provides its own `TriggerPopoverContext`. When the user types `@`, the mention popover opens. When they type `/`, the slash command popover opens. Keyboard events route to whichever popover is active.
|
|
222
|
+
|
|
223
|
+
## Keyboard Navigation
|
|
224
|
+
|
|
225
|
+
Same keyboard bindings as mentions:
|
|
226
|
+
|
|
227
|
+
| Key | Action |
|
|
228
|
+
| --- | --- |
|
|
229
|
+
| <Kbd>ArrowDown</Kbd> | Highlight next item |
|
|
230
|
+
| <Kbd>ArrowUp</Kbd> | Highlight previous item |
|
|
231
|
+
| <Kbd>Enter</Kbd> | Execute highlighted command / drill into category |
|
|
232
|
+
| <Kbd>Escape</Kbd> | Close popover |
|
|
233
|
+
| <Kbd>Backspace</Kbd> | Go back to categories (when query is empty) |
|
|
234
|
+
|
|
235
|
+
## Trigger Popover Architecture
|
|
236
|
+
|
|
237
|
+
Both mentions and slash commands are built on a generic **trigger popover** system:
|
|
238
|
+
|
|
239
|
+
- `ComposerPrimitive.Unstable_TriggerPopoverRoot` — the generic root, parameterized by trigger character and select behavior
|
|
240
|
+
- `ComposerPrimitive.Unstable_MentionRoot` — preset with `trigger="@"` and `onSelect: insertDirective`
|
|
241
|
+
- `ComposerPrimitive.Unstable_SlashCommandRoot` — preset with `trigger="/"` and `onSelect: action`
|
|
242
|
+
|
|
243
|
+
The trigger popover primitives (`TriggerPopoverPopover`, `TriggerPopoverItems`, etc.) are shared across both. You can also use `TriggerPopoverRoot` directly to build custom trigger systems with other characters (e.g. `:` for emoji).
|
|
244
|
+
|
|
245
|
+
### ComposerInput Plugin Protocol
|
|
246
|
+
|
|
247
|
+
Under the hood, each trigger root registers a **ComposerInputPlugin** with the composer input. This is a generic protocol that decouples the input from any specific trigger:
|
|
248
|
+
|
|
249
|
+
```ts
|
|
250
|
+
type ComposerInputPlugin = {
|
|
251
|
+
handleKeyDown(e: KeyboardEvent): boolean;
|
|
252
|
+
setCursorPosition(pos: number): void;
|
|
253
|
+
};
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
The input iterates over registered plugins for keyboard events and cursor changes. This is what enables multiple trigger roots to coexist without conflict.
|
|
257
|
+
|
|
258
|
+
## Primitives Reference
|
|
259
|
+
|
|
260
|
+
| Primitive | Description |
|
|
261
|
+
| --- | --- |
|
|
262
|
+
| `Unstable_SlashCommandRoot` | Convenience wrapper — `TriggerPopoverRoot` with `trigger="/"` and action behavior |
|
|
263
|
+
| `Unstable_TriggerPopoverRoot` | Generic root — configurable trigger character and select behavior |
|
|
264
|
+
| `Unstable_TriggerPopoverPopover` | Container — only renders when a trigger is active (`role="listbox"`) |
|
|
265
|
+
| `Unstable_TriggerPopoverCategories` | Render-function for the top-level category list |
|
|
266
|
+
| `Unstable_TriggerPopoverCategoryItem` | Button that drills into a category (`role="option"`, auto `data-highlighted`) |
|
|
267
|
+
| `Unstable_TriggerPopoverItems` | Render-function for items within the active category or search results |
|
|
268
|
+
| `Unstable_TriggerPopoverItem` | Button that selects an item (`role="option"`, auto `data-highlighted`) |
|
|
269
|
+
| `Unstable_TriggerPopoverBack` | Button that navigates back from items to categories |
|
|
270
|
+
|
|
271
|
+
## Related
|
|
272
|
+
|
|
273
|
+
- [Mentions Guide](/docs/guides/mentions) — `@`-mention system built on the same architecture
|
|
274
|
+
- [Suggestions Guide](/docs/guides/suggestions) — static follow-up prompts (different from slash commands)
|
|
275
|
+
- [Composer Primitives](/docs/primitives/composer) — underlying composer primitives
|
|
@@ -102,19 +102,42 @@ import { ComposerPrimitive } from "@assistant-ui/react";
|
|
|
102
102
|
|
|
103
103
|
The primitive's behavior (keyboard handling, disabled state, form submission) is merged onto your element. Your styles, your component, primitive wiring.
|
|
104
104
|
|
|
105
|
-
### Unstable
|
|
105
|
+
### Unstable Trigger Popovers
|
|
106
106
|
|
|
107
|
-
Composer
|
|
107
|
+
Composer includes an unstable **trigger popover** system for character-triggered popovers (e.g. `@` for mentions, `/` for slash commands). Multiple triggers can coexist on the same input.
|
|
108
|
+
|
|
109
|
+
**Mentions** (`@` trigger) — insert directive text into the message:
|
|
108
110
|
|
|
109
111
|
```tsx
|
|
110
|
-
<ComposerPrimitive.Unstable_MentionRoot>
|
|
112
|
+
<ComposerPrimitive.Unstable_MentionRoot adapter={mentionAdapter}>
|
|
111
113
|
<ComposerPrimitive.Root>
|
|
112
|
-
<
|
|
114
|
+
<ComposerPrimitive.Input placeholder="Type @ to mention..." />
|
|
113
115
|
<ComposerPrimitive.Unstable_MentionPopover />
|
|
114
116
|
</ComposerPrimitive.Root>
|
|
115
117
|
</ComposerPrimitive.Unstable_MentionRoot>
|
|
116
118
|
```
|
|
117
119
|
|
|
120
|
+
**Slash commands** (`/` trigger) — execute an action and clear the command text:
|
|
121
|
+
|
|
122
|
+
```tsx
|
|
123
|
+
<ComposerPrimitive.Unstable_SlashCommandRoot adapter={slashAdapter}>
|
|
124
|
+
<ComposerPrimitive.Root>
|
|
125
|
+
<ComposerPrimitive.Input placeholder="Type / for commands..." />
|
|
126
|
+
<ComposerPrimitive.Unstable_TriggerPopoverPopover>
|
|
127
|
+
<ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
128
|
+
{(items) => items.map(item => (
|
|
129
|
+
<ComposerPrimitive.Unstable_TriggerPopoverItem key={item.id} item={item}>
|
|
130
|
+
{item.label}
|
|
131
|
+
</ComposerPrimitive.Unstable_TriggerPopoverItem>
|
|
132
|
+
))}
|
|
133
|
+
</ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
134
|
+
</ComposerPrimitive.Unstable_TriggerPopoverPopover>
|
|
135
|
+
</ComposerPrimitive.Root>
|
|
136
|
+
</ComposerPrimitive.Unstable_SlashCommandRoot>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
See the [Mentions guide](/docs/guides/mentions) and [Slash Commands guide](/docs/guides/slash-commands) for full documentation.
|
|
140
|
+
|
|
118
141
|
## Parts
|
|
119
142
|
|
|
120
143
|
### Root
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assistant-ui/mcp-docs-server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.28",
|
|
4
4
|
"description": "MCP server for assistant-ui documentation and examples",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
"zod": "^4.3.6"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@types/node": "^25.5.
|
|
40
|
+
"@types/node": "^25.5.2",
|
|
41
41
|
"tsx": "^4.21.0",
|
|
42
42
|
"vitest": "^4.1.2",
|
|
43
|
-
"@assistant-ui/x-buildutils": "0.0.
|
|
43
|
+
"@assistant-ui/x-buildutils": "0.0.4"
|
|
44
44
|
},
|
|
45
45
|
"publishConfig": {
|
|
46
46
|
"access": "public",
|