@ frontmcp/ ui (英语)
@frontmcp/ui 是 FrontMCP 部件的回放一面: UI 是一个在像 ChatGPT 或 Claude 这样的 AI 主机内显示的工具 。 您将一个部件写为反应组件, 并指定工具的 ui.template at it; FrontMCP 将文件捆绑并包入 McpBridgeProvider 并挂载它与呼叫的数据。 这个软件包给通过主机读取调用和调用工具的组件钩子,基于MUI(Matrial UI)的11个组件,一个主题,以及图表,PDF,地图和图表等内容的渲染器. 作为 HTML 模板编写的部件不需要它(带有 UI 的工具) (中文(简体) ). 要制作一个代理可以驱动,使用的反应应用程序 @frontmcp/react 换句话说.
安装
npm install @frontmcp/ui react react-dom @mui/material @emotion/react @emotion/styled
- 对于部件文件,请在服务器的项目中安装它, 即使部件没有导入它: 代码 FrontMCP 添加以挂载部件文件导入
McpBridgeProvider从@frontmcp/ui/react。 。 。 . - 所需要的同行是:
react财务报告和审定财务报表react-dom18或19岁,@mui/material7、8或9,以及@emotion/react财务报告和审定财务报表@emotion/styled11. npm 7, 后与包件一同安装@types/react财务报告和审定财务报表@types/react-dom。 。 。 . - FrontMCP 组合部件文件
esbuild,可选的对等点@frontmcp/uipack没有什么可以为你安装。 一个来自frontmcp create有它; 其他任何地方,运行npm install esbuild并保持它的依赖性,而不是dev的依赖性,因为工具被调用时它被加载了. - 服务器需要节点.js 24或后.
渲染器的可选同伴
渲染器的库是可选的同位素,没有安装软件包 :
| 渲染器 | 入境点 | 可选同伴 |
|---|---|---|
| 图表 | @frontmcp/ui/renderer/charts | recharts |
| 专题报告 | @frontmcp/ui/renderer/pdf | react-pdf, (中文(简体) ), pdfjs-dist |
| 流程图 | @frontmcp/ui/renderer/flow | @xyflow/react |
| 地图 | @frontmcp/ui/renderer/maps | react-leaflet, (中文(简体) ), leaflet |
| 美人鱼图 | @frontmcp/ui/renderer/mermaid | mermaid |
| 数学 | @frontmcp/ui/renderer/math | katex |
| 视频和音频 | @frontmcp/ui/renderer/media | react-player |
| 马克德和MDX | @frontmcp/ui/renderer/mdx | react-markdown, (中文(简体) ), remark-gfm, (中文(简体) ), rehype-highlight, (中文(简体) ), rehype-raw |
| HTML 语言 | @frontmcp/ui/renderer/html | dompurify; 没有它, HTML 将显示已逃出 |
| CSV,图像,反应JSX | /renderer/csv, (中文(简体) ), /renderer/image, (中文(简体) ), /renderer/react | 无。 JSX由Babel编译,由esm.sh装入. |
每个渲染器在运行时加载其库,这是它第一次制作:根据页面可以解析的软件包名称(在节点下安装的端口或dev服务器,或导入地图),或者从其它角度 esm.sh (英语) 在浏览器中。 地图、数学和流图以及PDF.js工人的样式表总是来自esm.sh.
使用量
指着工具 ui.template 绝对路径的部件文件 :
import { join } from 'node:path';
import { Tool, ToolContext, z } from '@frontmcp/sdk';
@Tool({
name: 'get_weather',
description: 'Current weather for a city',
inputSchema: { city: z.string() },
outputSchema: { city: z.string(), tempC: z.number(), conditions: z.string() },
ui: { template: { file: join(__dirname, 'weather.widget.tsx') } },
})
export class GetWeather extends ToolContext {
async execute({ city }: { city: string }) {
return { city, tempC: 21, conditions: 'Sunny' };
}
}
导出组件为默认 weather.widget.tsx数字 :
import { Badge, Card } from '@frontmcp/ui/components';
import { FrontMcpThemeProvider } from '@frontmcp/ui/theme';
type Weather = { city: string; tempC: number; conditions: string };
export default function WeatherWidget({ output }: { output: Weather | null }) {
if (!output?.city) return <p>Loading…</p>;
return (
<FrontMcpThemeProvider>
<Card title={output.city} subtitle="Current weather">
<p>{output.tempC}°C</p>
<Badge label={output.conditions} variant="success" />
</Card>
</FrontMcpThemeProvider>
);
}
部件得到三个道具: output, (中文(简体) ), input 财务报告和审定财务报表 loading。检查需要的字段,比如 output?.city,而不是为了 output:一个失败的结果的错误文本也是真实的 。 在 ES 模块服务器中,使用 join(import.meta.dirname, 'weather.widget.tsx')名称部件文件 *.widget.tsx 让他们离开服务器 tsc 建造; frontmcp build 复制到其输出中. 构建部件文件 覆盖相对路径, resourceMode 和每个主机得到的.
从部件调用工具
import { useCallTool } from '@frontmcp/ui/react';
type Weather = { city: string; tempC: number };
export default function Refreshable({ output }: { output: Weather | null }) {
const [refresh, { data, loading, error }] = useCallTool<{ city: string }, Weather>('get_weather');
const weather = data?.structuredContent ?? (output?.city ? output : null);
return (
<div>
<p>{weather ? `${weather.city}: ${weather.tempC}°C` : 'No data yet'}</p>
<button disabled={loading} onClick={() => refresh({ city: 'Bergen' })}>
Bergen
</button>
{error && <p role="alert">{error.message}</p>}
</div>
);
}
useCallTool() 返回数组,而不是对象. call(args) 要求主机调用工具并用主机的全部结果解决,因此工具的输出在 data.structuredContent。一个失败的工具通常会随着 isError: true 内 data· ; error {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}是给那些不能打的电话的 Tool calls not supported on this platform (ext-apps) 从一个从未接过电话的东道主那里.
入境点
| 导入 | 里面有什么东西 |
|---|---|
@frontmcp/ui/react | McpBridgeProvider 和钩. @frontmcp/ui 也出口,与桥梁. |
@frontmcp/ui/components | 这11个组件。 每个都有自己的入口点 比如 @frontmcp/ui/components/Card。 。 。 . |
@frontmcp/ui/theme | FrontMcpThemeProvider, (中文(简体) ), createFrontMcpTheme, (中文(简体) ), defaultTheme, (中文(简体) ), darkTheme, (中文(简体) ), useFrontMcpTheme。 。 。 . |
@frontmcp/ui/renderer | ContentView, (中文(简体) ), renderContent, (中文(简体) ), detectContentType, (中文(简体) ), registerAllRenderers, (中文(简体) ), registerRenderer和每个渲染器。 每个渲染器也有自己的切入点; /renderer/common 有共享的帮助者. |
@frontmcp/ui/bridge | 桥梁作为一个阶级, FrontMcpBridge 财务报告和审定财务报表 createBridge()及其适配器和 generateBridgeIIFE(),对于页面 FrontMCP 不构建. |
@frontmcp/ui/runtime | detectContentType,以及 transpileJsx() 用它用的"贝贝"装载器. |
@frontmcp/ui/auth, (中文(简体) ), @frontmcp/ui/auth/vanilla | A 的组件和助手 自定义登录 UI; 数据 vanilla 条目没有反应. |
钩子
部件文件已经在里面 McpBridgeProvider。在提供者之外,钩子返回空值,并且 call() 失败 Bridge not initialized。 。 。 .
| 钩子 | 回返 |
|---|---|
useToolOutput<T>() | 呼叫的输出:嵌入到页面中的输出,然后每个结果主机发送. |
useToolInput<T>() | 唤作辩才. |
useStructuredContent<T>() | 这个 structuredContent 以显示寄件者所发送的结果;空到一个到达为止. |
useCallTool<In, Out>(name, options?) | [call, { data, loading, error, called }, reset]选项: onSuccess, (中文(简体) ), onError, (中文(简体) ), resetOnToolChange (默认) true) (中文(简体) ). |
useToolCalls({ key: toolName, ... }) | { key: { call, data, loading, error, reset }, ... }数字 : useCallTool 用于几种工具. |
useSendMessage() | [send(text), { loading, error, sent }]:在对话中添加一个消息,其中主机允许. |
useOpenLink() | open(url),通过主机. |
useTheme(), (中文(简体) ), useDisplayMode() | "light" 或者说 "dark",以及 "inline", (中文(简体) ), "fullscreen" 或者说 "pip",正如主办方报告的那样. |
useHostContext() | 主持人对自己说的话: { theme, displayMode, locale, userAgent, safeArea, viewport?, ... }。 。 。 . |
useCapability(name) | 主机能否做到这一点 name一样 "canCallTools"。 。 。 . false 直到主持人回答握手. |
useMcpBridge(), (中文(简体) ), useMcpBridgeContext() | 桥,和 { bridge, loading, error, ready, adapterId, capabilities, revision }。 。 。 . |
构成部分
@frontmcp/ui/components 是在MUI上构建的反应组件。 把它们放进去 FrontMcpThemeProvider。 。 。 .
| 构成部分 | 主要道具 | 渲染器 |
|---|---|---|
Button | variant (单位:千美元)primary, (中文(简体) ), secondary, (中文(简体) ), danger, (中文(简体) ), ghost, (中文(简体) ), size, (中文(简体) ), loading, (中文(简体) ), disabled, (中文(简体) ), onClick | 一个MUI Button· ; loading 增加一转相. |
Card | title, (中文(简体) ), subtitle, (中文(简体) ), headerActions, (中文(简体) ), footer, (中文(简体) ), elevation, (中文(简体) ), clickable, (中文(简体) ), slotProps | 一个MUI Card。 。 。 . |
Alert | severity, (中文(简体) ), title, (中文(简体) ), dismissible, (中文(简体) ), onDismiss, (中文(简体) ), icon | 一个MUI Alert。 。 。 . |
Badge | label (必须), variant, (中文(简体) ), size, (中文(简体) ), dot, (中文(简体) ), removable, (中文(简体) ), onRemove | 一个MUI Chip。 。 。 . |
Avatar | src, (中文(简体) ), alt, (中文(简体) ), size, (中文(简体) ), variant | 一个MUI Avatar。 。 。 . |
Modal | open 财务报告和审定财务报表 onClose (必须), title, (中文(简体) ), actions, (中文(简体) ), maxWidth, (中文(简体) ), slotProps | 一个MUI Dialog。 。 。 . |
Table | columns (单位:千美元){ key, label, align? }[], (中文(简体) ), rows, (中文(简体) ), size, (中文(简体) ), stickyHeader, (中文(简体) ), maxHeight | 一个MUI Table。 。 。 . |
TextField | label, (中文(简体) ), value, (中文(简体) ), onChange(value), (中文(简体) ), type, (中文(简体) ), multiline, (中文(简体) ), error, (中文(简体) ), helperText | 一个MUI TextField· ; onChange 得到价值. |
Select | options (单位:千美元){ value, label }[], (中文(简体) ), label, (中文(简体) ), value, (中文(简体) ), onChange(value) | MUI 选择字段 . |
List | items (单位:千美元){ id, primary, secondary?, icon?, onClick?, divider? }[], (中文(简体) ), dense | 一个MUI List。 。 。 . |
Loader | variant (单位:千美元)spinner, (中文(简体) ), bar, (中文(简体) ), skeleton, (中文(简体) ), overlay, (中文(简体) ), label, (中文(简体) ), determinate, (中文(简体) ), value | 一个旋转器,进步栏,骨架或背景. |
LoaderProvider 替换每 Loader 在它下,你自己的制造功能。 主题来自 createFrontMcpTheme({ palette?, typography?, shape?, mode? }),或现成 defaultTheme 财务报告和审定财务报表 darkTheme,转至 FrontMcpThemeProvider 作为 theme。 。 。 .
渲染器
import { ContentView, registerAllRenderers } from '@frontmcp/ui/renderer';
registerAllRenderers();
export function Report({ content }: { content: string }) {
return <ContentView content={content} />;
}
ContentView 检测字符串中的内容类型, 如 CSV、 美人鱼图、 图表的 JSON 或图像 URL , 并将其与匹配的渲染器相接, 包裹在 Suspense。 。 。 . renderContent(content, options?) 在没有 Suspense 边界,和 detectContentType(content) 只有名字的种类。 当多个渲染器相匹配时,更高的优先级获胜,依此顺序为:pdf,图,流,图,美人鱼,数学,图像,视频,音频,csv,jsx,mdx,html. registerRenderer() 自己加进去 { type, priority?, canHandle(content), render(content, options?) }。 。 。 .
文档
- 部件: 构建部件文件、道具、钩子、组件、主题和渲染器
- 用回放构建部件:分步骤指南
- 带有 UI 的工具: 模板或反应,以及部件如何服务
- 这个
ui选项: 工具部件、服务模式、内容安全政策的每个选项 - 主机和平台:每个主持人都得到什么, 和桥钩说话
相关软件包
@frontmcp/sdk: 服务器框架; 工具的ui选项来自它.@frontmcp/uipack: 创建服务器上每个部件页面的无反动核心html模板帮助.@frontmcp/testing: 测试助手, 并配对工具制成的部件 .@frontmcp/react:用于在React app内部运行FrontMCP服务器的钩和组件.
捐款
资料来源: libs/ui欢迎提出问题和拉动请求;见 捐款额。 。 。 .
源代码下每个输入点有一个文件夹 src/数字 : react/ (供应商和钩子), components/ (每个部件一个文件夹), theme/, (中文(简体) ), renderer/ (每个渲染器一个文件夹,加 common/, (中文(简体) ), bridge/ (适应器、登记和桥梁类), runtime/ (内容检测和 Babel 加载器)和 auth/。服务器在每个页面中的桥接脚本来自 @frontmcp/uipack在单曲中:
nx build ui
nx test ui
nx lint ui
许可证
阿帕奇2.0 (英语). 见 自由主义。 。 。 .