Skip to content
WebMCP Agents
Esc
↑↓navigate↵open⌘Jpreview
On this page

Use your shadcn components

Render the agent chat with shadcn/ui's AI patterns (the successor of Vercel's AI Elements), from the @webmcp-agents registry. The code lands in your project; the session logic stays in the package.

The built-in <AgentChat> needs one CSS import and no setup. If your app already uses shadcn/ui, you can render the same chat with the components you already have: shadcn/ui’s AI patterns (Message, Message Scroller, Prompt Input, Tool, Subagent, Reasoning, Suggestion, Model Selector). Vercel’s AI Elements moved into shadcn/ui in late 2026; these patterns are where it lives now, as source you copy into your project.

The split is the one AI Elements itself uses:

Part Where it lives What it is
useAgentChat() @webmcp-agents/chat The headless core: the conversation as AI SDK UIMessages, a useChat-shaped API (sendMessage, stop, regenerate, status), the adapter switcher, the local models, the suggestions, and toolPhase(part) for what WebMCP Agents adds to a plain tool call. Fixes reach you through the package.
The blocks the @webmcp-agents registry Source files composed of shadcn primitives. They are yours to restyle or rearrange.

Install

Add the registry once, then the block. It pulls the shadcn primitives it needs (trace, code-block, message, bubble, message-scroller, input-group, item, dropdown-menu, badge, button, scroll-area).

npx shadcn@latest registry add @webmcp-agents=https://webmcp-agents.dev/r/{name}.json
pnpm dlx shadcn@latest registry add @webmcp-agents=https://webmcp-agents.dev/r/{name}.json
yarn dlx shadcn@latest registry add @webmcp-agents=https://webmcp-agents.dev/r/{name}.json
bunx shadcn@latest registry add @webmcp-agents=https://webmcp-agents.dev/r/{name}.json
nubx shadcn@latest registry add @webmcp-agents=https://webmcp-agents.dev/r/{name}.json
aube dlx shadcn@latest registry add @webmcp-agents=https://webmcp-agents.dev/r/{name}.json
npx shadcn@latest add @webmcp-agents/agent-chat
pnpm dlx shadcn@latest add @webmcp-agents/agent-chat
yarn dlx shadcn@latest add @webmcp-agents/agent-chat
bunx shadcn@latest add @webmcp-agents/agent-chat
nubx shadcn@latest add @webmcp-agents/agent-chat
aube dlx shadcn@latest add @webmcp-agents/agent-chat
npm install @webmcp-agents/chat @webmcp-agents/react ai streamdown
pnpm add @webmcp-agents/chat @webmcp-agents/react ai streamdown
yarn add @webmcp-agents/chat @webmcp-agents/react ai streamdown
bun add @webmcp-agents/chat @webmcp-agents/react ai streamdown
nub add @webmcp-agents/chat @webmcp-agents/react ai streamdown
aube add @webmcp-agents/chat @webmcp-agents/react ai streamdown

Or add the block from its URL directly, without registering the registry: npx shadcn@latest add https://webmcp-agents.dev/r/agent-chat.json. It works in any shadcn project: Next.js, Vite, TanStack Start, React Router. Field Store on Next.js is the app that runs it.

Then render it inside the provider, where <AgentChat> would go:

import { AgentChatBlock } from "@/components/web-agents/agent-chat";
import { shopper } from "@/agents";

<WebAgentsProvider tools={tools}>
  {children}
  <AgentChatBlock agent={shopper} />
</WebAgentsProvider>

The chat still needs /api/chat (Add the chat); nothing changes server-side.

What each block shows

Block shadcn pattern What it renders
agent-chat Chat (Message Scroller), Message, Bubble, Prompt Input, Suggestion The panel: the thread, starter prompts, the composer with Stop and Send, the download card for an on-device model, errors with Try again.
agent-tool Tool (Trace + Code Block) One tool call: “Running add to cart…”, “Ran add to cart”, “Failed to run…”, “Cancelled…”, with input and output. A call parked on the page (an order waiting for the person’s click) renders as an Item that says “Confirm on the page: Click “Place order” to confirm”, with no approve or deny buttons: the click happens on the page, so a script can never confirm for the person.
agent-subagent Subagent (Trace + Badge) A delegate_to_<id> call: the sub-agent’s own tool calls nested under it, then its answer.
agent-reasoning Reasoning (Trace) “Thinking” while it streams, “Thought” after, the text inside.
agent-model-selector Model Selector (Dropdown Menu) Which assistant answers (Claude cloud, On-device), and which local model (with size and “on this device”).

Patterns not used, and why: Confirmation (approve or deny in chat) would re-create the problem the agent cursor solves: confirmations happen on the page. Context (tokens used) waits for usage data on the stream. Chain of Thought, Task, Plan and Checkpoint are good follow-ups for multi-step runs.

Build your own with useAgentChat

useAgentChat({ adapters, agent }) returns what a useChat consumer expects, plus what a plain UIMessage cannot say. Its reference page has a complete component; this is the shape.

You get What it is
messages The conversation as AI SDK UI messages: text, reasoning and dynamic-tool parts with AI SDK states.
status "ready", "submitted", "streaming" or "error".
sendMessage, stop, regenerate, clear Drive it. regenerate resumes an interrupted turn from its last finished tool call.
toolPhase(part) What UIMessage cannot say about a tool part: { phase, prompt?, agent? }.
adapters, adapter, selectAdapter, adapterStatus, prepare The adapter switcher and the adapter’s state; prepare starts an on-device model’s download from the person’s click.
models, selectModel, suggestions, tools The local models, the starter prompts, and the tools the model sees.

Every AI SDK component that reads UIMessage parts works as is. The two things UIMessage cannot say come from toolPhase(part): a call parked on the page (phase: "parked", with the prompt to show) and a sub-agent’s nested run (agent: { id, messages }, the nested run as UIMessages). phase is "running", "parked", "done", "error" or "cancelled".

Coming from ai-elements

If your project has the old components/ai-elements/* files, they keep working; shadcn/ui’s page lists the mapping (conversation.tsx to Chat, tool.tsx to Tool, agent.tsx to Subagent, and so on). The blocks here target the new names.

Reference

useAgentChat, <AgentChat> (the built-in widget).

Was this page helpful?