关于 react-mcp
面向 React 浏览器应用的包,可连接预设及用户添加的 Streamable HTTP MCP 服务,并管理状态、将已连接工具注册到 assistant-ui 的 model context。
主要功能
- 01管理预设和自定义服务
- 02持久化服务及认证状态
- 03将已连接工具注册到模型上下文
- 04列出并读取资源
- 05支持 elicitation 和 OAuth 认证
适用场景
- 01在 React 应用中添加用户管理的 MCP 服务
- 02将已连接服务的工具提供给聊天运行时
- 03构建服务设置和配置界面
MCP 相关
从浏览器连接 Streamable HTTP MCP 服务,支持工具列举与调用、资源列举与读取、elicitation、PKCE 和 DCR OAuth、Bearer 或无认证,以及手动连接管理。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ assistant-ui/ skills --skill react-mcp安装后在 Claude Code 中输入/react-mcp确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/oauth.mdsetup.mdui.md详细介绍
assistant-ui React MCP
请始终查阅 assistant-ui.com/llms.txt,以获取最新 API。
@assistant-ui/react-mcp 让用户能够在浏览器中连接预设或自定义的 Streamable HTTP MCP 服务。管理器会持久化服务和身份验证状态,向原语公开连接状态,并将每个已连接的工具注册到 modelContext 中,作为名为 serverId__toolName 的前端工具。
参考文档
- ./references/setup.md -- 管理器配置、存储、状态、命令式方法和资源读取
- ./references/ui.md -- 复制的配置对话框,以及所有管理器、服务和添加表单原语
- ./references/oauth.md -- 身份验证结构、OAuth 回调处理、CIMD 和连接状态
挂载管理器
使用 defineConnector 声明固定连接器,然后通过配置扩展最近的 aui 作用域。connectionTimeout 是以毫秒为单位的管理器默认值。连接器或自定义服务可以为自身的连接和 listTools() 就绪流程覆盖此值。
"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>
);
}
连接器是应用预设,无法移除。用户可通过 McpAddFormPrimitive 或 aui.mcp.addCustomServer(...) 提供自定义服务。这两种类型共用状态、存储、引导请求和工具注册路径。有关管理器选项和存储生命周期规则,请参阅设置。
前端工具调用后继续运行
管理器会自动注册已连接的工具。聊天运行时仍需将已完成的前端工具结果发送到路由,以便模型继续运行。
"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>;
}
如果没有聊天运行时提供 modelContext,管理器会挂载一个最精简的实例。在事件处理程序中直接调用工具时,请使用 aui.mcp.server({ id }).callTool(...)。
使用配置 UI
使用 npx assistant-ui@latest add mcp-config 安装带样式的对话框。它是一个复制的运行时连接元素,因此请从 @/components/assistant-ui/elements/mcp-config.aui 导入,并在管理器提供程序下渲染。
import { McpConfigDialog } from "@/components/assistant-ui/elements/mcp-config.aui";
export function ServerSettings() {
return <McpConfigDialog />;
}
将元素作为 children 传入,即可替换默认触发器。对于设置页面、侧边栏或自定义添加流程,请组合使用 UI 中的无头原语。
渲染引导请求
MCP 服务可以在工具调用进行期间请求结构化输入。请在与已连接服务相同的 mcpServer 作用域中渲染 Items。在连接器或自定义服务上设置 elicitation: false,即可选择不使用此协议能力。
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>
);
}
每次请求都会向渲染函数提供独立的活动请求。有效的数字字符串会被强制转换为数字,而布尔字段必须设置为布尔值。除非枚举成员或默认值允许空字符串,否则空字符串会被视为未回答,因此请将枚举属性渲染为选择框。缺少必填字段或值无效时,Accept 会保持禁用状态。
v1 范围
此软件包支持工具列表和调用、资源列表和读取、表单引导、带 PKCE 和 DCR 的 OAuth、Bearer 身份验证和无身份验证、Streamable HTTP 传输,以及手动连接或断开连接。提示词、采样、带退避机制的自动重连、按工具持久化启用状态、按工具征得同意,以及内置令牌加密暂不支持。
常见注意事项
工具无法传递给模型
- 服务必须处于
connected状态。工具的名称是serverId__toolName,而不只是 MCP 工具名称。 - 在
useChatRuntime上配置sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls,这样前端工具调用完成后就会恢复模型运行。
OAuth 回调失败或始终无法完成
- 回调路由必须与
oauthRedirectUri完全匹配,并在管理器提供程序下渲染McpOAuthCallback。 - 如果 CIMD 授权服务器没有注册端点,则需要静态 OAuth
clientId。
服务器状态在用户之间泄漏,或更换存储后记录丢失
McpLocalStorage()仅限浏览器使用,并以纯文本形式存储令牌。生产环境的身份验证状态应使用由仅 HTTP Cookie 支持的McpCustomStorage。- 不要为其他用户更换
storage。请重新挂载管理器,因为自定义服务器记录只会进行一次初始化。请参阅存储标识。
引导表单一直为空
- 如果没有待处理请求,
Items不会渲染任何内容;它还需要匹配的服务器作用域。请确认服务器已连接,且未设置elicitation: false。
资源浏览器在第一页后停止
- 将每次返回的
nextCursor传递给listResources({ cursor }),直到该值不存在;然后对选定项调用readResource(uri)。