[{"data":1,"prerenderedAt":1743},["ShallowReactive",2],{"navigation_docs":3,"-advanced-mcp-apps-internals":282,"-advanced-mcp-apps-internals-surround":1738},[4,40,70,99,122,156,189,253],{"title":5,"path":6,"stem":7,"children":8,"page":39},"入门指南","\u002Fgetting-started","1.getting-started",[9,14,19,24,29,34],{"title":10,"path":11,"stem":12,"icon":13},"简介","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-lucide-book-open",{"title":15,"path":16,"stem":17,"icon":18},"安装","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":20,"path":21,"stem":22,"icon":23},"配置","\u002Fgetting-started\u002Fconfiguration","1.getting-started\u002F3.configuration","i-lucide-settings",{"title":25,"path":26,"stem":27,"icon":28},"Inspector","\u002Fgetting-started\u002Finspector","1.getting-started\u002F4.inspector","i-lucide-circuit-board",{"title":30,"path":31,"stem":32,"icon":33},"Connection","\u002Fgetting-started\u002Fconnection","1.getting-started\u002F5.connection","i-lucide-plug",{"title":35,"path":36,"stem":37,"icon":38},"Agent Skills","\u002Fgetting-started\u002Fagent-skills","1.getting-started\u002F6.agent-skills","i-lucide-sparkles",false,{"title":41,"path":42,"stem":43,"children":44,"page":39},"工具","\u002Ftools","2.tools",[45,50,55,60,65],{"title":46,"path":47,"stem":48,"icon":49},"概览","\u002Ftools\u002Foverview","2.tools\u002F0.overview","i-lucide-wrench",{"title":51,"path":52,"stem":53,"icon":54},"Schema, handler & returns","\u002Ftools\u002Fschema-handler","2.tools\u002F1.schema-handler","i-lucide-braces",{"title":56,"path":57,"stem":58,"icon":59},"注释与输入示例","\u002Ftools\u002Fannotations","2.tools\u002F2.annotations","i-lucide-badge-info",{"title":61,"path":62,"stem":63,"icon":64},"错误与缓存","\u002Ftools\u002Ferrors-caching","2.tools\u002F3.errors-caching","i-lucide-shield",{"title":66,"path":67,"stem":68,"icon":69},"分组、文件与动态注册","\u002Ftools\u002Fgroups-organization","2.tools\u002F4.groups-organization","i-lucide-tags",{"title":71,"path":72,"stem":73,"children":74,"page":39},"资源","\u002Fresources","3.resources",[75,79,84,89,94],{"title":46,"path":76,"stem":77,"icon":78},"\u002Fresources\u002Foverview","3.resources\u002F0.overview","i-lucide-package",{"title":80,"path":81,"stem":82,"icon":83},"静态资源与结构","\u002Fresources\u002Fstatic-and-structure","3.resources\u002F1.static-and-structure","i-lucide-file-stack",{"title":85,"path":86,"stem":87,"icon":88},"模板与处理程序","\u002Fresources\u002Ftemplates-and-handlers","3.resources\u002F2.templates-and-handlers","i-lucide-git-branch",{"title":90,"path":91,"stem":92,"icon":93},"元数据、内容与错误","\u002Fresources\u002Fcontent-metadata-errors","3.resources\u002F3.content-metadata-errors","i-lucide-layers",{"title":95,"path":96,"stem":97,"icon":98},"分组与组织","\u002Fresources\u002Forganization","3.resources\u002F4.organization","i-lucide-folder-tree",{"title":100,"path":101,"stem":102,"children":103,"page":39},"提示词","\u002Fprompts","4.prompts",[104,108,113,117],{"title":46,"path":105,"stem":106,"icon":107},"\u002Fprompts\u002Foverview","4.prompts\u002F0.overview","i-lucide-message-square",{"title":109,"path":110,"stem":111,"icon":112},"编写与结构","\u002Fprompts\u002Fauthoring","4.prompts\u002F1.authoring","i-lucide-pen-line",{"title":114,"path":115,"stem":116,"icon":93},"输入、处理器与消息","\u002Fprompts\u002Finput-handler-messages","4.prompts\u002F2.input-handler-messages",{"title":118,"path":119,"stem":120,"icon":121},"模式与高级用法","\u002Fprompts\u002Fpatterns-advanced","4.prompts\u002F3.patterns-advanced","i-lucide-line-chart",{"title":123,"path":124,"stem":125,"children":126,"page":39},"处理器","\u002Fhandlers","5.handlers",[127,131,136,141,146,151],{"title":46,"path":128,"stem":129,"icon":130},"\u002Fhandlers\u002Foverview","5.handlers\u002F0.overview","i-lucide-server",{"title":132,"path":133,"stem":134,"icon":135},"默认与自定义处理器","\u002Fhandlers\u002Fdefault-and-custom","5.handlers\u002F1.default-and-custom","i-lucide-toggle-left",{"title":137,"path":138,"stem":139,"icon":140},"结构与选项","\u002Fhandlers\u002Fstructure-and-options","5.handlers\u002F2.structure-and-options","i-lucide-sliders-horizontal",{"title":142,"path":143,"stem":144,"icon":145},"示例与路由","\u002Fhandlers\u002Fexamples-routing","5.handlers\u002F3.examples-routing","i-lucide-route",{"title":147,"path":148,"stem":149,"icon":150},"分享与实践","\u002Fhandlers\u002Fsharing-practices","5.handlers\u002F4.sharing-practices","i-lucide-share-2",{"title":152,"path":153,"stem":154,"icon":155},"多处理器组织","\u002Fhandlers\u002Forganization","5.handlers\u002F5.organization","i-lucide-network",{"title":157,"path":158,"stem":159,"children":160,"page":39},"应用","\u002Fapps","6.apps",[161,165,170,175,179,184],{"title":46,"path":162,"stem":163,"icon":164},"\u002Fapps\u002Foverview","6.apps\u002F0.overview","i-lucide-app-window",{"title":166,"path":167,"stem":168,"icon":169},"编写与 defineMcpApp","\u002Fapps\u002Fauthoring","6.apps\u002F1.authoring","i-lucide-code-2",{"title":171,"path":172,"stem":173,"icon":174},"useMcpApp() 桥接","\u002Fapps\u002Fuse-mcp-app","6.apps\u002F2.use-mcp-app","i-lucide-message-circle",{"title":176,"path":177,"stem":178,"icon":64},"CSP 与构建流水线","\u002Fapps\u002Fcsp-and-wiring","6.apps\u002F3.csp-and-wiring",{"title":180,"path":181,"stem":182,"icon":183},"测试与发布","\u002Fapps\u002Ftesting-publishing","6.apps\u002F4.testing-publishing","i-lucide-rocket",{"title":185,"path":186,"stem":187,"icon":188},"模式与限制","\u002Fapps\u002Fpatterns-reference","6.apps\u002F5.patterns-reference","i-lucide-book-marked",{"title":190,"path":191,"stem":192,"children":193,"page":39},"进阶主题","\u002Fadvanced","7.advanced",[194,199,204,209,214,218,223,228,233,238,243,248],{"title":195,"path":196,"stem":197,"icon":198},"自定义路径","\u002Fadvanced\u002Fcustom-paths","7.advanced\u002F1.custom-paths","i-lucide-folder",{"title":200,"path":201,"stem":202,"icon":203},"日志","\u002Fadvanced\u002Flogging","7.advanced\u002F10.logging","i-lucide-scroll-text",{"title":205,"path":206,"stem":207,"icon":208},"MCP Apps 内部机制","\u002Fadvanced\u002Fmcp-apps-internals","7.advanced\u002F11.mcp-apps-internals","i-lucide-cog",{"title":210,"path":211,"stem":212,"icon":213},"列出定义","\u002Fadvanced\u002Flisting-definitions","7.advanced\u002F12.listing-definitions","i-lucide-list",{"title":215,"path":216,"stem":217,"icon":64},"Middleware","\u002Fadvanced\u002Fmiddleware","7.advanced\u002F2.middleware",{"title":219,"path":220,"stem":221,"icon":222},"TypeScript","\u002Fadvanced\u002Ftypescript","7.advanced\u002F3.typescript","i-lucide-type",{"title":224,"path":225,"stem":226,"icon":227},"Hooks","\u002Fadvanced\u002Fhooks","7.advanced\u002F4.hooks","i-lucide-webhook",{"title":229,"path":230,"stem":231,"icon":232},"MCP 评估","\u002Fadvanced\u002Fevals","7.advanced\u002F5.evals","i-lucide-flask-conical",{"title":234,"path":235,"stem":236,"icon":237},"会话","\u002Fadvanced\u002Fsessions","7.advanced\u002F6.sessions","i-lucide-database",{"title":239,"path":240,"stem":241,"icon":242},"动态定义","\u002Fadvanced\u002Fdynamic-definitions","7.advanced\u002F7.dynamic-definitions","i-lucide-toggle-right",{"title":244,"path":245,"stem":246,"icon":247},"代码模式 (Code Mode)","\u002Fadvanced\u002Fcode-mode","7.advanced\u002F8.code-mode","i-lucide-code",{"title":249,"path":250,"stem":251,"icon":252},"启发式询问","\u002Fadvanced\u002Felicitation","7.advanced\u002F9.elicitation","i-lucide-message-square-quote",{"title":254,"path":255,"stem":256,"children":257,"page":39},"示例","\u002Fexamples","8.examples",[258,263,268,273,278],{"title":259,"path":260,"stem":261,"icon":262},"身份验证","\u002Fexamples\u002Fauthentication","8.examples\u002F1.authentication","i-lucide-shield-check",{"title":264,"path":265,"stem":266,"icon":267},"API 集成","\u002Fexamples\u002Fapi-integration","8.examples\u002F2.api-integration","i-lucide-globe",{"title":269,"path":270,"stem":271,"icon":272},"常见模式","\u002Fexamples\u002Fcommon-patterns","8.examples\u002F3.common-patterns","i-lucide-lightbulb",{"title":274,"path":275,"stem":276,"icon":277},"文件操作","\u002Fexamples\u002Ffile-operations","8.examples\u002F4.file-operations","i-lucide-file",{"title":279,"path":280,"stem":281,"icon":107},"提示词示例","\u002Fexamples\u002Fprompt-examples","8.examples\u002F5.prompt-examples",{"id":283,"title":205,"body":284,"description":1729,"extension":1730,"links":1731,"meta":1732,"navigation":1733,"path":206,"seo":1734,"stem":207,"__hash__":1737},"docs\u002F7.advanced\u002F11.mcp-apps-internals.md",{"type":285,"value":286,"toc":1709},"minimark",[287,296,300,313,379,382,425,439,444,447,542,561,564,575,633,639,646,761,764,767,771,778,807,810,910,921,925,928,947,950,954,965,973,980,990,1126,1139,1142,1145,1158,1195,1210,1213,1220,1226,1285,1305,1414,1417,1469,1493,1506,1509,1516,1612,1615,1618,1632,1647,1656,1659,1705],[288,289,290,291,295],"p",{},"本页介绍 ",[292,293,294],"a",{"href":162},"MCP Apps"," 背后的组成部分：构建流水线、主机桥接、安全模型，以及你可以在其上组合的模式。",[297,298,299],"h2",{"id":299},"构建流水线",[288,301,302,303,307,308,312],{},"对于每个 ",[304,305,306],"code",{},"app\u002Fmcp\u002F*.vue"," 文件，Nuxt 模块会在构建时生成 ",[309,310,311],"strong",{},"三个产物","，并将它们注册到配置好的处理器上：",[314,315,320],"pre",{"className":316,"code":317,"language":318,"meta":319,"style":319},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight",".nuxt\u002Fmcp-apps\u002F\n├── color-picker.app.ts       # McpAppDefinition（已解析的 defineMcpApp 调用）\n├── color-picker.tool.ts      # 封装该应用的 McpToolDefinition\n├── color-picker.resource.ts  # 提供 HTML 的 McpResourceDefinition\n└── color-picker.html         # 单文件 Vue 打包结果（vite-plugin-singlefile）\n","bash","",[304,321,322,331,345,356,367],{"__ignoreMap":319},[323,324,327],"span",{"class":325,"line":326},"line",1,[323,328,330],{"class":329},"sBMFI",".nuxt\u002Fmcp-apps\u002F\n",[323,332,334,337,341],{"class":325,"line":333},2,[323,335,336],{"class":329},"├──",[323,338,340],{"class":339},"sfazB"," color-picker.app.ts",[323,342,344],{"class":343},"sHwdD","       # McpAppDefinition（已解析的 defineMcpApp 调用）\n",[323,346,348,350,353],{"class":325,"line":347},3,[323,349,336],{"class":329},[323,351,352],{"class":339}," color-picker.tool.ts",[323,354,355],{"class":343},"      # 封装该应用的 McpToolDefinition\n",[323,357,359,361,364],{"class":325,"line":358},4,[323,360,336],{"class":329},[323,362,363],{"class":339}," color-picker.resource.ts",[323,365,366],{"class":343},"  # 提供 HTML 的 McpResourceDefinition\n",[323,368,370,373,376],{"class":325,"line":369},5,[323,371,372],{"class":329},"└──",[323,374,375],{"class":339}," color-picker.html",[323,377,378],{"class":343},"         # 单文件 Vue 打包结果（vite-plugin-singlefile）\n",[288,380,381],{},"该流水线分三个阶段运行：",[383,384,385,404,419],"ol",{},[386,387,388,391,392,395,396,399,400,403],"li",{},[309,389,390],{},"解析"," — 从 ",[304,393,394],{},"\u003Cscript setup>"," 中提取 ",[304,397,398],{},"defineMcpApp({ … })"," 调用，并仅保留在宏参数内部被引用的导入。随后该宏会从浏览器包中",[309,401,402],{},"剥离","。",[386,405,406,409,410,418],{},[309,407,408],{},"打包"," — 通过编程方式调用 Vite，并使用 ",[292,411,415],{"href":412,"rel":413},"https:\u002F\u002Fgithub.com\u002Frichardtallent\u002Fvite-plugin-singlefile",[414],"nofollow",[304,416,417],{},"vite-plugin-singlefile"," 为每个 SFC 生成一个自包含的 HTML 文件（Vue 运行时、你的代码、scoped CSS、资源）。",[386,420,421,424],{},[309,422,423],{},"输出"," — 写入这三个 TypeScript 文件以及 HTML，然后将它们加入 Nuxt 的自动导入 + 处理器注册，使其表现得像其他工具 \u002F 资源一样。",[426,427,430,431,434,435,438],"callout",{"color":428,"icon":429},"info","i-lucide-info","输出位于 ",[304,432,433],{},"\u003CbuildDir>\u002Fmcp-apps\u002F"," 下。它会在每次构建时重新生成，开发服务器会监听 ",[304,436,437],{},"app\u002Fmcp\u002F**","，因此修改会热更新。",[440,441,443],"h3",{"id":442},"html-中会内联什么内容","HTML 中会内联什么内容",[288,445,446],{},"当 LLM 调用该工具时，工具包会取出打包后的 HTML 并注入：",[314,448,452],{"className":449,"code":450,"language":451,"meta":319,"style":319},"language-html shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Cmeta http-equiv=\"Content-Security-Policy\" content=\"…\">\n\u003Cscript type=\"application\u002Fjson\" id=\"__mcp_app_data__\">\n  { \"base\": \"#2563eb\", \"swatches\": [ … ] }\n\u003C\u002Fscript>\n","html",[304,453,454,494,527,533],{"__ignoreMap":319},[323,455,456,460,464,468,471,474,477,479,482,484,486,489,491],{"class":325,"line":326},[323,457,459],{"class":458},"sMK4o","\u003C",[323,461,463],{"class":462},"swJcz","meta",[323,465,467],{"class":466},"spNyl"," http-equiv",[323,469,470],{"class":458},"=",[323,472,473],{"class":458},"\"",[323,475,476],{"class":339},"Content-Security-Policy",[323,478,473],{"class":458},[323,480,481],{"class":466}," content",[323,483,470],{"class":458},[323,485,473],{"class":458},[323,487,488],{"class":339},"…",[323,490,473],{"class":458},[323,492,493],{"class":458},">\n",[323,495,496,498,501,504,506,508,511,513,516,518,520,523,525],{"class":325,"line":333},[323,497,459],{"class":458},[323,499,500],{"class":462},"script",[323,502,503],{"class":466}," type",[323,505,470],{"class":458},[323,507,473],{"class":458},[323,509,510],{"class":339},"application\u002Fjson",[323,512,473],{"class":458},[323,514,515],{"class":466}," id",[323,517,470],{"class":458},[323,519,473],{"class":458},[323,521,522],{"class":339},"__mcp_app_data__",[323,524,473],{"class":458},[323,526,493],{"class":458},[323,528,529],{"class":325,"line":347},[323,530,532],{"class":531},"sTEyZ","  { \"base\": \"#2563eb\", \"swatches\": [ … ] }\n",[323,534,535,538,540],{"class":325,"line":358},[323,536,537],{"class":458},"\u003C\u002F",[323,539,500],{"class":462},[323,541,493],{"class":458},[288,543,544,545,548,549,552,553,556,557,560],{},"第一次 ",[304,546,547],{},"useMcpApp()"," 调用会同步读取 ",[304,550,551],{},"#__mcp_app_data__","，因此 ",[304,554,555],{},"data.value"," 在",[309,558,559],{},"首次渲染时就已经填充","——没有 fetch，没有瀑布流。",[297,562,563],{"id":563},"主机桥接",[288,565,566,567,570,571,574],{},"iframe 和宿主通过使用 JSON-RPC 2.0 信封的 ",[304,568,569],{},"postMessage"," 进行通信。工具包提供了一个单例的 ",[304,572,573],{},"useHostBridge()","（内部实现），它会：",[383,576,577,587,597,611,622],{},[386,578,579,580,583,584,403],{},"执行 ",[304,581,582],{},"ui\u002Finitialize"," 握手，以协商能力并接收 ",[304,585,586],{},"HostContext",[386,588,589,590,593,594,403],{},"将传入的 ",[304,591,592],{},"tool-result"," 消息路由回 ",[304,595,596],{},"data",[386,598,599,600,603,604,603,607,610],{},"将发出的 ",[304,601,602],{},"callTool","、",[304,605,606],{},"prompt",[304,608,609],{},"openLink"," 请求分发给宿主。",[386,612,613,614,617,618,621],{},"在与旧宿主通信时，回退到旧版 ",[304,615,616],{},"mcp-ui"," 信封（",[304,619,620],{},"{ type, payload }","）。",[386,623,624,625,628,629,632],{},"检测 ",[309,626,627],{},"ChatGPT Apps SDK","（",[304,630,631],{},"window.openai","），并在可用时使用其原生 API。",[288,634,635,636,638],{},"你不会直接与它交互——",[304,637,547],{}," 组合了公开接口。",[288,640,641,642,645],{},"当 LLM 调用 ",[304,643,644],{},"color-picker"," 时的完整往返流程：",[383,647,648,657,670,680,686,700,709,726,739,747],{},[386,649,650,653,654,403],{},[309,651,652],{},"宿主 → 服务器"," — ",[304,655,656],{},"tools\u002Fcall color-picker { base }",[386,658,659,662,663,666,667,403],{},[309,660,661],{},"服务器"," — 运行 ",[304,664,665],{},"handler()"," 并生成 ",[304,668,669],{},"structuredContent",[386,671,672,675,676,679],{},[309,673,674],{},"服务器 → 宿主"," — 返回包含内联数据和 ",[304,677,678],{},"ui:\u002F\u002F"," 资源引用的打包 HTML。",[386,681,682,685],{},[309,683,684],{},"宿主 → iframe"," — 以内联方式挂载 iframe，并进行沙箱隔离。",[386,687,688,653,691,693,694,552,697,699],{},[309,689,690],{},"iframe",[304,692,547],{}," 同步读取内联的 ",[304,695,696],{},"\u003Cscript id=\"__mcp_app_data__\">",[304,698,596],{}," 在首次渲染时就已填充。",[386,701,702,705,706,708],{},[309,703,704],{},"iframe → 宿主"," — 发送 ",[304,707,582],{}," 以协商能力。",[386,710,711,713,714,628,716,603,719,603,722,725],{},[309,712,684],{}," — 回复 ",[304,715,586],{},[304,717,718],{},"theme",[304,720,721],{},"displayMode",[304,723,724],{},"containerDimensions","、…）。",[386,727,728,730,731,653,735,738],{},[309,729,704],{}," ",[732,733,734],"em",{},"(可选)",[304,736,737],{},"ui\u002FcallTool { name, params }","，用于就地刷新。",[386,740,741,743,744,403],{},[309,742,652],{}," — 将调用转发为 ",[304,745,746],{},"tools\u002Fcall name { params }",[386,748,749,752,753,755,756,758,759,403],{},[309,750,751],{},"服务器 → 宿主 → iframe"," — 新的 ",[304,754,669],{}," 作为 ",[304,757,592],{}," 返回，并替换 ",[304,760,596],{},[297,762,763],{"id":763},"安全模型",[288,765,766],{},"MCP Apps 运行在一个从你的 MCP 端点同源加载的、受沙箱限制的 iframe 中。工具包通过三层来强化该表面。",[440,768,770],{"id":769},"_1-默认-csp","1. 默认 CSP",[288,772,773,774,777],{},"每个应用 HTML 都会获得一个 CSP ",[304,775,776],{},"\u003Cmeta>","，它会：",[779,780,781,784,791],"ul",{},[386,782,783],{},"阻止所有第三方脚本。只有内联打包脚本可以执行。",[386,785,786,787,790],{},"阻止 ",[304,788,789],{},"\u003Cform>"," 的 action 目标。",[386,792,793,794,603,797,603,800,603,803,806],{},"在你显式允许之前，禁止 ",[304,795,796],{},"connect-src",[304,798,799],{},"img-src",[304,801,802],{},"style-src",[304,804,805],{},"font-src"," 外部来源。",[288,808,809],{},"你可以按应用启用外部资源：",[314,811,815],{"className":812,"code":813,"language":814,"meta":319,"style":319},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","defineMcpApp({\n  csp: {\n    resourceDomains: ['https:\u002F\u002Fimages.example.com'], \u002F\u002F 图片 \u002F 样式 \u002F 字体 \u002F link\n    connectDomains: ['https:\u002F\u002Fapi.example.com'],     \u002F\u002F fetch \u002F XHR \u002F WebSocket\n  },\n  \u002F\u002F …\n})\n","ts",[304,816,817,829,840,867,890,895,901],{"__ignoreMap":319},[323,818,819,823,826],{"class":325,"line":326},[323,820,822],{"class":821},"s2Zo4","defineMcpApp",[323,824,825],{"class":531},"(",[323,827,828],{"class":458},"{\n",[323,830,831,834,837],{"class":325,"line":333},[323,832,833],{"class":462},"  csp",[323,835,836],{"class":458},":",[323,838,839],{"class":458}," {\n",[323,841,842,845,847,850,853,856,858,861,864],{"class":325,"line":347},[323,843,844],{"class":462},"    resourceDomains",[323,846,836],{"class":458},[323,848,849],{"class":531}," [",[323,851,852],{"class":458},"'",[323,854,855],{"class":339},"https:\u002F\u002Fimages.example.com",[323,857,852],{"class":458},[323,859,860],{"class":531},"]",[323,862,863],{"class":458},",",[323,865,866],{"class":343}," \u002F\u002F 图片 \u002F 样式 \u002F 字体 \u002F link\n",[323,868,869,872,874,876,878,881,883,885,887],{"class":325,"line":358},[323,870,871],{"class":462},"    connectDomains",[323,873,836],{"class":458},[323,875,849],{"class":531},[323,877,852],{"class":458},[323,879,880],{"class":339},"https:\u002F\u002Fapi.example.com",[323,882,852],{"class":458},[323,884,860],{"class":531},[323,886,863],{"class":458},[323,888,889],{"class":343},"     \u002F\u002F fetch \u002F XHR \u002F WebSocket\n",[323,891,892],{"class":325,"line":369},[323,893,894],{"class":458},"  },\n",[323,896,898],{"class":325,"line":897},6,[323,899,900],{"class":343},"  \u002F\u002F …\n",[323,902,904,907],{"class":325,"line":903},7,[323,905,906],{"class":458},"}",[323,908,909],{"class":531},")\n",[288,911,912,913,916,917,920],{},"同样的允许列表也会镜像到 ",[304,914,915],{},"_meta.ui.csp"," 和 ",[304,918,919],{},"_meta['openai\u002FwidgetCSP']","，供那些自行强制执行 CSP 的宿主使用。",[440,922,924],{"id":923},"_2-域名验证","2. 域名验证",[288,926,927],{},"CSP 来源会在构建时进行验证。工具包会拒绝：",[779,929,930,933,944],{},[386,931,932],{},"非字符串或空值。",[386,934,935,936,939,940,943],{},"除 ",[304,937,938],{},"http(s):\u002F\u002F"," 或 ",[304,941,942],{},"ws(s):\u002F\u002F"," 之外的 URL 协议。",[386,945,946],{},"包含引号、分号或空白字符的字符串。",[288,948,949],{},"如果某个域名看起来可疑，构建就会失败——你不会因为配置错误而意外发布一个注入向量。",[440,951,953],{"id":952},"_3-iframe-隔离","3. iframe 隔离",[288,955,956,957,960,961,964],{},"该 iframe 的运行方式就像你域名上的第三方页面：没有 cookie、没有来自父应用的 ",[304,958,959],{},"localStorage","、没有共享模块图。这是",[309,962,963],{},"有意为之","——应用必须声明自己需要什么，并且不能访问父 Nuxt 运行时。",[426,966,968,969,972],{"color":967,"icon":64},"warning","只有当你完全控制 iframe 加载的每一个字节时，才传入 ",[304,970,971],{},"csp: false","。移除 CSP 就等于关闭了防范依赖被攻破的唯一防线。",[297,974,976,977],{"id":975},"自定义-_meta","自定义 ",[304,978,979],{},"_meta",[288,981,982,983,986,987,989],{},"处理器返回的是一个标准的 MCP ",[304,984,985],{},"CallToolResult","，因此你可以通过 ",[304,988,979],{}," 附加任何宿主特定元数据：",[314,991,993],{"className":812,"code":992,"language":814,"meta":319,"style":319},"defineMcpApp({\n  _meta: {\n    'openai\u002FwidgetAccessible': true,\n    'openai\u002FtoolInvocation\u002Finvoking': '正在加载…',\n    'openai\u002FtoolInvocation\u002Finvoked': '已加载',\n  },\n  handler: async () => ({ structuredContent: { … } }),\n})\n",[304,994,995,1003,1012,1031,1052,1072,1076,1119],{"__ignoreMap":319},[323,996,997,999,1001],{"class":325,"line":326},[323,998,822],{"class":821},[323,1000,825],{"class":531},[323,1002,828],{"class":458},[323,1004,1005,1008,1010],{"class":325,"line":333},[323,1006,1007],{"class":462},"  _meta",[323,1009,836],{"class":458},[323,1011,839],{"class":458},[323,1013,1014,1017,1020,1022,1024,1028],{"class":325,"line":347},[323,1015,1016],{"class":458},"    '",[323,1018,1019],{"class":462},"openai\u002FwidgetAccessible",[323,1021,852],{"class":458},[323,1023,836],{"class":458},[323,1025,1027],{"class":1026},"sfNiH"," true",[323,1029,1030],{"class":458},",\n",[323,1032,1033,1035,1038,1040,1042,1045,1048,1050],{"class":325,"line":358},[323,1034,1016],{"class":458},[323,1036,1037],{"class":462},"openai\u002FtoolInvocation\u002Finvoking",[323,1039,852],{"class":458},[323,1041,836],{"class":458},[323,1043,1044],{"class":458}," '",[323,1046,1047],{"class":339},"正在加载…",[323,1049,852],{"class":458},[323,1051,1030],{"class":458},[323,1053,1054,1056,1059,1061,1063,1065,1068,1070],{"class":325,"line":369},[323,1055,1016],{"class":458},[323,1057,1058],{"class":462},"openai\u002FtoolInvocation\u002Finvoked",[323,1060,852],{"class":458},[323,1062,836],{"class":458},[323,1064,1044],{"class":458},[323,1066,1067],{"class":339},"已加载",[323,1069,852],{"class":458},[323,1071,1030],{"class":458},[323,1073,1074],{"class":325,"line":897},[323,1075,894],{"class":458},[323,1077,1078,1081,1083,1086,1089,1092,1095,1098,1101,1103,1106,1109,1111,1114,1117],{"class":325,"line":903},[323,1079,1080],{"class":821},"  handler",[323,1082,836],{"class":458},[323,1084,1085],{"class":466}," async",[323,1087,1088],{"class":458}," ()",[323,1090,1091],{"class":466}," =>",[323,1093,1094],{"class":531}," (",[323,1096,1097],{"class":458},"{",[323,1099,1100],{"class":462}," structuredContent",[323,1102,836],{"class":458},[323,1104,1105],{"class":458}," {",[323,1107,1108],{"class":531}," … ",[323,1110,906],{"class":458},[323,1112,1113],{"class":458}," }",[323,1115,1116],{"class":531},")",[323,1118,1030],{"class":458},[323,1120,1122,1124],{"class":325,"line":1121},8,[323,1123,906],{"class":458},[323,1125,909],{"class":531},[288,1127,1128,1129,1132,1133,1135,1136,1138],{},"工具包会自动填充 ",[304,1130,1131],{},"_meta.ui.resourceUri","（这样宿主就可以按需重新获取 HTML）以及 ",[304,1134,915],{},"。你放入 ",[304,1137,979],{}," 的任何内容都会在其基础上进行合并。",[297,1140,1141],{"id":1141},"高级模式",[440,1143,1144],{"id":1144},"重用服务端逻辑",[288,1146,1147,1148,603,1151,916,1154,1157],{},"应用与 Nuxt 应用的其他部分共享 ",[304,1149,1150],{},"server\u002Fapi\u002F",[304,1152,1153],{},"server\u002Futils\u002F",[304,1155,1156],{},"shared\u002F","。一个典型的布局如下：",[314,1159,1161],{"className":316,"code":1160,"language":318,"meta":319,"style":319},"app\u002Fmcp\u002Fcolor-picker.vue          # UI + 调用 $fetch('\u002Fapi\u002Fpalette') 的 handler\nserver\u002Fapi\u002Fpalette.get.ts         # 实际的数据端点（人类 + 工具都可调用）\nserver\u002Futils\u002Fpalette.ts           # 共享生成器 \u002F 辅助函数\nshared\u002Ftypes\u002Fpalette.ts           # SFC 和端点都会自动导入的类型\n",[304,1162,1163,1171,1179,1187],{"__ignoreMap":319},[323,1164,1165,1168],{"class":325,"line":326},[323,1166,1167],{"class":329},"app\u002Fmcp\u002Fcolor-picker.vue",[323,1169,1170],{"class":343},"          # UI + 调用 $fetch('\u002Fapi\u002Fpalette') 的 handler\n",[323,1172,1173,1176],{"class":325,"line":333},[323,1174,1175],{"class":329},"server\u002Fapi\u002Fpalette.get.ts",[323,1177,1178],{"class":343},"         # 实际的数据端点（人类 + 工具都可调用）\n",[323,1180,1181,1184],{"class":325,"line":347},[323,1182,1183],{"class":329},"server\u002Futils\u002Fpalette.ts",[323,1185,1186],{"class":343},"           # 共享生成器 \u002F 辅助函数\n",[323,1188,1189,1192],{"class":325,"line":358},[323,1190,1191],{"class":329},"shared\u002Ftypes\u002Fpalette.ts",[323,1193,1194],{"class":343},"           # SFC 和端点都会自动导入的类型\n",[288,1196,1197,1198,1201,1202,1205,1206,1209],{},"普通 Nuxt 页面、外部客户端或 MCP App 的处理器都会以完全相同的契约访问 ",[304,1199,1200],{},"\u002Fapi\u002Fpalette","——而且位于 ",[304,1203,1204],{},"shared\u002Ftypes\u002F"," 下的类型无需 ",[304,1207,1208],{},"import"," 语句即可全局解析。",[440,1211,1212],{"id":1212},"多个处理器",[288,1214,1215,1216,1219],{},"应用在构建时会被归属到一个命名的 MCP 处理器，就像 ",[304,1217,1218],{},"server\u002Fmcp\u002Fhandlers\u002F\u003Cname>\u002F"," 下的工具和资源一样。控制归属有两种方式：",[288,1221,1222,1225],{},[309,1223,1224],{},"子文件夹约定"," — 将 SFC 放到与处理器名称匹配的子目录下：",[314,1227,1229],{"className":316,"code":1228,"language":318,"meta":319,"style":319},"app\u002Fmcp\u002F\n├── color-picker.vue          # → 处理器 'apps'（默认）\n├── finder\u002F\n│   └── stay-finder.vue       # → 处理器 'finder' (\u002Fmcp\u002Ffinder)\n└── checkout\u002F\n    └── stay-checkout.vue     # → 处理器 'checkout' (\u002Fmcp\u002Fcheckout)\n",[304,1230,1231,1236,1246,1253,1267,1274],{"__ignoreMap":319},[323,1232,1233],{"class":325,"line":326},[323,1234,1235],{"class":329},"app\u002Fmcp\u002F\n",[323,1237,1238,1240,1243],{"class":325,"line":333},[323,1239,336],{"class":329},[323,1241,1242],{"class":339}," color-picker.vue",[323,1244,1245],{"class":343},"          # → 处理器 'apps'（默认）\n",[323,1247,1248,1250],{"class":325,"line":347},[323,1249,336],{"class":329},[323,1251,1252],{"class":339}," finder\u002F\n",[323,1254,1255,1258,1261,1264],{"class":325,"line":358},[323,1256,1257],{"class":329},"│",[323,1259,1260],{"class":339},"   └──",[323,1262,1263],{"class":339}," stay-finder.vue",[323,1265,1266],{"class":343},"       # → 处理器 'finder' (\u002Fmcp\u002Ffinder)\n",[323,1268,1269,1271],{"class":325,"line":369},[323,1270,372],{"class":329},[323,1272,1273],{"class":339}," checkout\u002F\n",[323,1275,1276,1279,1282],{"class":325,"line":897},[323,1277,1278],{"class":329},"    └──",[323,1280,1281],{"class":339}," stay-checkout.vue",[323,1283,1284],{"class":343},"     # → 处理器 'checkout' (\u002Fmcp\u002Fcheckout)\n",[288,1286,1287,653,1290,1292,1293,1296,1297,1300,1301,1304],{},[309,1288,1289],{},"显式覆盖",[304,1291,822],{}," 上的 ",[304,1294,1295],{},"attachTo","（以及 ",[304,1298,1299],{},"group"," \u002F ",[304,1302,1303],{},"tags","）会覆盖文件夹默认值：",[314,1306,1311],{"className":1307,"code":1308,"filename":1309,"language":1310,"meta":319,"style":319},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Cscript setup lang=\"ts\">\ndefineMcpApp({\n  attachTo: 'finder',\n  group: 'stays',\n  tags: ['searchable'],\n  \u002F\u002F ...\n})\n\u003C\u002Fscript>\n","app\u002Fmcp\u002Fstay-finder.vue","vue",[304,1312,1313,1335,1343,1359,1375,1395,1400,1406],{"__ignoreMap":319},[323,1314,1315,1317,1319,1322,1325,1327,1329,1331,1333],{"class":325,"line":326},[323,1316,459],{"class":458},[323,1318,500],{"class":462},[323,1320,1321],{"class":466}," setup",[323,1323,1324],{"class":466}," lang",[323,1326,470],{"class":458},[323,1328,473],{"class":458},[323,1330,814],{"class":339},[323,1332,473],{"class":458},[323,1334,493],{"class":458},[323,1336,1337,1339,1341],{"class":325,"line":333},[323,1338,822],{"class":821},[323,1340,825],{"class":531},[323,1342,828],{"class":458},[323,1344,1345,1348,1350,1352,1355,1357],{"class":325,"line":347},[323,1346,1347],{"class":462},"  attachTo",[323,1349,836],{"class":458},[323,1351,1044],{"class":458},[323,1353,1354],{"class":339},"finder",[323,1356,852],{"class":458},[323,1358,1030],{"class":458},[323,1360,1361,1364,1366,1368,1371,1373],{"class":325,"line":358},[323,1362,1363],{"class":462},"  group",[323,1365,836],{"class":458},[323,1367,1044],{"class":458},[323,1369,1370],{"class":339},"stays",[323,1372,852],{"class":458},[323,1374,1030],{"class":458},[323,1376,1377,1380,1382,1384,1386,1389,1391,1393],{"class":325,"line":369},[323,1378,1379],{"class":462},"  tags",[323,1381,836],{"class":458},[323,1383,849],{"class":531},[323,1385,852],{"class":458},[323,1387,1388],{"class":339},"searchable",[323,1390,852],{"class":458},[323,1392,860],{"class":531},[323,1394,1030],{"class":458},[323,1396,1397],{"class":325,"line":897},[323,1398,1399],{"class":343},"  \u002F\u002F ...\n",[323,1401,1402,1404],{"class":325,"line":903},[323,1403,906],{"class":458},[323,1405,909],{"class":531},[323,1407,1408,1410,1412],{"class":325,"line":1121},[323,1409,537],{"class":458},[323,1411,500],{"class":462},[323,1413,493],{"class":458},[288,1415,1416],{},"然后添加匹配的处理器索引文件：",[314,1418,1421],{"className":812,"code":1419,"filename":1420,"language":814,"meta":319,"style":319},"import { defineMcpHandler } from '@nuxtjs\u002Fmcp-toolkit\u002Fserver'\n\nexport default defineMcpHandler({})\n","server\u002Fmcp\u002Fhandlers\u002Ffinder\u002Findex.ts",[304,1422,1423,1446,1452],{"__ignoreMap":319},[323,1424,1425,1428,1430,1433,1435,1438,1440,1443],{"class":325,"line":326},[323,1426,1208],{"class":1427},"s7zQu",[323,1429,1105],{"class":458},[323,1431,1432],{"class":531}," defineMcpHandler",[323,1434,1113],{"class":458},[323,1436,1437],{"class":1427}," from",[323,1439,1044],{"class":458},[323,1441,1442],{"class":339},"@nuxtjs\u002Fmcp-toolkit\u002Fserver",[323,1444,1445],{"class":458},"'\n",[323,1447,1448],{"class":325,"line":333},[323,1449,1451],{"emptyLinePlaceholder":1450},true,"\n",[323,1453,1454,1457,1460,1462,1464,1467],{"class":325,"line":347},[323,1455,1456],{"class":1427},"export",[323,1458,1459],{"class":1427}," default",[323,1461,1432],{"class":821},[323,1463,825],{"class":531},[323,1465,1466],{"class":458},"{}",[323,1468,909],{"class":531},[288,1470,1471,1472,1475,1476,1479,1480,1483,1484,916,1487,1490,1491,403],{},"在 ",[304,1473,1474],{},"defaultHandlerStrategy: 'orphans'","（默认值）下，该应用不再泄漏到 ",[304,1477,1478],{},"\u002Fmcp"," 中——它只会出现在 ",[304,1481,1482],{},"\u002Fmcp\u002Ffinder","。需要手动跨处理器汇总？",[304,1485,1486],{},"getMcpTools({ handler: 'finder' })",[304,1488,1489],{},"getMcpResources({ handler: 'finder' })"," 会返回原始定义，供你进一步筛选。参见 ",[292,1492,123],{"href":128},[426,1494,1495,603,1497,916,1499,1501,1502,1505],{"color":428,"icon":429},[304,1496,1295],{},[304,1498,1299],{},[304,1500,1303],{}," 必须是",[309,1503,1504],{},"字面量","。工具包会在构建时静态读取它们，因此路由决策在开发、构建和部署之间都是确定性的。动态表达式会以明确错误导致构建失败。",[440,1507,1508],{"id":1508},"按宿主适配",[288,1510,1511,1512,1515],{},"使用 ",[304,1513,1514],{},"hostContext"," 选择性启用宿主特定能力：",[314,1517,1519],{"className":812,"code":1518,"language":814,"meta":319,"style":319},"const isChatGpt = computed(() => typeof window !== 'undefined' && 'openai' in window)\nconst supportsFullscreen = computed(() => hostContext.value?.displayMode !== undefined)\n",[304,1520,1521,1573],{"__ignoreMap":319},[323,1522,1523,1526,1529,1531,1534,1536,1539,1541,1544,1547,1550,1552,1555,1557,1560,1562,1565,1567,1570],{"class":325,"line":326},[323,1524,1525],{"class":466},"const",[323,1527,1528],{"class":531}," isChatGpt ",[323,1530,470],{"class":458},[323,1532,1533],{"class":821}," computed",[323,1535,825],{"class":531},[323,1537,1538],{"class":458},"()",[323,1540,1091],{"class":466},[323,1542,1543],{"class":458}," typeof",[323,1545,1546],{"class":531}," window ",[323,1548,1549],{"class":458},"!==",[323,1551,1044],{"class":458},[323,1553,1554],{"class":339},"undefined",[323,1556,852],{"class":458},[323,1558,1559],{"class":458}," &&",[323,1561,1044],{"class":458},[323,1563,1564],{"class":339},"openai",[323,1566,852],{"class":458},[323,1568,1569],{"class":458}," in",[323,1571,1572],{"class":531}," window)\n",[323,1574,1575,1577,1580,1582,1584,1586,1588,1590,1593,1596,1599,1602,1605,1607,1610],{"class":325,"line":333},[323,1576,1525],{"class":466},[323,1578,1579],{"class":531}," supportsFullscreen ",[323,1581,470],{"class":458},[323,1583,1533],{"class":821},[323,1585,825],{"class":531},[323,1587,1538],{"class":458},[323,1589,1091],{"class":466},[323,1591,1592],{"class":531}," hostContext",[323,1594,1595],{"class":458},".",[323,1597,1598],{"class":531},"value",[323,1600,1601],{"class":458},"?.",[323,1603,1604],{"class":531},"displayMode ",[323,1606,1549],{"class":458},[323,1608,1609],{"class":458}," undefined",[323,1611,909],{"class":531},[288,1613,1614],{},"尽可能避免按宿主硬编码行为——桥接层已经处理了主要差异。",[440,1616,1617],{"id":1617},"测试应用",[288,1619,1620,1621,1624,1625,1628,1629,1631],{},"服务端：",[304,1622,1623],{},"handler"," 是一个普通的异步函数。直接从 ",[304,1626,1627],{},".nuxt\u002Fmcp-apps\u002F\u003Cname>.app.ts"," 导入已解析的应用定义（或通过解析器导入 SFC 的 ",[304,1630,822],{}," 参数），并使用 mock 输入直接调用该 handler。",[288,1633,1634,1635,1638,1639,1642,1643,1646],{},"iframe 端：使用 ",[304,1636,1637],{},"@vue\u002Ftest-utils"," 渲染 SFC，并通过注入 ",[304,1640,1641],{},"window.parent.postMessage"," 监听器来 stub 主机桥接。工具包自己的测试套件（",[304,1644,1645],{},"packages\u002Fnuxt-mcp-toolkit\u002Ftest\u002Fapps-handshake.test.ts","）展示了这种模式。",[426,1648,1649,1650,1652,1653,1655],{"color":428,"icon":429},"MCP Apps 中的大多数回归都源于忘记了**",[304,1651,1623],{}," 在服务端运行，而模板在客户端运行**。把它们视为 API 的两半：一半生成契约（",[304,1654,669],{},"），另一半消费它。",[297,1657,1658],{"id":1658},"限制与易踩坑",[779,1660,1661,1671,1680,1690,1696],{},[386,1662,1663,1666,1667,1670],{},[309,1664,1665],{},"每个应用只能有一个 handler。"," 如果你需要从同一个 UI 中再暴露一个工具，请在别处声明它，并通过 ",[304,1668,1669],{},"callTool('other-tool', …)"," 调用。",[386,1672,1673,1679],{},[309,1674,1675,1676,1678],{},"应用的 ",[304,1677,394],{}," 中不能使用顶层 await","——宏必须能够被静态分析。",[386,1681,1682,1689],{},[309,1683,1684,1685,1688],{},"SFC 中只允许相对导入 + 自动导入 + ",[304,1686,1687],{},"#shared"," 别名","。任何引入 Nuxt 运行时的内容都无法打包。",[386,1691,1692,1695],{},[309,1693,1694],{},"保持载荷尽量小。"," 数据会内联到 HTML 中；较大的载荷（>1 MB）会明显拖慢首次渲染。",[386,1697,1698,1704],{},[309,1699,1511,1700,1703],{},[304,1701,1702],{},"scoped"," 进行样式隔离。"," 全局样式会泄漏到各个应用，因为每个应用都会加载 Vue 的样式运行时副本。",[1706,1707,1708],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}",{"title":319,"searchDepth":333,"depth":333,"links":1710},[1711,1714,1715,1720,1722,1728],{"id":299,"depth":333,"text":299,"children":1712},[1713],{"id":442,"depth":347,"text":443},{"id":563,"depth":333,"text":563},{"id":763,"depth":333,"text":763,"children":1716},[1717,1718,1719],{"id":769,"depth":347,"text":770},{"id":923,"depth":347,"text":924},{"id":952,"depth":347,"text":953},{"id":975,"depth":333,"text":1721},"自定义 _meta",{"id":1141,"depth":333,"text":1141,"children":1723},[1724,1725,1726,1727],{"id":1144,"depth":347,"text":1144},{"id":1212,"depth":347,"text":1212},{"id":1508,"depth":347,"text":1508},{"id":1617,"depth":347,"text":1617},{"id":1658,"depth":333,"text":1658},"该工具包如何打包、提供和连接 MCP Apps —— 以及你可以在其基础上构建的模式。","md",null,{},{"icon":208},{"title":1735,"description":1736},"MCP Apps 内部机制与高级模式","了解构建流水线、主机桥接协议、安全默认配置，以及 @nuxtjs\u002Fmcp-toolkit 中 MCP Apps 可实现的高级模式。","G42ztutLyhlstzpUf2giCk1FyKaTGQ0pD-ch1WRhCJo",[1739,1741],{"title":200,"path":201,"stem":202,"description":1740,"icon":203,"children":-1},"使用 useMcpLogger() 将日志流式传递给 MCP 客户端，并捕获结构化的宽事件",{"title":210,"path":211,"stem":212,"description":1742,"icon":213,"children":-1},"从你自己的服务器路由中读取工具包发现的工具、资源和提示词，而无需重复它们的名称和描述。",1778659577355]