@frontmcp/uipack

中文文档
1.12.2发布于 2026/11/15Apache-2.0TypeScriptESM + CJS构建来源已验证近 30 天下载 1.4万

构建 FrontMCP 部件页面的无反射核心: HTML shell 有 CSP 和 Bridge, 模板渲染, CDN 导入分辨率

中文使用文档
文档目录19 节
  1. 安装
  2. 使用量
  3. 围绕自己的标记建立一页
  4. 解决对 CDN URL 的导入
  5. 从 npm 生成组件
  6. 生成桥脚本
  7. 获取类型脚本定义
  8. 入境点
  9. 适配器
  10. 贝壳
  11. 解析器
  12. 构成部分
  13. 桥梁运行时间
  14. 键入
  15. 用户
  16. 文档
  17. 相关软件包
  18. 捐款
  19. 许可证

@ frontmcp/ 邮包

@frontmcp/uipack 是 FrontMCP 创建部件页面的无反应核心,在服务器上。 它使一个工具的模板变成一个完整的HTML页面,其中包含内容安全政策,调用的数据和与主机交谈的桥接脚本;解决部件导入到CDN URL;并捆绑回放部件文件. @frontmcp/sdk 取决于它,所以FrontMCP服务器已经拥有了它. 将模板分割为函数 html,测试没有服务器的模板 renderToolTemplate(),或为您自己的一个主机构建部件页面.

npm License

安装

npm install @frontmcp/uipack
  • 无反应依赖. 运行时间依赖是 zod 财务报告和审定财务报表 entities (HTML 字符引用解码器) sanitizeHtml() ; npm 7 并随后安装对等点 @frontmcp/lazy-zod,在同一版本中.
  • esbuild 是一个可选的对等点, 只需要捆绑 .tsx 财务报告和审定财务报表 .jsx 部件文件 。 安装它作为依赖性,而不是 dev 依赖性,因为它在部件被渲染时被装入.
  • highlight.js 是一个可选的同伴,仅需要用于 markdown.highlightTheme (单位:千美元)ui.runtimeOptions.markdown.highlightTheme) (中文(简体) ). 当一个模板使用时,它会从您的项目中被载入.
  • @mdx-js/mdx, (中文(简体) ), react 财务报告和审定财务报表 react-dom 是可选的同位素,仅用于制作MDX模板(mdxComponents在服务器上,和 remark-gfm 给一个 markdown.gfm。 。 。 . react 财务报告和审定财务报表 react-dom 也可以在服务器上渲染一个组件(uiType: 'react'和一个水合(水合)部件hydrate) (中文(简体) ). 它们是从你的工程中加载的, 所以模板的组件和渲染器共享一个反应.
  • 它运行在节点.js24或后.

使用量

以工具调用的方式制作一个模板, 没有服务器 :

import { html, renderToolTemplate, type TemplateContext } from '@frontmcp/uipack';

type Weather = { city: string; tempC: number };

const badge = (text: string) => html`<span class="badge">${text}</span>`;

const result = renderToolTemplate({
  toolName: 'get_weather',
  input: { city: 'Oslo' },
  output: { city: 'Oslo', tempC: 21 },
  template: (ctx: TemplateContext<{ city: string }, Weather>) =>
    html`<h2>${ctx.output.city} ${badge(`${ctx.output.tempC}°C`)}</h2>`,
});

result.html 是一个完整的 HTML 文档,其正文是 <h2>Oslo <span class="badge">21°C</span></h2>, (中文(简体) ), result.uiType 实值 "html",以及 result.meta["ui/mimeType"] 实值 "text/html;profile=mcp-app"内插值 html 被逃脱,所以一个城市 <script> 作为 &lt;script&gt;; 使用 html 或者说 trustedHtml() 没逃过两次. html 与工具模板的构建器相同 ctx.helpers.html,因此部件的片段可以活在自己的文件中,并被自己测试(将模板分割为函数) (中文(简体) ).

围绕自己的标记建立一页

import { buildShell } from '@frontmcp/uipack/shell';

const { html, hash, size } = buildShell('<div id="root"></div>', {
  toolName: 'get_weather',
  input: { city: 'London' },
  output: { temp: 18 },
  includeBridge: true,
  csp: { connectDomains: ['https://api.weather.com'] },
});

hash 是一个短而非晶体散列的页面,用于缓存键,以及 size 其长度为字节。 页面看起来是这样,桥脚本缩短:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta
      http-equiv="Content-Security-Policy"
      content="default-src 'none'; script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net ... https://esm.sh; ... connect-src https://cdn.jsdelivr.net ... https://esm.sh https://api.weather.com; ..."
    />
    <script>
      window.__mcpAppsEnabled = true;
      window.__mcpToolName = 'get_weather';
      window.__mcpToolInput = { city: 'London' };
      window.__mcpToolOutput = { temp: 18 };
      window.__mcpStructuredContent = null;
    </script>
    <script>
      /* the bridge: picks an adapter for the host and sets window.FrontMcpBridge */
    </script>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

解决对 CDN URL 的导入

import { createEsmShResolver, rewriteImports } from '@frontmcp/uipack/resolver';

const resolver = createEsmShResolver({ providerOrder: ['cloudflare', 'jsdelivr'] });

resolver.resolve('chart.js');
// { value: 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.5.1/chart.umd.min.js', type: 'url' }

rewriteImports("import { format } from 'date-fns';", { resolver }).code;
// "import { format } from 'https://esm.sh/date-fns';"

CDN 登记册中的软件包(react, (中文(简体) ), react-dom, (中文(简体) ), chart.js, (中文(简体) ), d3, (中文(简体) ), lodash解决其注册的 URL, 并尝试提供商 providerOrder;任何其他软件包决定 https://esm.sh/<specifier>。 。 。 .

从 npm 生成组件

import { renderComponent } from '@frontmcp/uipack/component';

const { html } = renderComponent(
  { source: { npm: 'my-weather-widget', exportName: 'WeatherCard' } },
  { toolName: 'get_weather', output: { temp: 18 } },
);

renderComponent() 是同步的。 页面从 https://esm.sh/my-weather-widget,通过导入地图从 esm.sh 装入 React,使组件进入 #root 以工具的输出为道具. 来源可以是:

来源形状发生什么事
无{ npm: 'my-chart', exportName?, version? }从其CDN注册条目或esm.sh装入.
文件{ file: '/abs/path/widget.tsx', exportName?, inline? }一个本地文件. .tsx 财务报告和审定财务报表 .jsx 文件与 esbuilding 捆绑在一起; 从工作目录中解析一个相对路径.
导入{ import: 'https://cdn.example.com/widget.js', exportName? }模块 URL,按原样使用.
函数(input, output) => '<div>…</div>'返回 HTML.

生成桥脚本

import { BRIDGE_SCRIPT_TAGS, generateBridgeIIFE } from '@frontmcp/uipack/bridge-runtime';

const everyHost = BRIDGE_SCRIPT_TAGS.universal;
const openAiOnly = `<script>${generateBridgeIIFE({ adapters: ['openai', 'generic'], minify: true })}</script>`;

脚本检测主机和设定 window.FrontMcpBridge数字 :

成员说明
adapterId, (中文(简体) ), initialized, (中文(简体) ), capabilities适配器为宿主所选,是否已就绪,能作何事.
getToolInput(), (中文(简体) ), getToolOutput(), (中文(简体) ), getStructuredContent()呼叫的数据,从页面,然后从每个结果,主机发送.
callTool(name, args)通过主机调用一个工具并返回主机的结果 .
onToolResult(callback), (中文(简体) ), onContextChange(callback)订阅结果和主机更改。 每个返回一个未订阅的函数 .
getTheme(), (中文(简体) ), getDisplayMode(), (中文(简体) ), getHostContext(), (中文(简体) ), hasCapability(name)主持人对自己说的话.
sendMessage(text), (中文(简体) ), openLink(url)在对话中添加信息,打开链接,通过主机.
requestDisplayMode(mode), (中文(简体) ), setSize({ width?, height? }), (中文(简体) ), requestClose()问 inline, (中文(简体) ), fullscreen 或者说 pip,报告部件大小,请删除部件.
updateModelContext(data, merge?)告诉主机该知道什么,主机支持在哪里.
getWidgetState(), (中文(简体) ), setWidgetState(state)保持状态 localStorage。 。 。 .

获取类型脚本定义

import { createTypeFetcher } from '@frontmcp/uipack/typings';

const fetcher = createTypeFetcher({ allowedPackages: ['@myorg/*'], maxDepth: 3 });
const { results, errors } = await fetcher.fetchBatch({ imports: ["import { z } from 'zod'"] });
// results[0].files: the .d.ts files, at virtual node_modules/ paths

它会得到 .d.ts 从 esm.sh 导入的每个文件,在自导入之后一直到 maxDepth (默认2). 只获取允许的软件包 : react, (中文(简体) ), react-dom, (中文(简体) ), react/jsx-runtime, (中文(简体) ), zod 财务报告和审定财务报表 @frontmcp/*附加时 allowedPackages,或带有 allowedPackages: false。 。 。 .

入境点

@frontmcp/uipack 输出下面的一切。 每个单元也是自己的切入点:

导入里面有什么东西
@frontmcp/uipack/adaptersrenderToolTemplate(), (中文(简体) ), MCP_APPS_MIME_TYPE,而SDK用来构建工具部件响应的帮助者.
@frontmcp/uipack/shellbuildShell(), (中文(简体) ), html, (中文(简体) ), trustedHtml(),模板助手,CSP,自定义贝壳.
@frontmcp/uipack/resolver导入分辨率, CDN 注册, 导入地图 .
@frontmcp/uipack/componentrenderComponent() 和组件来源.
@frontmcp/uipack/bridge-runtime桥脚本生成器.
@frontmcp/uipack/typings这个 .d.ts 取取器及其缓存.
@frontmcp/uipack/types部件配置的类型, 如 UITemplateConfig 财务报告和审定财务报表 TemplateContext。 。 。 .
@frontmcp/uipack/utils出逃相助者.

适配器

导出说明
renderToolTemplate(options)以调用方式制作模板 : { html, uiType, hash, size, meta }选项: toolName, (中文(简体) ), input, (中文(简体) ), output, (中文(简体) ), template, (中文(简体) ), platformType?, (中文(简体) ), resourceMode?, (中文(简体) ), sizing?, (中文(简体) ), csp?, (中文(简体) ), escapeStringResults?, (中文(简体) ), contentSecurity? (对模板的标记进行卫生处理) sanitizeHtml(), (中文(简体) ), markdown? (单位:千美元){ gfm?, highlightTheme? } 用于Markdown或MDX模板, mdxComponents? (字符串模板是带有这些组件的服务器上渲染的MDX), uiType? (强迫渲染器: 'html', (中文(简体) ), 'markdown', (中文(简体) ), 'mdx', (中文(简体) ), 'react', (中文(简体) ), hydrate? (放弃a) { file } 服务器上的部件和水合物。 投出模板无法取用的选项; 在tsx下, await prepareRenderOptions() 在制作MDX之前.
describeRenderOptionProblems(template, options)为它无法取取的模板设定的渲染选项,每句一; [] 当没有.
MCP_APPS_MIME_TYPE"text/html;profile=mcp-app"。 。 。 .

贝壳

导出说明
buildShell(content, config)一页左右 content数字 : { html, hash, size }。 。 。 . config数字 : toolName (必须), input, (中文(简体) ), output, (中文(简体) ), structuredContent, (中文(简体) ), csp, (中文(简体) ), includeBridge (默认) true, (中文(简体) ), withShell (默认) true· ; false 返回只包含数据脚本和内容, title, (中文(简体) ), sizing, (中文(简体) ), displayMode, (中文(简体) ), customShell。 。 。 .
html`…`, (中文(简体) ), trustedHtml(markup), (中文(简体) ), isTrustedHtml(value)构建、标记和检测信任的标记。 内插值 html 被逃脱.
sanitizeHtml(markup, policy?)什麽 ui.contentSecurity 已经 它读取了标记,就像浏览器的标记器所做的一样,写出每个标记,每个属性值一次解码,检查后写回逃出. 它可以删除 <script>, (中文(简体) ), on* 处理者, srcdoc, (中文(简体) ), <object>编号 :<embed>编号 :<applet>, (中文(简体) ), <base>, (中文(简体) ), <meta>SVG动画, data-tool-call编号 :data-tool-args,注释,其方案不是 URL 属性 http:, (中文(简体) ), https: 或者说 mailto:, (中文(简体) ), @import 内 <style>,交叉来源 <link rel=stylesheet>,以及 position: fixed编号 :sticky 内 style 属性. policy数字 : allowInlineScripts, (中文(简体) ), allowUnsafeLinks, (中文(简体) ), allowToolCallAttributes, (中文(简体) ), bypassSanitization, (中文(简体) ), maxMarkupLength (默认) DEFAULT_MAX_MARKUP_LENGTH,2个小米字符;更长的打分投出. 线性时间.
describeContentSecurityProblems(policy)为什么一个值不能是一个 ui.contentSecurity 策略(不是平面对象,旗帜不是布尔,未知键),每个句子.
createTemplateHelpers()一组新的模板助手 : escapeHtml, (中文(简体) ), formatDate, (中文(简体) ), formatCurrency, (中文(简体) ), uniqueId, (中文(简体) ), jsonEmbed, (中文(简体) ), html, (中文(简体) ), trustedHtml。 。 。 .
buildCSPDirectives(csp?), (中文(简体) ), buildCSPMetaTag(csp?)页面政策:默认的 CDN 来源加 connectDomains 财务报告和审定财务报表 resourceDomains。 。 。 .
buildDataInjectionScript({ toolName, input?, output?, structuredContent?, sizing?, displayMode? })这个 <script> 设置 window.__mcpToolName, (中文(简体) ), __mcpToolInput, (中文(简体) ), __mcpToolOutput 财务报告和审定财务报表 __mcpStructuredContent。 。 。 .
resolveShellTemplate(source, options?)Async (英语). 装入自定义 shell 从 { inline }, (中文(简体) ), { url, timeout? } 或者说 { npm, exportName?, version? },并验证它.
validateShellTemplate(template), (中文(简体) ), applyShellTemplate(template, values)检查并填入自定义 shell 的占位符 : {{CONTENT}} (必须), {{CSP}}, (中文(简体) ), {{DATA}}, (中文(简体) ), {{BRIDGE}}, (中文(简体) ), {{TITLE}}。 。 。 .
DEFAULT_CDN_DOMAINS每个页面的出处允许:jsDelivr,cdnjs,Google字体和esm.sh.

解析器

导出说明
createEsmShResolver({ registry?, providerOrder?, fallbackCdnBase? })默认解析器 .
createResolverWithOverrides(overrides, options?)默认解析器, 某些软件包有固定的 URL .
DEFAULT_CDN_REGISTRY, (中文(简体) ), mergeRegistries(custom)登记处react, (中文(简体) ), react-dom, (中文(简体) ), chart.js, (中文(简体) ), d3, (中文(简体) ), lodash),它与您的条目合并.
lookupPackage(name, registry?), (中文(简体) ), getPackageCDNUrl(name, providerOrder?, registry?)查询注册.
parseImports(source), (中文(简体) ), extractExternalPackages(source)源代码中的导入,以及它们命名的包.
rewriteImports(source, { resolver?, skipPackages?, overrides? })用 CDN URL 替换光标: { code, rewrittenCount, rewrites, fallbackPackages }。 。 。 .
createImportMap(dependencies), (中文(简体) ), mergeImportMaps(...maps), (中文(简体) ), generateImportMapScriptTag(map)构建,合并并写入浏览器导入地图.

构成部分

导出说明
renderComponent(config, shellConfig)决定: config.source 并构建周围的页面: { html, hash, size }。 。 。 .
resolveUISource(source, options?)决定源为 a ResolvedComponent。 。 。 .
generateMountScript(resolved, propsMapping?)导入并挂载模块组件的模块脚本 .
bundleFileSource(), (中文(简体) ), transpileReactSource()套装或倒装 a .tsx 或者说 .jsx 装有构件的部件 .
isNpmSource, (中文(简体) ), isFileSource, (中文(简体) ), isImportSource, (中文(简体) ), isFunctionSource类型卫兵的源.

桥梁运行时间

导出说明
generateBridgeIIFE(options?)桥脚本. 选项 : adapters (从) openai, (中文(简体) ), ext-apps, (中文(简体) ), claude, (中文(简体) ), gemini, (中文(简体) ), generic, (中文(简体) ), debug, (中文(简体) ), trustedOrigins, (中文(简体) ), minify。 。 。 .
generatePlatformBundle(platform, options?)脚本用于 chatgpt, (中文(简体) ), claude, (中文(简体) ), gemini 或者说 universal。 。 。 .
UNIVERSAL_BRIDGE_SCRIPT每个适配器的脚本.
BRIDGE_SCRIPT_TAGS{ universal, chatgpt, claude, gemini },每个包裹 <script>。 。 。 .

键入

导出说明
createTypeFetcher(options?, cache?)A 类 TypeFetcher选项: allowedPackages, (中文(简体) ), maxDepth, (中文(简体) ), timeout (每个请求10 s), maxConcurrency (5), (中文), cdnBaseUrl, (中文(简体) ), fetch。 。 。 .
TypeFetcherfetchBatch({ imports, maxDepth?, timeout? })数字 : { results, errors, totalTimeMs, cacheHits }。 。 。 .
MemoryTypeCache, (中文(简体) ), globalTypeCache最近使用最少但已过期的缓存;共享的缓存保存了最多500个条目长达1小时.
parseDtsImports(content), (中文(简体) ), combineDtsContents(contents)分析a .d.ts 文件的导入; 将多个文件合并为一个文件.

用户

导出说明
escapeHtml(value)逃脱 &, (中文(简体) ), <, (中文(简体) ), >, (中文(简体) ), " 财务报告和审定财务报表 ',还有U+2028和U+2029. null 财务报告和审定财务报表 undefined 给 ''。 。 。 .
escapeHtmlAttr(value)逃脱 & 财务报告和审定财务报表 ",用于属性值.
escapeJsString(value)逃避 JavaScript 字符串的字符串 .
escapeScriptClose(json)替换 </ 与 <\/,所以文本不能关闭 a <script>。 。 。 .
safeJsonForScript(value)JSON安全放进去 <script>数字 : <, (中文(简体) ), > 财务报告和审定财务报表 & 逃脱了,大英作为弦 {"error":"Value could not be serialized"} jSON不能持有的值,例如循环值.
safeStringify(value, space?)JSON.stringify 写着 [Circular] 用于循环参考.

文档

  • 部件数字 : @frontmcp/uipack 在服务器上, html 财务报告和审定财务报表 renderToolTemplate()
  • 这个 ui 选项: 模板、服务模式、内容安全政策
  • 主机和平台桥, window.FrontMcpBridge,每个主机得到什么
  • 选择部件如何服务: 内置和静态页面,以及部件可以装入的内容

捐款

资料来源: libs/uipack欢迎提出问题和拉动请求;见 捐款额。 。 。 .

源代码下每个输入点有一个文件夹 src/数字 : adapters/, (中文(简体) ), shell/, (中文(简体) ), resolver/, (中文(简体) ), component/, (中文(简体) ), bridge-runtime/, (中文(简体) ), typings/, (中文(简体) ), types/ 财务报告和审定财务报表 utils/。 。 。 . utils 财务报告和审定财务报表 bridge-runtime - 没有别的依赖; resolver 用途 utils· ; shell 用途 utils, (中文(简体) ), resolver 财务报告和审定财务报表 bridge-runtime· ; component 以 shell· ; adapters 全部使用; typings 孤军奋战 types 只有进口类型。 测试出逃和内容安全政策有敌意的改变。 在单曲中:

nx build uipack
nx test uipack
nx lint uipack

许可证

阿帕奇2.0 (英语). 见 自由主义。 。 。 .

版本与发布记录

@frontmcp/uipack 共发布 113 个版本,首次发布于 2025/12/23;过去 12 个月发布了 113 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.12.2latest2026/11/151 天前
1.12.12026/11/132 天前
1.12.02026/11/114 天前
1.12.0-rc.1rc2026/11/114 天前
1.11.32026/11/106 天前
1.11.22026/11/096 天前

其他发布通道:beta → 1.1.2-beta.1,rc → 1.12.0-rc.1。

关于 @frontmcp/uipack 的常见问题

@frontmcp/uipack 是什么?

构建 FrontMCP 部件页面的无反射核心: HTML shell 有 CSP 和 Bridge, 模板渲染, CDN 导入分辨率

如何安装 @frontmcp/uipack?

在项目目录运行 npm install @frontmcp/uipack,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@frontmcp/lazy-zod(1.12.2)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@frontmcp/uipack 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@frontmcp/uipack 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@frontmcp/uipack 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=24.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@frontmcp/uipack 可以商用吗?

@frontmcp/uipack 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@frontmcp/uipack 的下载量有多少?

根据 npm 官方下载统计,@frontmcp/uipack 在 2026/10/16 – 2026/11/14 这 30 天内被下载 13,821 次,日均约 461 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@frontmcp/uipack 还在维护吗?

最新版本 1.12.2 发布于 2026/11/15(1 天前);至今共发布 113 个版本,其中过去 12 个月发布了 113 个;首次发布于 2025/12/23。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。