mcpField
R
react-mcp

react-mcp

github.com/assistant-ui开发294.0k 次安装1 天前更新
代码仓库

关于 react-mcp

面向 React 浏览器应用的包,可连接预设及用户添加的 Streamable HTTP MCP 服务,并管理状态、将已连接工具注册到 assistant-ui 的 model context。

主要功能

  1. 01管理预设和自定义服务
  2. 02持久化服务及认证状态
  3. 03将已连接工具注册到模型上下文
  4. 04列出并读取资源
  5. 05支持 elicitation 和 OAuth 认证

适用场景

  1. 01在 React 应用中添加用户管理的 MCP 服务
  2. 02将已连接服务的工具提供给聊天运行时
  3. 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.md
setup.md
ui.md

详细介绍

assistant-ui React MCP

请始终查阅 assistant-ui.com/llms.txt,以获取最新 API。

@assistant-ui/react-mcp 让用户能够在浏览器中连接预设或自定义的 Streamable HTTP MCP 服务。管理器会持久化服务和身份验证状态,向原语公开连接状态,并将每个已连接的工具注册到 modelContext 中,作为名为 serverId__toolName 的前端工具。

参考文档

挂载管理器

使用 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)。

相关技能

  • tools -- 由开发者管理、可与用户管理的 MCP 服务互补的前端和后端工具
  • setup -- CLI 设置和 mcp 项目模板
  • runtime -- useChatRuntime 和运行时提供程序配置
  • elements -- 安装和修改复制而来的 mcp-config 元素

评论

支持 Markdown