用途:为智能体渲染的 UI 建立安全模型。内容经过外部服务→MCP 服务器→模型→宿主→iframe 多跳传递,每跳都可能被非用户方塑造,需按此设计。
沙箱契约:View 运行在沙箱 iframe 中,无法访问宿主 DOM、cookie、localStorage 或源;postMessage 是唯一通道,使能力可枚举可审计,不要试图放宽。CSP 默认拒绝,未在 _meta.ui.csp 声明的一律阻断;嵌套 frame 默认禁止,除非用 frameDomains 显式开启(部分宿主不支持)。对 mcp-ui 客户端渲染器,sandbox.url 代理源是隔离的执行点,切勿指向自有应用源。
编写 CSP:在资源内容的 _meta 中声明尽可能窄的白名单,包含 connectDomains(fetch/WebSocket)、resourceDomains(脚本、样式、图片、字体)、frameDomains、baseUriDomains 与 domain。规则:每个真实依赖一条,禁用通配符;尽量避免 CDN,可用 vite-plugin-singlefile 或 esbuild 内联资源;connectDomains 是数据可能外泄的目标源,需逐个论证;frameDomains 保持为空,且 Copilot 完全忽略它。CSP 必须放在内容 _meta 而非 config 参数,否则 View 能加载但静默无法联网。
structuredContent 是不可信输入:用 textContent 而非 innerHTML,避免 innerHTML、outerHTML、insertAdjacentHTML、document.write、eval、new Function 与 javascript: URL。在 View 边界用 zod、valibot 或手动守卫做 schema 校验,并限制数组与字符串长度。数据来源 URL 需过滤协议,仅允许 http:/https:;导航走 app.openLink/ ui/open-link,不用 window.open 或 location.assign。
提示注入:向 ui/update-model-context 或 ui/message 传数据时只送结构化事实(ID、计数、选择项),不要送原始第三方文本;模型产生的工具参数需服务端校验。
授权与密钥:View 不是信任边界,所有变更操作由服务端针对已认证用户授权,金额、数量、权限等均在服务端重算,变更工具需幂等;visibility:["app"] 只是上下文卫生,不等于访问控制。View 包内不得含 API key、令牌或连接串,特权调用走服务端代理,部署前移除匿名认证。localStorage 与 setWidgetState 均不可作持久存储。
发布前清单包括:白名单仅含实际使用的源、frameDomains 为空或有记录的产品需求、CSP 位于资源内容 _meta、无危险 HTML/JS 调用、schema 校验与边界、URL 协议白名单、导航统一走 openLink、模型上下文只含事实、变更工具服务端授权且幂等、包内与 URI 无密钥、移除匿名认证并配置 OAuth 2.1 或 Entra SSO,UI 破坏性变更时提升资源 URI。可运行 /ui:csp 自动检查前八项。