测试与发布
宿主兼容性
| 宿主 | 渲染 | sendPrompt | callTool | openLink | 说明 |
|---|---|---|---|---|---|
| Cursor | ✅ | ✅ | ✅ | ✅ | 使用 JSON-RPC bridge 和旧版 ready/resize 消息进行了测试。 |
| ChatGPT (Apps SDK) | ✅ | ⚠️ | ✅ | ✅ | 可用时使用 window.openai。后续消息会发送,但下一次工具结果并不总是以内联方式渲染。 |
| MCP UI / Inspector 风格宿主 | ✅ | varies | varies | varies | bridge 会发出规范的 JSON-RPC 消息,并在有用时发出旧版 mcp-ui 封装。请在记录支持情况前逐个宿主验证。 |
bridge 会在握手时自动检测宿主,并适配其协议——对于 MCP UI 宿主使用现代 JSON-RPC,对于旧客户端使用旧版 mcp-ui 封装,在存在 ChatGPT Apps SDK 全局对象时则使用它们。你的代码只需要调用 useMcpApp()。
本地测试循环
MCP Apps 使用与工具、资源和提示词相同的可流式传输 HTTP 端点。默认路由是 /mcp,除非你在 nuxt.config 中设置了 mcp.route。
启动你的 Nuxt 应用:
pnpm dev
npm run dev
yarn dev
bun dev
你的本地 MCP URL 是:
http://localhost:3000/mcp
先使用 MCP Inspector、npx @modelcontextprotocol/inspector@latest,或 Nuxt DevTools 中的 MCP 面板。确认:
- 应用 SFC 显示为一个工具,例如
color-picker或release-control; - 调用该工具会返回
structuredContent; - 工具结果包含一个
text/html;profile=mcp-app资源; - 资源 URI 看起来像
ui://mcp-app/<name>。
有些客户端可以调用工具,但无法渲染 iframe。验证 UI 本身时,请使用支持 MCP Apps 的宿主。
使用 ngrok 在 ChatGPT 中测试
ChatGPT 需要一个公开的 HTTPS 端点,即使在本地开发时也是如此。将你的本地 Nuxt 服务器隧道出去:
ngrok http 3000
ngrok 会打印一个转发 URL:
Forwarding https://your-subdomain.ngrok-free.dev -> http://localhost:3000
在该来源上使用 /mcp 路由:
https://your-subdomain.ngrok-free.dev/mcp
在 ChatGPT 中:
- 在 Settings → Apps → Advanced settings 中启用 Developer Mode。
- 打开 Settings → Apps。
- 点击 Create app。
- 输入你的公开 MCP URL,包括
/mcp。 - 启用该应用并开始新的聊天。
- 在输入提示之前,从 composer 中选择你的应用。
使用 @ 提及该应用,这样 ChatGPT 就会通过你的连接器路由提示词:
@Weather App London 的天气怎么样?
然后测试 iframe 行为:
- 点击调用
callTool()的按钮,并确认小组件在没有新的聊天轮次的情况下更新; - 点击调用
sendPrompt()的按钮,并确认对话中出现后续消息; - 点击调用
openLink()的按钮,并确认 ChatGPT 打开或提示外部 URL; - 观察你的 Nuxt 终端和 ngrok 仪表盘中针对
/mcp的 POST 请求。
如果你通过 ngrok 暴露本地开发环境,请在 Vite 中允许隧道主机:
export default defineNuxtConfig({
vite: {
server: {
allowedHosts: ['.ngrok-free.dev', '.ngrok.app'],
},
},
})
对于 ChatGPT 之类的跨域宿主,请有意地配置 MCP origin 检查:
export default defineNuxtConfig({
mcp: {
security: {
allowedOrigins: '*',
},
},
})
仅在演示或公开只读界面中使用 '*'。对于包含私有数据或真实副作用的生产应用,请使用受信任来源列表。
部署到 Vercel 或其他云平台
MCP Apps 不 使用第二个 URL。部署 Nuxt 应用,并将 ChatGPT 连接到同一个 MCP 路由:
https://your-project.vercel.app/mcp
工具包会从常见托管变量中自动检测 _meta.ui.domain:
NUXT_PUBLIC_APP_URL;- Vercel:
VERCEL_PROJECT_PRODUCTION_URL,VERCEL_URL; - Netlify:
URL; - Render:
RENDER_EXTERNAL_URL; - Railway:
RAILWAY_PUBLIC_DOMAIN; - Fly:
FLY_APP_NAME。
如果你需要覆盖检测到的值,请显式设置它:
<script setup lang="ts">
defineMcpApp({
_meta: {
ui: {
domain: 'https://my-app.example.com',
},
},
})
</script>
对于 Vercel,请确保你的构建包含你所部署工具包版本中的 MCP Apps 打包依赖。如果你测试的是一个未发布包,请使用新的 pkg.pr.new 构建,或在应用中安装所需的构建依赖,直到该包发布为止。
为 ChatGPT 提交做准备
OpenAI 会在广泛分发前审核应用。在提交之前,请检查:
- 你的 MCP 服务器可通过 HTTPS 公开访问;
- 每个应用资源都返回
text/html;profile=mcp-app; - 每个应用工具都具有清晰的
description、inputSchema和行为注解; - 已存在
_meta.ui.resourceUri(工具包会生成它); _meta.ui.domain已设置或被自动检测;- 对外部图片、脚本、字体、API 或 iframe 的 CSP 是显式配置的;
structuredContent简洁且对模型来说是安全可读的;- 大型或仅供小组件使用的数据放在
_meta中,而不是structuredContent中; - 如果你的应用需要公开分发,OAuth、隐私政策、应用名称、截图和测试提示词都已准备就绪。
当宿主暴露 Apps SDK(window.openai)或强制执行小组件 CSP 时,工具包会将你的 csp 镜像到 _meta.ui.csp 和 openai/widgetCSP。行为,尤其是 sendPrompt 和后续重新渲染,可能会在 ChatGPT 不同版本之间发生变化。在提交或宣布支持之前,请重新测试你的应用。
故障排查
来自 /mcp 的 403 Forbidden
请求已到达你的服务器,但未通过 origin 或 host 检查。
- 对于 ChatGPT/ngrok 演示,将
mcp.security.allowedOrigins设置为'*'或受信任的来源列表。 - 对于 Vite 开发服务器隧道,将隧道域名添加到
vite.server.allowedHosts。 - 修改
nuxt.config.ts后,重启 Nuxt 开发服务器。
小组件未渲染
检查工具结果:
- 资源 MIME 类型必须是
text/html;profile=mcp-app。 - 资源 URI 应与
_meta.ui.resourceUri匹配。 - 宿主必须支持 MCP Apps。有些 MCP 客户端可以调用工具,但只显示文本。
没有收到 ui/* 消息
iframe 已加载,但宿主未启用 MCP Apps bridge。
- 确认宿主将 HTML 作为 MCP App 资源渲染,而不是作为普通文件。
- 在宿主开发者工具中检查浏览器控制台是否有 CSP 或 sandbox 错误。
- 在 Cursor 或 ChatGPT 中测试以比较宿主行为。
CSP 阻止了图片或 fetch 调用
添加显式允许列表:
defineMcpApp({
csp: {
resourceDomains: ['https://images.example.com'],
connectDomains: ['https://api.example.com'],
},
})
对于强制执行小组件 CSP 的宿主,工具包会将这些镜像到 _meta.ui.csp 和 openai/widgetCSP。
Vercel 找不到生成的 MCP App 文件
请使用包含 MCP Apps 构建修复的工具包版本。旧的未发布构建可能会在运行时导入 .nuxt/mcp-apps/gen/*.ts,而该文件在已部署的 Vercel function 中并不存在。
缺少 vite-plugin-singlefile 或 @vitejs/plugin-vue
请使用提供 MCP Apps 打包依赖的工具包版本,或者在测试未发布构建时将它们安装到应用中。
ChatGPT 一直显示旧的小组件
ChatGPT 可能会按 URI 缓存小组件模板。如果你进行了会破坏兼容性的 UI 更改,请更改资源 URI 或文件名,以便宿主加载新的模板。
其他客户端
Claude Code、Claude Desktop(启用远程 MCP 的情况下)、Cursor、VS Code 和类似 Codex 风格的客户端,会使用你用于工具的相同 MCP URL 连接到你的服务器。不存在单独的“仅应用”端点。
Web 和移动端的 ChatGPT/Claude 应用可能不会在每个发布渠道都渲染 MCP UI 小组件。请始终在你支持的产品版本上验证内联 iframe。
在调试 JSON-RPC UI bridge 时,优先将 Cursor 作为主要开发工具;它是本模块测试套件中使用最充分的环境。
相关内容
- CSP 与构建流水线 — HTML 和
_meta是如何生成的。 - 模式与限制 — iframe 约束和 API 速查表。
- 处理器 — 如果你将应用与其他工具分开,可选的
https://…/mcp/apps界面。 - OpenAI:构建你的 MCP 服务器
- OpenAI:从 ChatGPT 连接
- OpenAI:测试你的集成
- OpenAI:提交并维护你的应用
- OpenAI:应用提交指南