[{"data":1,"prerenderedAt":783},["ShallowReactive",2],{"navigation_docs":3,"-apps-csp-and-wiring":287,"-apps-csp-and-wiring-surround":778},[4,40,70,99,122,156,189,258],{"title":5,"path":6,"stem":7,"children":8,"page":39},"Getting Started","\u002Fgetting-started","1.getting-started",[9,14,19,24,29,34],{"title":10,"path":11,"stem":12,"icon":13},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-lucide-book-open",{"title":15,"path":16,"stem":17,"icon":18},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":20,"path":21,"stem":22,"icon":23},"Configuration","\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},"Tools","\u002Ftools","2.tools",[45,50,55,60,65],{"title":46,"path":47,"stem":48,"icon":49},"Overview","\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},"Annotations & input examples","\u002Ftools\u002Fannotations","2.tools\u002F2.annotations","i-lucide-badge-info",{"title":61,"path":62,"stem":63,"icon":64},"Errors & caching","\u002Ftools\u002Ferrors-caching","2.tools\u002F3.errors-caching","i-lucide-shield",{"title":66,"path":67,"stem":68,"icon":69},"Groups, files & dynamic registration","\u002Ftools\u002Fgroups-organization","2.tools\u002F4.groups-organization","i-lucide-tags",{"title":71,"path":72,"stem":73,"children":74,"page":39},"Resources","\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},"Static resources & structure","\u002Fresources\u002Fstatic-and-structure","3.resources\u002F1.static-and-structure","i-lucide-file-stack",{"title":85,"path":86,"stem":87,"icon":88},"Templates & handlers","\u002Fresources\u002Ftemplates-and-handlers","3.resources\u002F2.templates-and-handlers","i-lucide-git-branch",{"title":90,"path":91,"stem":92,"icon":93},"Metadata, content & errors","\u002Fresources\u002Fcontent-metadata-errors","3.resources\u002F3.content-metadata-errors","i-lucide-layers",{"title":95,"path":96,"stem":97,"icon":98},"Groups & organization","\u002Fresources\u002Forganization","3.resources\u002F4.organization","i-lucide-folder-tree",{"title":100,"path":101,"stem":102,"children":103,"page":39},"Prompts","\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},"Authoring & structure","\u002Fprompts\u002Fauthoring","4.prompts\u002F1.authoring","i-lucide-pen-line",{"title":114,"path":115,"stem":116,"icon":93},"Input, handler & messages","\u002Fprompts\u002Finput-handler-messages","4.prompts\u002F2.input-handler-messages",{"title":118,"path":119,"stem":120,"icon":121},"Patterns & advanced","\u002Fprompts\u002Fpatterns-advanced","4.prompts\u002F3.patterns-advanced","i-lucide-line-chart",{"title":123,"path":124,"stem":125,"children":126,"page":39},"Handlers","\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},"Default & custom handlers","\u002Fhandlers\u002Fdefault-and-custom","5.handlers\u002F1.default-and-custom","i-lucide-toggle-left",{"title":137,"path":138,"stem":139,"icon":140},"Structure & options","\u002Fhandlers\u002Fstructure-and-options","5.handlers\u002F2.structure-and-options","i-lucide-sliders-horizontal",{"title":142,"path":143,"stem":144,"icon":145},"Examples & routing","\u002Fhandlers\u002Fexamples-routing","5.handlers\u002F3.examples-routing","i-lucide-route",{"title":147,"path":148,"stem":149,"icon":150},"Sharing & practices","\u002Fhandlers\u002Fsharing-practices","5.handlers\u002F4.sharing-practices","i-lucide-share-2",{"title":152,"path":153,"stem":154,"icon":155},"Multi-handler organization","\u002Fhandlers\u002Forganization","5.handlers\u002F5.organization","i-lucide-network",{"title":157,"path":158,"stem":159,"children":160,"page":39},"Apps","\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},"Authoring & defineMcpApp","\u002Fapps\u002Fauthoring","6.apps\u002F1.authoring","i-lucide-code-2",{"title":171,"path":172,"stem":173,"icon":174},"useMcpApp() bridge","\u002Fapps\u002Fuse-mcp-app","6.apps\u002F2.use-mcp-app","i-lucide-message-circle",{"title":176,"path":177,"stem":178,"icon":64},"CSP & build pipeline","\u002Fapps\u002Fcsp-and-wiring","6.apps\u002F3.csp-and-wiring",{"title":180,"path":181,"stem":182,"icon":183},"Testing & publishing","\u002Fapps\u002Ftesting-publishing","6.apps\u002F4.testing-publishing","i-lucide-rocket",{"title":185,"path":186,"stem":187,"icon":188},"Patterns & limits","\u002Fapps\u002Fpatterns-reference","6.apps\u002F5.patterns-reference","i-lucide-book-marked",{"title":190,"path":191,"stem":192,"children":193,"page":39},"Advanced Topics","\u002Fadvanced","7.advanced",[194,199,204,209,214,219,223,228,233,238,243,248,253],{"title":195,"path":196,"stem":197,"icon":198},"Custom Paths","\u002Fadvanced\u002Fcustom-paths","7.advanced\u002F1.custom-paths","i-lucide-folder",{"title":200,"path":201,"stem":202,"icon":203},"Logging","\u002Fadvanced\u002Flogging","7.advanced\u002F10.logging","i-lucide-scroll-text",{"title":205,"path":206,"stem":207,"icon":208},"MCP Apps Internals","\u002Fadvanced\u002Fmcp-apps-internals","7.advanced\u002F11.mcp-apps-internals","i-lucide-cog",{"title":210,"path":211,"stem":212,"icon":213},"Listing Definitions","\u002Fadvanced\u002Flisting-definitions","7.advanced\u002F12.listing-definitions","i-lucide-list",{"title":215,"path":216,"stem":217,"icon":218},"llms.txt discovery","\u002Fadvanced\u002Fllms-txt","7.advanced\u002F13.llms-txt","i-lucide-file-text",{"title":220,"path":221,"stem":222,"icon":64},"Middleware","\u002Fadvanced\u002Fmiddleware","7.advanced\u002F2.middleware",{"title":224,"path":225,"stem":226,"icon":227},"TypeScript","\u002Fadvanced\u002Ftypescript","7.advanced\u002F3.typescript","i-lucide-type",{"title":229,"path":230,"stem":231,"icon":232},"Hooks","\u002Fadvanced\u002Fhooks","7.advanced\u002F4.hooks","i-lucide-webhook",{"title":234,"path":235,"stem":236,"icon":237},"MCP Evals","\u002Fadvanced\u002Fevals","7.advanced\u002F5.evals","i-lucide-flask-conical",{"title":239,"path":240,"stem":241,"icon":242},"Sessions","\u002Fadvanced\u002Fsessions","7.advanced\u002F6.sessions","i-lucide-database",{"title":244,"path":245,"stem":246,"icon":247},"Dynamic Definitions","\u002Fadvanced\u002Fdynamic-definitions","7.advanced\u002F7.dynamic-definitions","i-lucide-toggle-right",{"title":249,"path":250,"stem":251,"icon":252},"Code Mode","\u002Fadvanced\u002Fcode-mode","7.advanced\u002F8.code-mode","i-lucide-code",{"title":254,"path":255,"stem":256,"icon":257},"Elicitation","\u002Fadvanced\u002Felicitation","7.advanced\u002F9.elicitation","i-lucide-message-square-quote",{"title":259,"path":260,"stem":261,"children":262,"page":39},"Examples","\u002Fexamples","8.examples",[263,268,273,278,283],{"title":264,"path":265,"stem":266,"icon":267},"Authentication","\u002Fexamples\u002Fauthentication","8.examples\u002F1.authentication","i-lucide-shield-check",{"title":269,"path":270,"stem":271,"icon":272},"API Integration","\u002Fexamples\u002Fapi-integration","8.examples\u002F2.api-integration","i-lucide-globe",{"title":274,"path":275,"stem":276,"icon":277},"Common Patterns","\u002Fexamples\u002Fcommon-patterns","8.examples\u002F3.common-patterns","i-lucide-lightbulb",{"title":279,"path":280,"stem":281,"icon":282},"File Operations","\u002Fexamples\u002Ffile-operations","8.examples\u002F4.file-operations","i-lucide-file",{"title":284,"path":285,"stem":286,"icon":107},"Prompt Examples","\u002Fexamples\u002Fprompt-examples","8.examples\u002F5.prompt-examples",{"id":288,"title":176,"body":289,"description":769,"extension":770,"links":771,"meta":772,"navigation":773,"path":177,"seo":774,"stem":178,"__hash__":777},"docs\u002F6.apps\u002F3.csp-and-wiring.md",{"type":290,"value":291,"toc":765},"minimark",[292,297,306,324,327,569,580,589,651,662,666,677,707,710,752,761],[293,294,296],"h2",{"id":295},"csp-resource-allow-lists","CSP & Resource Allow-Lists",[298,299,300,301,305],"p",{},"The toolkit injects a ",[302,303,304],"strong",{},"conservative Content Security Policy"," into every app HTML. By default the iframe can:",[307,308,309,313,316],"ul",{},[310,311,312],"li",{},"Run only its own inline script.",[310,314,315],{},"Render images and styles only from the same response.",[310,317,318,319,323],{},"Talk over ",[320,321,322],"code",{},"postMessage"," to its parent host.",[298,325,326],{},"If your UI needs external assets or APIs, allow them explicitly:",[328,329,335],"pre",{"className":330,"code":331,"filename":332,"language":333,"meta":334,"style":334},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Cscript setup lang=\"ts\">\ndefineMcpApp({\n  description: 'Pick a colour and preview a palette.',\n  csp: {\n    resourceDomains: ['https:\u002F\u002Fimages.unsplash.com'],\n    connectDomains: ['https:\u002F\u002Fapi.example.com'],\n  },\n  handler: async ({ base }) => ({ structuredContent: await $fetch('\u002Fapi\u002Fpalette', { query: { base } }) }),\n})\n\u003C\u002Fscript>\n","app\u002Fmcp\u002Fcolor-picker.vue","vue","",[320,336,337,372,386,407,418,441,462,468,551,559],{"__ignoreMap":334},[338,339,342,346,350,354,357,360,363,367,369],"span",{"class":340,"line":341},"line",1,[338,343,345],{"class":344},"sMK4o","\u003C",[338,347,349],{"class":348},"swJcz","script",[338,351,353],{"class":352},"spNyl"," setup",[338,355,356],{"class":352}," lang",[338,358,359],{"class":344},"=",[338,361,362],{"class":344},"\"",[338,364,366],{"class":365},"sfazB","ts",[338,368,362],{"class":344},[338,370,371],{"class":344},">\n",[338,373,375,379,383],{"class":340,"line":374},2,[338,376,378],{"class":377},"s2Zo4","defineMcpApp",[338,380,382],{"class":381},"sTEyZ","(",[338,384,385],{"class":344},"{\n",[338,387,389,392,395,398,401,404],{"class":340,"line":388},3,[338,390,391],{"class":348},"  description",[338,393,394],{"class":344},":",[338,396,397],{"class":344}," '",[338,399,400],{"class":365},"Pick a colour and preview a palette.",[338,402,403],{"class":344},"'",[338,405,406],{"class":344},",\n",[338,408,410,413,415],{"class":340,"line":409},4,[338,411,412],{"class":348},"  csp",[338,414,394],{"class":344},[338,416,417],{"class":344}," {\n",[338,419,421,424,426,429,431,434,436,439],{"class":340,"line":420},5,[338,422,423],{"class":348},"    resourceDomains",[338,425,394],{"class":344},[338,427,428],{"class":381}," [",[338,430,403],{"class":344},[338,432,433],{"class":365},"https:\u002F\u002Fimages.unsplash.com",[338,435,403],{"class":344},[338,437,438],{"class":381},"]",[338,440,406],{"class":344},[338,442,444,447,449,451,453,456,458,460],{"class":340,"line":443},6,[338,445,446],{"class":348},"    connectDomains",[338,448,394],{"class":344},[338,450,428],{"class":381},[338,452,403],{"class":344},[338,454,455],{"class":365},"https:\u002F\u002Fapi.example.com",[338,457,403],{"class":344},[338,459,438],{"class":381},[338,461,406],{"class":344},[338,463,465],{"class":340,"line":464},7,[338,466,467],{"class":344},"  },\n",[338,469,471,474,476,479,482,486,489,492,495,498,501,503,507,510,512,514,517,519,522,525,528,530,532,535,538,541,544,546,549],{"class":340,"line":470},8,[338,472,473],{"class":377},"  handler",[338,475,394],{"class":344},[338,477,478],{"class":352}," async",[338,480,481],{"class":344}," ({",[338,483,485],{"class":484},"sHdIc"," base",[338,487,488],{"class":344}," })",[338,490,491],{"class":352}," =>",[338,493,494],{"class":381}," (",[338,496,497],{"class":344},"{",[338,499,500],{"class":348}," structuredContent",[338,502,394],{"class":344},[338,504,506],{"class":505},"s7zQu"," await",[338,508,509],{"class":377}," $fetch",[338,511,382],{"class":381},[338,513,403],{"class":344},[338,515,516],{"class":365},"\u002Fapi\u002Fpalette",[338,518,403],{"class":344},[338,520,521],{"class":344},",",[338,523,524],{"class":344}," {",[338,526,527],{"class":348}," query",[338,529,394],{"class":344},[338,531,524],{"class":344},[338,533,534],{"class":381}," base ",[338,536,537],{"class":344},"}",[338,539,540],{"class":344}," }",[338,542,543],{"class":381},") ",[338,545,537],{"class":344},[338,547,548],{"class":381},")",[338,550,406],{"class":344},[338,552,554,556],{"class":340,"line":553},9,[338,555,537],{"class":344},[338,557,558],{"class":381},")\n",[338,560,562,565,567],{"class":340,"line":561},10,[338,563,564],{"class":344},"\u003C\u002F",[338,566,349],{"class":348},[338,568,371],{"class":344},[298,570,571,572,575,576,579],{},"The CSP is mirrored into ",[320,573,574],{},"_meta.ui.csp"," (and ",[320,577,578],{},"openai\u002FwidgetCSP"," for ChatGPT) so hosts that enforce CSP at the iframe level pick up the same rules.",[581,582,584,585,588],"callout",{"color":583,"icon":64},"warning","Pass ",[320,586,587],{},"csp: false"," only as a last resort — and only if you fully control the assets the iframe loads. The default policy is what makes apps safe to render across hosts.",[590,591,592,605],"table",{},[593,594,595],"thead",{},[596,597,598,602],"tr",{},[599,600,601],"th",{},"Field",[599,603,604],{},"What it allows",[606,607,608,629],"tbody",{},[596,609,610,616],{},[611,612,613],"td",{},[320,614,615],{},"resourceDomains",[611,617,618,621,622,621,625,628],{},[320,619,620],{},"\u003Cimg>",", ",[320,623,624],{},"\u003Cstyle>",[320,626,627],{},"\u003Clink>",", fonts loaded from these origins",[596,630,631,636],{},[611,632,633],{},[320,634,635],{},"connectDomains",[611,637,638,621,641,621,644,621,647,650],{},[320,639,640],{},"fetch()",[320,642,643],{},"XHR",[320,645,646],{},"WebSocket",[320,648,649],{},"EventSource"," to these origins",[298,652,653,654,657,658,661],{},"Origins should use ",[320,655,656],{},"http(s):\u002F\u002F"," or ",[320,659,660],{},"ws(s):\u002F\u002F",". The toolkit rejects empty values, unsupported URL schemes, whitespace, quotes, and semicolons before the app response is served.",[293,663,665],{"id":664},"how-its-wired","How It's Wired",[298,667,668,669,672,673,676],{},"Behind the scenes, each ",[320,670,671],{},".vue"," file under the configured apps directory becomes ",[302,674,675],{},"three artifacts"," at build time:",[678,679,680,687,701],"ol",{},[310,681,682,683,686],{},"A ",[302,684,685],{},"tool definition"," registered on your MCP handler (input schema, description, server handler).",[310,688,682,689,692,693,696,697,700],{},[302,690,691],{},"UI resource"," at ",[320,694,695],{},"ui:\u002F\u002Fmcp-app\u002F\u003Cname>"," returning ",[320,698,699],{},"text\u002Fhtml;profile=mcp-app",".",[310,702,682,703,706],{},[302,704,705],{},"single-file HTML bundle"," of the Vue SFC (Vue runtime, your code, scoped CSS, assets) inlined into the resource response.",[298,708,709],{},"When the LLM calls the tool:",[678,711,712,722,728,739],{},[310,713,714,715,718,719,700],{},"Your ",[320,716,717],{},"handler"," runs on the server and produces ",[320,720,721],{},"structuredContent",[310,723,724,725,700],{},"The toolkit injects that data into the bundled HTML as ",[320,726,727],{},"\u003Cscript type=\"application\u002Fjson\" id=\"__mcp_app_data__\">…\u003C\u002Fscript>",[310,729,730,731,734,735,738],{},"The host returns the resource to the user; its iframe boots and ",[320,732,733],{},"useMcpApp()"," reads the inline data into ",[320,736,737],{},"data"," synchronously.",[310,740,741,742,621,745,621,748,751],{},"From there, the iframe and the host exchange messages over a JSON-RPC bridge for ",[320,743,744],{},"callTool",[320,746,747],{},"sendPrompt",[320,749,750],{},"openLink",", and theme\u002Fsize updates.",[581,753,756,757,760],{"color":754,"icon":755},"primary","i-lucide-zap","Everything ships in ",[302,758,759],{},"one HTML response",". No extra HTTP request from the iframe, no waterfall, no flicker.",[762,763,764],"style",{},"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 .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}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}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);}",{"title":334,"searchDepth":374,"depth":374,"links":766},[767,768],{"id":295,"depth":374,"text":296},{"id":664,"depth":374,"text":665},"Content Security Policy, allow-listed domains, and how HTML bundles are produced.","md",null,{},{"icon":64},{"title":775,"description":776},"MCP Apps — CSP & wiring","iframe CSP, external assets, and the build pipeline for MCP UI resources.","MwH9uAcFyCGJauuZqpXoURyvbJKcNGBSF-v-00hjJQM",[779,781],{"title":171,"path":172,"stem":173,"description":780,"icon":174,"children":-1},"data, hostContext, sendPrompt, callTool, and openLink from inside the iframe.",{"title":180,"path":181,"stem":182,"description":782,"icon":183,"children":-1},"Test MCP Apps locally, pick a compatible host, and ship HTTPS endpoints for ChatGPT, Claude, and IDE clients.",1787670842248]