
react-mcp
Adds user managed browser MCP servers to assistant-ui with @assistant-ui/react-mcp. Use when mounting McpManagerResource, declaring defineConnector presets, persisting custom servers and OAuth state, composing McpManagerPrimitive, McpServerPrimitive, McpAddFormPrimitive, or McpElicitationPrimitive, handling an OAuth callback, browsing MCP resources, or diagnosing missing server tools, connection failures, and OAuth redirects. This covers end user chosen servers, not application owned backend MCP tools. For those use tools; for the chat runtime use runtime; for the copied dialog use elements.
- Installs
- 4K
- Last 24h
- +11
- Trending rank
- #8527
- Security
- Warn
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/assistant-ui/skills --skill react-mcp- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads react-mcp automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
Security audits
Independent scans of the skill's instructions and bundled files.
SKILL.md
The instructions your agent reads when the skill is triggered.
assistant-ui React MCP
Always consult assistant-ui.com/llms.txt for the latest API.
@assistant-ui/react-mcp lets users connect preset or custom Streamable HTTP MCP servers in the browser. The manager persists server and auth state, exposes connection state to primitives, and registers each connected tool into modelContext as a frontend tool named serverId__toolName.
References
- ./references/setup.md -- manager configuration, storage, state, imperative methods, and resource reads
- ./references/ui.md -- the copied configuration dialog and every manager, server, and add form primitive
- ./references/oauth.md -- auth shapes, OAuth callback handling, CIMD, and connection states
Mount the manager
Declare fixed connectors with defineConnector, then extend the nearest aui scope with a config. connectionTimeout is a manager default in milliseconds. A connector or custom server can override it for its own connect and listTools() readiness flow.
"use client";
import type { ReactNode } from "react";
import { AuiConfig, AuiProvider, useAui } from "@assistant-ui/react";
import { McpManagerResource, defineConnector } from "@assistant-ui/react-mcp";
const connectors = [
defineConnector({
id: "linear",
name: "Linear",
url: "https://mcp.linear.app",
auth: { type: "oauth", scopes: ["read"] },
icon: "/icons/linear.svg",
}),
defineConnector({
id: "weather",
name: "Weather",
url: "https://mcp.example.com/weather",
auth: { type: "none" },
connectionTimeout: 10_000,
}),
];
export function Providers({ children }: { children: ReactNode }) {
const aui = useAui();
const config = AuiConfig({
mcp: McpManagerResource({
connectors,
connectionTimeout: 15_000,
}),
});
return (
<AuiProvider extends={aui} config={config}>
{children}
</AuiProvider>
);
}
Connectors are application presets and cannot be removed. A custom server is user supplied through McpAddFormPrimitive or aui.mcp.addCustomServer(...). Both kinds share state, storage, elicitation, and the tool registration path. See setup for manager options and storage lifetime rules.
Continue after frontend tool calls
The manager registers connected tools automatically. A chat runtime still needs to send completed frontend tool results to the route so the model can continue.
"use client";
import type { ReactNode } from "react";
import { lastAssistantMessageIsCompleteWithToolCalls } from "ai";
import { AssistantRuntimeProvider } from "@assistant-ui/react";
import { useChatRuntime } from "@assistant-ui/ai-sdk";
export function Chat({ children }: { children: ReactNode }) {
const runtime = useChatRuntime({
sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls,
});
return <AssistantRuntimeProvider runtime={runtime}>{children}</AssistantRuntimeProvider>;
}
If no chat runtime provides modelContext, the manager mounts a minimal one. Use aui.mcp.server({ id }).callTool(...) for a direct call in an event handler.
Use the configuration UI
Install the styled dialog with npx assistant-ui@latest add mcp-config. It is a copied runtime connected element, so import it from @/components/assistant-ui/elements/mcp-config.aui and render it under the manager provider.
import { McpConfigDialog } from "@/components/assistant-ui/elements/mcp-config.aui";
export function ServerSettings() {
return <McpConfigDialog />;
}
Pass an element as children to replace its default trigger. For a settings page, sidebar, or custom add flow, compose the headless primitives in ui.
Render elicitation requests
An MCP server can request structured input while a tool call is in flight. Render Items in the same mcpServer scope as the connected server. Set elicitation: false on a connector or custom server to opt it out of the protocol capability.
import { McpElicitationPrimitive } from "@assistant-ui/react-mcp";
type FieldSchema = {
type?: string;
enum?: readonly string[];
};
export function ElicitationRequests() {
return (
<McpElicitationPrimitive.Items>
{() => (
<McpElicitationPrimitive.Root>
<McpElicitationPrimitive.Message />
<McpElicitationPrimitive.Error />
<McpElicitationPrimitive.Fields>
{({ name, schema, value, setValue }) => {
const field = schema as FieldSchema;
if (field.type === "boolean") {
return (
<label>
{name}
<input
type="checkbox"
checked={value === true}
onChange={(event) => setValue(event.target.checked)}
/>
</label>
);
}
if (field.enum) {
return (
<label>
{name}
<select
value={typeof value === "string" ? value : ""}
onChange={(event) => setValue(event.target.value)}
>
{!field.enum.includes("") && <option value="">Select {name}</option>}
{field.enum.map((option) => (
<option key={option} value={option}>
{option}
</option>
))}
</select>
</label>
);
}
return (
<label>
{name}
<input
value={typeof value === "string" || typeof value === "number" ? String(value) : ""}
onChange={(event) => setValue(event.target.value)}
/>
</label>
);
}}
</McpElicitationPrimitive.Fields>
<McpElicitationPrimitive.Accept>Submit</McpElicitationPrimitive.Accept>
<McpElicitationPrimitive.Decline>Decline</McpElicitationPrimitive.Decline>
<McpElicitationPrimitive.Cancel>Cancel</McpElicitationPrimitive.Cancel>
</McpElicitationPrimitive.Root>
)}
</McpElicitationPrimitive.Items>
);
}
The render function receives a separate active request each time. Numeric strings are coerced when valid, while boolean fields must set a boolean. An empty string is unanswered unless the property allows it through an enum member or default, so render enum properties as a select. Accept remains disabled for missing required fields and invalid values.
v1 scope
This package ships tool listing and invocation, resource listing and reads, form elicitation, OAuth with PKCE and DCR, bearer and no auth, Streamable HTTP transport, and manual connect or disconnect. Prompts, sampling, automatic reconnect with backoff, persisted per tool enablement, per tool consent, and built in token encryption are deferred.
Common Gotchas
Tools never reach the model
- The server must be
connected. Its tools are namedserverId__toolName, not just the MCP tool name. - Configure
sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCallsonuseChatRuntimeso completed frontend tool calls resume the model.
OAuth callback fails or never completes
- The callback route must exactly match
oauthRedirectUriand renderMcpOAuthCallbackbeneath the manager provider. - A CIMD only authorization server without a registration endpoint needs a static OAuth
clientId.
Server state leaks across users or a storage swap loses records
McpLocalStorage()is browser only and stores tokens in plain text. Use an HTTP only cookie backedMcpCustomStoragefor production auth state.- Do not swap
storagefor another user. Remount the manager because custom server records hydrate only once. See storage identity.
An elicitation form stays blank
Itemsrenders nothing without pending requests and requires the matching server scope. Confirm that the server is connected and has not setelicitation: false.
A resource browser stops after the first page
- Pass each returned
nextCursortolistResources({ cursor })until it is absent, then callreadResource(uri)for a selected item.
Related Skills
- tools -- developer owned frontend and backend tools that complement user managed MCP servers
- setup -- CLI setup and the
mcpproject template - runtime --
useChatRuntimeand runtime provider configuration - elements -- installing and modifying the copied
mcp-configelement
FAQ
What does the react-mcp skill do?
Adds user managed browser MCP servers to assistant-ui with @assistant-ui/react-mcp. Use when mounting McpManagerResource, declaring defineConnector presets, persisting custom servers and OAuth state, composing McpManagerPrimitive, McpServerPrimitive, McpAddFormPrimitive, or McpElicitationPrimitive, handling an OAuth callback, browsing MCP resources, or diagnosing missing server tools, connection failures, and OAuth redirects. This covers end user chosen servers, not application owned backend MCP tools. For those use tools; for the chat runtime use runtime; for the copied dialog use elements.
How do I install react-mcp?
Run npx skills add https://github.com/assistant-ui/skills --skill react-mcp in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/react-mcp/ (personal) or .claude/skills/react-mcp/ (project).
Which AI agents can use react-mcp?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is react-mcp safe to install?
Security partners have reviewed it: Gen Agent Trust Hub passed; Socket passed; Snyk flagged items to review. As with any skill, read the SKILL.md and bundled scripts before installing.
Who maintains react-mcp?
It is published by assistant-ui in assistant-ui/skills. It has 3,982 recorded installs.
More from assistant-ui/skills
assistant-ui
assistant-ui/skills
Overview and router for assistant-ui, the React library for building AI chat interfaces from composable primitives and a styled elements catalog. Use for high-level, cross-cutting, or architecture questions: choosing packages, picking a runtime, or understanding the layers (elements, primitives, the aui client with AuiConfig and AuiProvider, the runtime, adapters) and the message model. Covers @assistant-ui/react 0.15.x, @assistant-ui/ai-sdk for AI SDK v7 (useChatRuntime), @assistant-ui/core, @assistant-ui/store, assistant-stream, assistant-cloud, the LangGraph, LangChain, Google ADK, A2A, AG-UI, Eve, OpenCode, and Pi adapters, the @assistant-ui/react-native and @assistant-ui/react-ink bindings, and the useAui, useAuiState, and useAuiEvent hooks. For a specific area route to a focused sibling instead: setup, elements, primitives, runtime, tools, generative-ui, streaming, cloud, thread-list, copilots, markdown, react-mcp, observability, react-native, ink, or upda
streaming
assistant-ui/skills
Streaming wire protocols and backend helpers for assistant-ui, built on the assistant-stream package. Use when building a custom streaming endpoint outside the Vercel AI SDK with createAssistantStreamResponse, createAssistantStream, or createAssistantStreamController; choosing between the Data Stream protocol (useDataStreamRuntime, DataStreamEncoder, DataStreamDecoder) and the Assistant Transport protocol (AssistantTransportEncoder, AssistantTransportDecoder); decoding a response with AssistantStream.fromResponse, UIMessageStreamDecoder, or PlainTextDecoder; or wiring resumable streams through assistant-stream/resumable with in-memory, Redis, or ioredis stores. Route here for wire level symptoms: an unexpected part-start or text-delta shape, a tool call that never settles, a part that silently drops, a Content-Type mismatch, or a reload that cannot resume a response. For runtime hooks use runtime; for AI SDK route handlers without a custom protocol use setup; for cloud persistence use
tools
assistant-ui/skills
Defines model-callable tools and renders their calls in assistant-ui. The authoring model: a "use generative" file whose default export is defineToolkit({...}), compiled by withAui from @assistant-ui/next, aui() from @assistant-ui/vite, or withAui from @assistant-ui/metro, mounted with AuiConfig({ tools: Tools({ toolkit }) }), and exposed to the model with new AISDKToolkit({ toolkit }).tools({ frontend }). Covers the tool kinds (backend, "use client" frontend, humanTool(), providerTool(), externalTool(), stubTool(), defineMcpToolkit()), render and display, ToolCallMessagePartProps, approval gates, MCP servers, MCP Apps, WebMCP, and sub-agent messages. Reach for it when a tool is never called, a tool UI does not render, a frontend result never reaches the model, humanTool() throws at runtime, or an approval gate cannot be answered. For model-composed UI use generative-ui, for MCP servers users add in the browser use react-mcp, and for the styled ToolFallback and ToolGroup use elements.
primitives
assistant-ui/skills
Builds and customizes assistant-ui chat UI from composable, unstyled @assistant-ui/react primitives: ThreadPrimitive, ComposerPrimitive (with UnstableTriggerPopover for mentions and slash commands), MessagePrimitive and MessagePartPrimitive, ActionBarPrimitive, BranchPickerPrimitive, AttachmentPrimitive, ErrorPrimitive, AssistantModalPrimitive, ChainOfThoughtPrimitive, SelectionToolbarPrimitive, SuggestionPrimitive, QueueItemPrimitive, and the ThreadList primitives. Use when assembling or styling a custom Thread, Composer, message list, action bar, branch picker, or suggestion grid; wiring composer input, dictation, quoting, or attachments; or handling editing, branching, virtualization, scrolling, or chain of thought UI. Covers MessagePrimitive.Parts render functions per part type, groupPartByType, AuiIf in selector form, and the unstyled gotchas (AssistantRuntimeProvider, className). For prebuilt UI use setup, for the styled catalog use elements, for multi-thread sidebars use thread
runtime
assistant-ui/skills
Guide to the assistant-ui runtime system, the state and action layer behind every chat surface. Use when creating a runtime (useLocalRuntime with a ChatModelAdapter, useExternalStoreRuntime for Redux or Zustand backed stores, useRemoteThreadListRuntime, useCloudThreadListRuntime, useAssistantTransportRuntime), wiring AssistantRuntimeProvider, or reading and mutating thread, message, composer, and attachment state. Covers useAui, useAuiState, and useAuiEvent with the stable selector rule, the scope accessors (aui.thread, aui.message, aui.composer, and siblings), the AuiConfig plus AuiProvider grammar, RuntimeCapabilities, and the attachment, speech, dictation, feedback, suggestion, and history adapters. Route here for a provider error ('Cannot read property of undefined'), a removed v0.12 hook import, an infinite re-render from an object literal selector, or state not updating. For multi-thread list UI use thread-list instead; for toolkit definitions and tool call UI use tools instead.
thread-list
assistant-ui/skills
Builds and customizes multiple conversation lists in assistant-ui with the runtime connected ThreadList and ThreadListSidebar elements, ThreadListPrimitive, ThreadListItemPrimitive, ThreadListItemMorePrimitive, useAui, useAuiState, and threads.selectionChanged. Use when adding a conversation sidebar, switching, archiving, renaming, deleting, searching, grouping, paginating, or persisting threads, or when thread state is stale after authentication. Covers AssistantCloud, RemoteThreadListRuntime, and ExternalStoreThreadListAdapter. Use runtime for the active conversation runtime, cloud for managed authentication and persistence, and elements for registry installation and styling.
Popular frontend & design skills
setup-matt-pocock-skills
mattpocock/skills
Configure this repo for the engineering skills: set up its issue tracker, triage label vocabulary, and domain doc layout. Run once before first use of the other engineering skills.
frontend-design
anthropics/skills
Guidance for distinctive, intentional visual design when building new UI or reshaping an existing one. Helps with aesthetic direction, typography, and making choices that don't read as templated defaults.
hyperframes-animation
heygen-com/hyperframes
All animation knowledge for HyperFrames — atomic motion rules, multi-phase scene blueprints, scene transitions, broader motion-design techniques, AND the seven runtime adapters (GSAP default, plus Lottie, Three.js, Anime.js, CSS keyframes, Web Animations API, TypeGPU). Use for any motion or animation task: pick 2-4 rules and compose, or load a blueprint, or look up runtime-specific API (e.g. GSAP eases / Lottie player / Three.js mixer). Also covers auditing an existing composition's choreography (animation map) and 24 named text-animation effects. HyperFrames-native: single paused timeline, seek-safe, deterministic.
prototype
mattpocock/skills
Build a throwaway prototype to answer a design question. Use when the user wants to sanity-check whether a state model or logic feels right, or explore what a UI should look like.
hyperframes-core
heygen-com/hyperframes
The HyperFrames composition contract — build one renderable project. Use for composition structure, the data- timing attributes, class="clip", tracks, sub-compositions, variables, framework-owned media playback, deterministic-render rules, and validation. Read before writing composition HTML.
vercel-react-best-practices
vercel-labs/agent-skills
React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.