McpPrompts
Compose MCP prompt picker behavior with unstyled parts for listing, selecting, and inserting prompts.
McpPrompts
McpPrompts in @tambo-ai/react-ui-base owns the MCP prompt selection lifecycle — listing available prompts, fetching selected prompt content, validating format, and surfacing errors — while keeping styling in @tambo-ai/ui-registry or your own UI layer.
Demo
import { McpPrompts } from "@tambo-ai/react-ui-base/mcp-prompts";import { Sparkles } from "lucide-react";export function DemoMcpPrompts() { return ( <McpPrompts.Root onInsertText={(text) => console.log("Insert:", text)}> <McpPrompts.Trigger className="flex items-center gap-2 rounded-lg border border-neutral-200 px-3 py-1.5 text-sm text-neutral-700 hover:bg-neutral-100 disabled:opacity-40 dark:border-neutral-700 dark:text-neutral-300 dark:hover:bg-neutral-800"> <Sparkles className="h-3.5 w-3.5" /> Insert Prompt </McpPrompts.Trigger> <McpPrompts.List render={(props, state) => ( <div {...props} className="mt-1 flex flex-col gap-1 rounded-lg border border-neutral-200 bg-white p-1 shadow-lg dark:border-neutral-700 dark:bg-neutral-800"> {state.prompts.map((entry) => ( <McpPrompts.Item key={entry.prompt.name} name={entry.prompt.name} description={entry.prompt.description} className="w-full rounded-md px-3 py-1.5 text-left text-sm text-neutral-700 hover:bg-neutral-100 data-[selected]:bg-neutral-100 dark:text-neutral-300 dark:hover:bg-neutral-700" > {entry.prompt.name} </McpPrompts.Item> ))} </div> )} /> <McpPrompts.Error render={(props, state) => ( <div {...props} className="mt-2 text-sm text-red-600 dark:text-red-400"> {state.error} </div> )} /> </McpPrompts.Root> );}Anatomy
<McpPrompts.Root onInsertText={handleInsert}>
<McpPrompts.Trigger />
<McpPrompts.List>
<McpPrompts.Item name="..." />
</McpPrompts.List>
<McpPrompts.Error />
</McpPrompts.Root>Examples
Prompt Selection Lifecycle
The Root manages a selection lifecycle: idle -> fetching -> done (or error). When a prompt is selected via Item, the Root fetches the prompt content, validates it, and calls onInsertText with the extracted text.
<McpPrompts.Root
onInsertText={(text) => {
setInputValue((prev) => (prev ? `${prev}\n\n${text}` : text));
}}
>
{/* children */}
</McpPrompts.Root>Accessing List State via Render Props
Use the render prop on List to access the prompt collection for custom iteration:
<McpPrompts.List
render={(props, state) => (
<ul {...props}>
{state.prompts.map((entry) => (
<li key={entry.prompt.name}>
<McpPrompts.Item
name={entry.prompt.name}
description={entry.prompt.description}
>
<strong>{entry.prompt.name}</strong>
<span>{entry.prompt.description}</span>
</McpPrompts.Item>
</li>
))}
</ul>
)}
/>Error Handling
The Error part only renders when the selection lifecycle enters the error state (invalid format, no text content, or fetch failure). Consumers are responsible for managing error dismissal.
<McpPrompts.Error
render={(props, state) => (
<div {...props} role="alert" className="text-red-500">
{state.error}
</div>
)}
/>API reference
Root
| Prop | Type | Description |
|---|---|---|
onInsertText | (text: string) => void | Optional. Callback invoked when prompt text is ready. |
Renders nothing when no MCP prompts are available and not loading.
Render state:
| Field | Type | Description |
|---|---|---|
promptCount | number | Number of available prompts. |
isLoading | boolean | Whether the prompt list is loading. |
status | "idle" | "fetching" | "error" | "done" | Current selection lifecycle status. |
Trigger
No custom props. Renders as a <button> disabled when no prompts are available.
Render state:
| Field | Type | Description |
|---|---|---|
hasPrompts | boolean | Whether prompts are available. |
isLoading | boolean | Whether the prompt list is loading. |
List
No custom props. Provides the prompt collection through render state.
Render state:
| Field | Type | Description |
|---|---|---|
prompts | ListPromptEntry[] | Array of available prompts. |
promptCount | number | Count of available prompts. |
Item
| Prop | Type | Description |
|---|---|---|
name | string | The prompt name to select when clicked. |
description | string | Optional description exposed via state. |
Render state:
| Field | Type | Description |
|---|---|---|
name | string | The prompt name. |
description | string | undefined | The prompt description. |
isSelected | boolean | Whether this prompt is currently selected. |
select | () => void | Selects this prompt. |
Error
No custom props. Renders only when the selection status is "error".
Render state:
| Field | Type | Description |
|---|---|---|
error | string | null | The error message. |
Accessibility
Triggerrenders as<button>and is automatically disabled when no prompts are available.Itemrenders as<button>with adata-selectedattribute for the currently selected prompt.- Consumers should provide appropriate
aria-labelattributes on the trigger.
Styling Hooks
data-slot="mcp-prompts"data-slot="mcp-prompts-trigger"data-slot="mcp-prompts-list"data-slot="mcp-prompts-item"data-slot="mcp-prompts-error"data-selectedonItemwhen selected