[{"data":1,"prerenderedAt":4221},["ShallowReactive",2],{"navigation_docs":3,"-core-concepts-apps":159,"-core-concepts-apps-surround":4216},[4,40,70,130],{"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},"MCP 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},"Core Concepts","\u002Fcore-concepts","2.core-concepts",[45,50,55,60,65],{"title":46,"path":47,"stem":48,"icon":49},"Tools","\u002Fcore-concepts\u002Ftools","2.core-concepts\u002F2.tools","i-lucide-wrench",{"title":51,"path":52,"stem":53,"icon":54},"Resources","\u002Fcore-concepts\u002Fresources","2.core-concepts\u002F3.resources","i-lucide-package",{"title":56,"path":57,"stem":58,"icon":59},"Prompts","\u002Fcore-concepts\u002Fprompts","2.core-concepts\u002F4.prompts","i-lucide-message-square",{"title":61,"path":62,"stem":63,"icon":64},"Handlers","\u002Fcore-concepts\u002Fhandlers","2.core-concepts\u002F5.handlers","i-lucide-server",{"title":66,"path":67,"stem":68,"icon":69},"Apps","\u002Fcore-concepts\u002Fapps","2.core-concepts\u002F6.apps","i-lucide-app-window",{"title":71,"path":72,"stem":73,"children":74,"page":39},"Advanced Topics","\u002Fadvanced","3.advanced",[75,80,85,90,95,100,105,110,115,120,125],{"title":76,"path":77,"stem":78,"icon":79},"Custom Paths","\u002Fadvanced\u002Fcustom-paths","3.advanced\u002F1.custom-paths","i-lucide-folder",{"title":81,"path":82,"stem":83,"icon":84},"Logging","\u002Fadvanced\u002Flogging","3.advanced\u002F10.logging","i-lucide-scroll-text",{"title":86,"path":87,"stem":88,"icon":89},"MCP Apps Internals","\u002Fadvanced\u002Fmcp-apps-internals","3.advanced\u002F11.mcp-apps-internals","i-lucide-cog",{"title":91,"path":92,"stem":93,"icon":94},"Middleware","\u002Fadvanced\u002Fmiddleware","3.advanced\u002F2.middleware","i-lucide-shield",{"title":96,"path":97,"stem":98,"icon":99},"TypeScript","\u002Fadvanced\u002Ftypescript","3.advanced\u002F3.typescript","i-lucide-type",{"title":101,"path":102,"stem":103,"icon":104},"Hooks","\u002Fadvanced\u002Fhooks","3.advanced\u002F4.hooks","i-lucide-webhook",{"title":106,"path":107,"stem":108,"icon":109},"MCP Evals","\u002Fadvanced\u002Fevals","3.advanced\u002F5.evals","i-lucide-flask-conical",{"title":111,"path":112,"stem":113,"icon":114},"Sessions","\u002Fadvanced\u002Fsessions","3.advanced\u002F6.sessions","i-lucide-database",{"title":116,"path":117,"stem":118,"icon":119},"Dynamic Definitions","\u002Fadvanced\u002Fdynamic-definitions","3.advanced\u002F7.dynamic-definitions","i-lucide-toggle-right",{"title":121,"path":122,"stem":123,"icon":124},"Code Mode","\u002Fadvanced\u002Fcode-mode","3.advanced\u002F8.code-mode","i-lucide-code",{"title":126,"path":127,"stem":128,"icon":129},"Elicitation","\u002Fadvanced\u002Felicitation","3.advanced\u002F9.elicitation","i-lucide-message-square-quote",{"title":131,"path":132,"stem":133,"children":134,"page":39},"Examples","\u002Fexamples","4.examples",[135,140,145,150,155],{"title":136,"path":137,"stem":138,"icon":139},"Authentication","\u002Fexamples\u002Fauthentication","4.examples\u002F1.authentication","i-lucide-shield-check",{"title":141,"path":142,"stem":143,"icon":144},"API Integration","\u002Fexamples\u002Fapi-integration","4.examples\u002F2.api-integration","i-lucide-globe",{"title":146,"path":147,"stem":148,"icon":149},"Common Patterns","\u002Fexamples\u002Fcommon-patterns","4.examples\u002F3.common-patterns","i-lucide-lightbulb",{"title":151,"path":152,"stem":153,"icon":154},"File Operations","\u002Fexamples\u002Ffile-operations","4.examples\u002F4.file-operations","i-lucide-file",{"title":156,"path":157,"stem":158,"icon":59},"Prompt Examples","\u002Fexamples\u002Fprompt-examples","4.examples\u002F5.prompt-examples",{"id":160,"title":66,"body":161,"description":4207,"extension":4208,"links":4209,"meta":4210,"navigation":4211,"path":67,"seo":4212,"stem":68,"__hash__":4215},"docs\u002F2.core-concepts\u002F6.apps.md",{"type":162,"value":163,"toc":4174},"minimark",[164,169,178,206,212,246,351,355,358,1239,1242,1296,1300,1323,1374,1392,1397,1407,1480,1491,1496,1507,1647,1651,1666,1825,1841,1851,1855,1869,1933,2046,2225,2228,2233,2240,2348,2351,2359,2390,2484,2490,2500,2669,2865,2873,2880,2883,2964,2971,2980,2987,2993,3114,3117,3123,3130,3200,3211,3215,3222,3236,3239,3417,3428,3435,3490,3501,3505,3516,3540,3543,3579,3586,3590,3684,3692,3696,3702,3713,3788,3792,3795,3858,3862,3867,3928,3931,3935,3941,3945,3951,3990,3993,4038,4045,4049,4164,4171],[165,166,168],"h2",{"id":167},"what-are-mcp-apps","What are MCP Apps?",[170,171,172,173,177],"p",{},"MCP Apps are ",[174,175,176],"strong",{},"interactive HTML widgets"," returned by an MCP tool and rendered inline by compatible hosts. Instead of streaming back text, your tool ships a small UI that the user can read, scroll, filter, and click — connected back to your server through a typed message bridge.",[170,179,180,181,188,189,193,194,197,198,201,202,205],{},"They follow the ",[182,183,187],"a",{"href":184,"rel":185},"https:\u002F\u002Fmodelcontextprotocol.io",[186],"nofollow","MCP UI proposal (SEP-1865)",": a tool returns a ",[190,191,192],"code",{},"text\u002Fhtml;profile=mcp-app"," resource referenced by ",[190,195,196],{},"ui:\u002F\u002F",", the host loads it inside a sandboxed ",[190,199,200],{},"iframe",", and the iframe talks back over ",[190,203,204],{},"postMessage",".",[170,207,208,211],{},[190,209,210],{},"@nuxtjs\u002Fmcp-toolkit"," makes that authoring experience feel like writing a regular Nuxt page:",[213,214,215,226,237,243],"ul",{},[216,217,218,219,222,223,205],"li",{},"One ",[174,220,221],{},"Vue SFC"," per app in ",[190,224,225],{},"app\u002Fmcp\u002F",[216,227,228,229,232,233,236],{},"A ",[190,230,231],{},"defineMcpApp"," macro inside ",[190,234,235],{},"\u003Cscript setup>"," declares the tool, schema, and server handler.",[216,238,228,239,242],{},[190,240,241],{},"useMcpApp()"," composable gives you reactive data, host context, and a typed bridge to the host.",[216,244,245],{},"The toolkit bundles the SFC into a single self-contained HTML file at build time and serves it from your MCP endpoint.",[247,248,249],"code-collapse",{},[250,251,257],"pre",{"className":252,"code":253,"filename":254,"language":255,"meta":256,"style":256},"language-txt shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","Create a new MCP App in my Nuxt app using @nuxtjs\u002Fmcp-toolkit.\n\n- Create a Vue SFC in app\u002Fmcp\u002F (e.g. app\u002Fmcp\u002Fcolor-picker.vue)\n- Use defineMcpApp({ description, inputSchema, handler }) inside \u003Cscript setup lang=\"ts\">\n- inputSchema uses Zod; handler runs server-side and returns { structuredContent }\n- handler can call any Nuxt API route via $fetch — keep heavy data work on the server\n- In the template, call useMcpApp\u003CTPayload>() to get { data, loading, hostContext, sendPrompt, callTool, openLink }\n- data is hydrated from structuredContent on first render — no extra request\n- Use sendPrompt(text) to push a follow-up into the chat that triggers another tool\u002Fapp\n- Use callTool(name, params) to re-invoke an MCP tool and refresh data in place\n- Use openLink(url) to ask the host to open a URL outside the iframe\n- Add CSP allow-lists with csp: { resourceDomains, connectDomains } if you load images or call external APIs\n- Make the layout fluid (no fixed heights); hosts often render the iframe inline at variable widths\n\nDocs: https:\u002F\u002Fmcp-toolkit.nuxt.dev\u002Fcore-concepts\u002Fapps\n","Prompt","txt","",[190,258,259,267,274,280,286,292,298,304,310,316,322,328,334,340,345],{"__ignoreMap":256},[260,261,264],"span",{"class":262,"line":263},"line",1,[260,265,266],{},"Create a new MCP App in my Nuxt app using @nuxtjs\u002Fmcp-toolkit.\n",[260,268,270],{"class":262,"line":269},2,[260,271,273],{"emptyLinePlaceholder":272},true,"\n",[260,275,277],{"class":262,"line":276},3,[260,278,279],{},"- Create a Vue SFC in app\u002Fmcp\u002F (e.g. app\u002Fmcp\u002Fcolor-picker.vue)\n",[260,281,283],{"class":262,"line":282},4,[260,284,285],{},"- Use defineMcpApp({ description, inputSchema, handler }) inside \u003Cscript setup lang=\"ts\">\n",[260,287,289],{"class":262,"line":288},5,[260,290,291],{},"- inputSchema uses Zod; handler runs server-side and returns { structuredContent }\n",[260,293,295],{"class":262,"line":294},6,[260,296,297],{},"- handler can call any Nuxt API route via $fetch — keep heavy data work on the server\n",[260,299,301],{"class":262,"line":300},7,[260,302,303],{},"- In the template, call useMcpApp\u003CTPayload>() to get { data, loading, hostContext, sendPrompt, callTool, openLink }\n",[260,305,307],{"class":262,"line":306},8,[260,308,309],{},"- data is hydrated from structuredContent on first render — no extra request\n",[260,311,313],{"class":262,"line":312},9,[260,314,315],{},"- Use sendPrompt(text) to push a follow-up into the chat that triggers another tool\u002Fapp\n",[260,317,319],{"class":262,"line":318},10,[260,320,321],{},"- Use callTool(name, params) to re-invoke an MCP tool and refresh data in place\n",[260,323,325],{"class":262,"line":324},11,[260,326,327],{},"- Use openLink(url) to ask the host to open a URL outside the iframe\n",[260,329,331],{"class":262,"line":330},12,[260,332,333],{},"- Add CSP allow-lists with csp: { resourceDomains, connectDomains } if you load images or call external APIs\n",[260,335,337],{"class":262,"line":336},13,[260,338,339],{},"- Make the layout fluid (no fixed heights); hosts often render the iframe inline at variable widths\n",[260,341,343],{"class":262,"line":342},14,[260,344,273],{"emptyLinePlaceholder":272},[260,346,348],{"class":262,"line":347},15,[260,349,350],{},"Docs: https:\u002F\u002Fmcp-toolkit.nuxt.dev\u002Fcore-concepts\u002Fapps\n",[165,352,354],{"id":353},"quick-start","Quick Start",[170,356,357],{},"A complete app — schema, server handler, UI — in one file:",[250,359,364],{"className":360,"code":361,"filename":362,"language":363,"meta":256,"style":256},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Cscript setup lang=\"ts\">\nimport { z } from 'zod'\n\ninterface PalettePayload {\n  base: string\n  swatches: { name: string, hex: string }[]\n}\n\ndefineMcpApp({\n  description: 'Pick a colour and preview a 5-tone palette.',\n  inputSchema: {\n    base: z.string().describe('Hex colour to anchor the palette, e.g. #2563eb'),\n  },\n  handler: async ({ base }): Promise\u003C{ structuredContent: PalettePayload }> => {\n    const swatches = await $fetch\u003C{ name: string, hex: string }[]>('\u002Fapi\u002Fpalette', {\n      query: { base },\n    })\n    return { structuredContent: { base, swatches } }\n  },\n})\n\nconst { data, loading, sendPrompt } = useMcpApp\u003CPalettePayload>()\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cmain class=\"picker\">\n    \u003Cp v-if=\"loading\">\n      Mixing colours…\n    \u003C\u002Fp>\n    \u003Cul v-else-if=\"data\" class=\"swatches\">\n      \u003Cli v-for=\"s in data.swatches\" :key=\"s.hex\">\n        \u003Cbutton\n          type=\"button\"\n          :style=\"{ background: s.hex }\"\n          @click=\"sendPrompt(`Use ${s.name} (${s.hex}) as the primary colour.`)\"\n        >\n          {{ s.name }}\n        \u003C\u002Fbutton>\n      \u003C\u002Fli>\n    \u003C\u002Ful>\n  \u003C\u002Fmain>\n\u003C\u002Ftemplate>\n\n\u003Cstyle scoped>\n.picker { padding: 16px; font-family: system-ui, sans-serif; }\n.swatches { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; padding: 0; list-style: none; }\n.swatches button { width: 100%; aspect-ratio: 1; border-radius: 8px; border: 0; cursor: pointer; }\n\u003C\u002Fstyle>\n","app\u002Fmcp\u002Fcolor-picker.vue","vue",[190,365,366,398,426,430,442,453,485,490,494,505,523,532,568,573,614,668,683,692,717,722,730,735,773,783,788,798,821,843,849,859,891,925,934,950,965,980,986,992,1002,1012,1021,1031,1040,1045,1058,1097,1168,1230],{"__ignoreMap":256},[260,367,368,372,376,380,383,386,389,393,395],{"class":262,"line":263},[260,369,371],{"class":370},"sMK4o","\u003C",[260,373,375],{"class":374},"swJcz","script",[260,377,379],{"class":378},"spNyl"," setup",[260,381,382],{"class":378}," lang",[260,384,385],{"class":370},"=",[260,387,388],{"class":370},"\"",[260,390,392],{"class":391},"sfazB","ts",[260,394,388],{"class":370},[260,396,397],{"class":370},">\n",[260,399,400,404,407,411,414,417,420,423],{"class":262,"line":269},[260,401,403],{"class":402},"s7zQu","import",[260,405,406],{"class":370}," {",[260,408,410],{"class":409},"sTEyZ"," z",[260,412,413],{"class":370}," }",[260,415,416],{"class":402}," from",[260,418,419],{"class":370}," '",[260,421,422],{"class":391},"zod",[260,424,425],{"class":370},"'\n",[260,427,428],{"class":262,"line":276},[260,429,273],{"emptyLinePlaceholder":272},[260,431,432,435,439],{"class":262,"line":282},[260,433,434],{"class":378},"interface",[260,436,438],{"class":437},"sBMFI"," PalettePayload",[260,440,441],{"class":370}," {\n",[260,443,444,447,450],{"class":262,"line":288},[260,445,446],{"class":374},"  base",[260,448,449],{"class":370},":",[260,451,452],{"class":437}," string\n",[260,454,455,458,460,462,465,467,470,473,476,478,480,482],{"class":262,"line":294},[260,456,457],{"class":374},"  swatches",[260,459,449],{"class":370},[260,461,406],{"class":370},[260,463,464],{"class":374}," name",[260,466,449],{"class":370},[260,468,469],{"class":437}," string",[260,471,472],{"class":370},",",[260,474,475],{"class":374}," hex",[260,477,449],{"class":370},[260,479,469],{"class":437},[260,481,413],{"class":370},[260,483,484],{"class":409},"[]\n",[260,486,487],{"class":262,"line":300},[260,488,489],{"class":370},"}\n",[260,491,492],{"class":262,"line":306},[260,493,273],{"emptyLinePlaceholder":272},[260,495,496,499,502],{"class":262,"line":312},[260,497,231],{"class":498},"s2Zo4",[260,500,501],{"class":409},"(",[260,503,504],{"class":370},"{\n",[260,506,507,510,512,514,517,520],{"class":262,"line":318},[260,508,509],{"class":374},"  description",[260,511,449],{"class":370},[260,513,419],{"class":370},[260,515,516],{"class":391},"Pick a colour and preview a 5-tone palette.",[260,518,519],{"class":370},"'",[260,521,522],{"class":370},",\n",[260,524,525,528,530],{"class":262,"line":324},[260,526,527],{"class":374},"  inputSchema",[260,529,449],{"class":370},[260,531,441],{"class":370},[260,533,534,537,539,541,543,546,549,551,554,556,558,561,563,566],{"class":262,"line":330},[260,535,536],{"class":374},"    base",[260,538,449],{"class":370},[260,540,410],{"class":409},[260,542,205],{"class":370},[260,544,545],{"class":498},"string",[260,547,548],{"class":409},"()",[260,550,205],{"class":370},[260,552,553],{"class":498},"describe",[260,555,501],{"class":409},[260,557,519],{"class":370},[260,559,560],{"class":391},"Hex colour to anchor the palette, e.g. #2563eb",[260,562,519],{"class":370},[260,564,565],{"class":409},")",[260,567,522],{"class":370},[260,569,570],{"class":262,"line":336},[260,571,572],{"class":370},"  },\n",[260,574,575,578,580,583,586,590,593,596,599,602,604,606,609,612],{"class":262,"line":342},[260,576,577],{"class":498},"  handler",[260,579,449],{"class":370},[260,581,582],{"class":378}," async",[260,584,585],{"class":370}," ({",[260,587,589],{"class":588},"sHdIc"," base",[260,591,592],{"class":370}," }):",[260,594,595],{"class":437}," Promise",[260,597,598],{"class":370},"\u003C{",[260,600,601],{"class":374}," structuredContent",[260,603,449],{"class":370},[260,605,438],{"class":437},[260,607,608],{"class":370}," }>",[260,610,611],{"class":378}," =>",[260,613,441],{"class":370},[260,615,616,619,622,625,628,631,633,635,637,639,641,643,645,647,649,652,655,657,659,662,664,666],{"class":262,"line":347},[260,617,618],{"class":378},"    const",[260,620,621],{"class":409}," swatches",[260,623,624],{"class":370}," =",[260,626,627],{"class":402}," await",[260,629,630],{"class":498}," $fetch",[260,632,598],{"class":370},[260,634,464],{"class":374},[260,636,449],{"class":370},[260,638,469],{"class":437},[260,640,472],{"class":370},[260,642,475],{"class":374},[260,644,449],{"class":370},[260,646,469],{"class":437},[260,648,413],{"class":370},[260,650,651],{"class":374},"[]",[260,653,654],{"class":370},">",[260,656,501],{"class":374},[260,658,519],{"class":370},[260,660,661],{"class":391},"\u002Fapi\u002Fpalette",[260,663,519],{"class":370},[260,665,472],{"class":370},[260,667,441],{"class":370},[260,669,671,674,676,678,680],{"class":262,"line":670},16,[260,672,673],{"class":374},"      query",[260,675,449],{"class":370},[260,677,406],{"class":370},[260,679,589],{"class":409},[260,681,682],{"class":370}," },\n",[260,684,686,689],{"class":262,"line":685},17,[260,687,688],{"class":370},"    }",[260,690,691],{"class":374},")\n",[260,693,695,698,700,702,704,706,708,710,712,714],{"class":262,"line":694},18,[260,696,697],{"class":402},"    return",[260,699,406],{"class":370},[260,701,601],{"class":374},[260,703,449],{"class":370},[260,705,406],{"class":370},[260,707,589],{"class":409},[260,709,472],{"class":370},[260,711,621],{"class":409},[260,713,413],{"class":370},[260,715,716],{"class":370}," }\n",[260,718,720],{"class":262,"line":719},19,[260,721,572],{"class":370},[260,723,725,728],{"class":262,"line":724},20,[260,726,727],{"class":370},"}",[260,729,691],{"class":409},[260,731,733],{"class":262,"line":732},21,[260,734,273],{"emptyLinePlaceholder":272},[260,736,738,741,743,746,748,751,753,756,758,760,763,765,768,770],{"class":262,"line":737},22,[260,739,740],{"class":378},"const",[260,742,406],{"class":370},[260,744,745],{"class":409}," data",[260,747,472],{"class":370},[260,749,750],{"class":409}," loading",[260,752,472],{"class":370},[260,754,755],{"class":409}," sendPrompt ",[260,757,727],{"class":370},[260,759,624],{"class":370},[260,761,762],{"class":498}," useMcpApp",[260,764,371],{"class":370},[260,766,767],{"class":437},"PalettePayload",[260,769,654],{"class":370},[260,771,772],{"class":409},"()\n",[260,774,776,779,781],{"class":262,"line":775},23,[260,777,778],{"class":370},"\u003C\u002F",[260,780,375],{"class":374},[260,782,397],{"class":370},[260,784,786],{"class":262,"line":785},24,[260,787,273],{"emptyLinePlaceholder":272},[260,789,791,793,796],{"class":262,"line":790},25,[260,792,371],{"class":370},[260,794,795],{"class":374},"template",[260,797,397],{"class":370},[260,799,801,804,807,810,812,814,817,819],{"class":262,"line":800},26,[260,802,803],{"class":370},"  \u003C",[260,805,806],{"class":374},"main",[260,808,809],{"class":378}," class",[260,811,385],{"class":370},[260,813,388],{"class":370},[260,815,816],{"class":391},"picker",[260,818,388],{"class":370},[260,820,397],{"class":370},[260,822,824,827,829,832,834,836,839,841],{"class":262,"line":823},27,[260,825,826],{"class":370},"    \u003C",[260,828,170],{"class":374},[260,830,831],{"class":378}," v-if",[260,833,385],{"class":370},[260,835,388],{"class":370},[260,837,838],{"class":391},"loading",[260,840,388],{"class":370},[260,842,397],{"class":370},[260,844,846],{"class":262,"line":845},28,[260,847,848],{"class":409},"      Mixing colours…\n",[260,850,852,855,857],{"class":262,"line":851},29,[260,853,854],{"class":370},"    \u003C\u002F",[260,856,170],{"class":374},[260,858,397],{"class":370},[260,860,862,864,866,869,871,873,876,878,880,882,884,887,889],{"class":262,"line":861},30,[260,863,826],{"class":370},[260,865,213],{"class":374},[260,867,868],{"class":378}," v-else-if",[260,870,385],{"class":370},[260,872,388],{"class":370},[260,874,875],{"class":391},"data",[260,877,388],{"class":370},[260,879,809],{"class":378},[260,881,385],{"class":370},[260,883,388],{"class":370},[260,885,886],{"class":391},"swatches",[260,888,388],{"class":370},[260,890,397],{"class":370},[260,892,894,897,899,902,904,906,909,911,914,916,918,921,923],{"class":262,"line":893},31,[260,895,896],{"class":370},"      \u003C",[260,898,216],{"class":374},[260,900,901],{"class":378}," v-for",[260,903,385],{"class":370},[260,905,388],{"class":370},[260,907,908],{"class":391},"s in data.swatches",[260,910,388],{"class":370},[260,912,913],{"class":378}," :key",[260,915,385],{"class":370},[260,917,388],{"class":370},[260,919,920],{"class":391},"s.hex",[260,922,388],{"class":370},[260,924,397],{"class":370},[260,926,928,931],{"class":262,"line":927},32,[260,929,930],{"class":370},"        \u003C",[260,932,933],{"class":374},"button\n",[260,935,937,940,942,944,947],{"class":262,"line":936},33,[260,938,939],{"class":378},"          type",[260,941,385],{"class":370},[260,943,388],{"class":370},[260,945,946],{"class":391},"button",[260,948,949],{"class":370},"\"\n",[260,951,953,956,958,960,963],{"class":262,"line":952},34,[260,954,955],{"class":378},"          :style",[260,957,385],{"class":370},[260,959,388],{"class":370},[260,961,962],{"class":391},"{ background: s.hex }",[260,964,949],{"class":370},[260,966,968,971,973,975,978],{"class":262,"line":967},35,[260,969,970],{"class":378},"          @click",[260,972,385],{"class":370},[260,974,388],{"class":370},[260,976,977],{"class":391},"sendPrompt(`Use ${s.name} (${s.hex}) as the primary colour.`)",[260,979,949],{"class":370},[260,981,983],{"class":262,"line":982},36,[260,984,985],{"class":370},"        >\n",[260,987,989],{"class":262,"line":988},37,[260,990,991],{"class":409},"          {{ s.name }}\n",[260,993,995,998,1000],{"class":262,"line":994},38,[260,996,997],{"class":370},"        \u003C\u002F",[260,999,946],{"class":374},[260,1001,397],{"class":370},[260,1003,1005,1008,1010],{"class":262,"line":1004},39,[260,1006,1007],{"class":370},"      \u003C\u002F",[260,1009,216],{"class":374},[260,1011,397],{"class":370},[260,1013,1015,1017,1019],{"class":262,"line":1014},40,[260,1016,854],{"class":370},[260,1018,213],{"class":374},[260,1020,397],{"class":370},[260,1022,1024,1027,1029],{"class":262,"line":1023},41,[260,1025,1026],{"class":370},"  \u003C\u002F",[260,1028,806],{"class":374},[260,1030,397],{"class":370},[260,1032,1034,1036,1038],{"class":262,"line":1033},42,[260,1035,778],{"class":370},[260,1037,795],{"class":374},[260,1039,397],{"class":370},[260,1041,1043],{"class":262,"line":1042},43,[260,1044,273],{"emptyLinePlaceholder":272},[260,1046,1048,1050,1053,1056],{"class":262,"line":1047},44,[260,1049,371],{"class":370},[260,1051,1052],{"class":374},"style",[260,1054,1055],{"class":378}," scoped",[260,1057,397],{"class":370},[260,1059,1061,1063,1065,1067,1071,1073,1077,1080,1083,1085,1088,1090,1093,1095],{"class":262,"line":1060},45,[260,1062,205],{"class":370},[260,1064,816],{"class":437},[260,1066,406],{"class":370},[260,1068,1070],{"class":1069},"sqsOY"," padding",[260,1072,449],{"class":370},[260,1074,1076],{"class":1075},"sbssI"," 16px",[260,1078,1079],{"class":370},";",[260,1081,1082],{"class":1069}," font-family",[260,1084,449],{"class":370},[260,1086,1087],{"class":409}," system-ui",[260,1089,472],{"class":370},[260,1091,1092],{"class":409}," sans-serif",[260,1094,1079],{"class":370},[260,1096,716],{"class":370},[260,1098,1100,1102,1104,1106,1109,1111,1114,1116,1119,1121,1124,1126,1129,1131,1134,1137,1140,1142,1145,1147,1149,1151,1154,1156,1159,1161,1164,1166],{"class":262,"line":1099},46,[260,1101,205],{"class":370},[260,1103,886],{"class":437},[260,1105,406],{"class":370},[260,1107,1108],{"class":1069}," display",[260,1110,449],{"class":370},[260,1112,1113],{"class":409}," grid",[260,1115,1079],{"class":370},[260,1117,1118],{"class":1069}," grid-template-columns",[260,1120,449],{"class":370},[260,1122,1123],{"class":498}," repeat",[260,1125,501],{"class":370},[260,1127,1128],{"class":1075},"5",[260,1130,472],{"class":370},[260,1132,1133],{"class":1075}," 1fr",[260,1135,1136],{"class":370},");",[260,1138,1139],{"class":1069}," gap",[260,1141,449],{"class":370},[260,1143,1144],{"class":1075}," 8px",[260,1146,1079],{"class":370},[260,1148,1070],{"class":1069},[260,1150,449],{"class":370},[260,1152,1153],{"class":1075}," 0",[260,1155,1079],{"class":370},[260,1157,1158],{"class":1069}," list-style",[260,1160,449],{"class":370},[260,1162,1163],{"class":409}," none",[260,1165,1079],{"class":370},[260,1167,716],{"class":370},[260,1169,1171,1173,1175,1178,1180,1183,1185,1188,1190,1193,1195,1198,1200,1203,1205,1207,1209,1212,1214,1216,1218,1221,1223,1226,1228],{"class":262,"line":1170},47,[260,1172,205],{"class":370},[260,1174,886],{"class":437},[260,1176,1177],{"class":437}," button",[260,1179,406],{"class":370},[260,1181,1182],{"class":1069}," width",[260,1184,449],{"class":370},[260,1186,1187],{"class":1075}," 100%",[260,1189,1079],{"class":370},[260,1191,1192],{"class":1069}," aspect-ratio",[260,1194,449],{"class":370},[260,1196,1197],{"class":1075}," 1",[260,1199,1079],{"class":370},[260,1201,1202],{"class":1069}," border-radius",[260,1204,449],{"class":370},[260,1206,1144],{"class":1075},[260,1208,1079],{"class":370},[260,1210,1211],{"class":1069}," border",[260,1213,449],{"class":370},[260,1215,1153],{"class":1075},[260,1217,1079],{"class":370},[260,1219,1220],{"class":1069}," cursor",[260,1222,449],{"class":370},[260,1224,1225],{"class":409}," pointer",[260,1227,1079],{"class":370},[260,1229,716],{"class":370},[260,1231,1233,1235,1237],{"class":262,"line":1232},48,[260,1234,778],{"class":370},[260,1236,1052],{"class":374},[260,1238,397],{"class":370},[170,1240,1241],{},"That's it. The toolkit:",[1243,1244,1245,1259,1272,1282],"ol",{},[216,1246,1247,1248,1250,1251,1254,1255,1258],{},"Detects ",[190,1249,231],{}," and ",[174,1252,1253],{},"registers an MCP tool"," named ",[190,1256,1257],{},"color-picker"," (from the filename).",[216,1260,1261,1262,1265,1266,1269,1270,205],{},"Generates a ",[174,1263,1264],{},"UI resource"," at ",[190,1267,1268],{},"ui:\u002F\u002Fmcp-app\u002Fcolor-picker"," exposing ",[190,1271,192],{},[216,1273,1274,1275,205],{},"Bundles the SFC + assets into a single HTML file with ",[182,1276,1279],{"href":1277,"rel":1278},"https:\u002F\u002Fgithub.com\u002Frichardtallent\u002Fvite-plugin-singlefile",[186],[190,1280,1281],{},"vite-plugin-singlefile",[216,1283,1284,1285,1288,1289,1292,1293,205],{},"Wires the ",[190,1286,1287],{},"handler","'s ",[190,1290,1291],{},"structuredContent"," into the iframe so the UI hydrates ",[174,1294,1295],{},"without a second round-trip",[165,1297,1299],{"id":1298},"file-convention","File Convention",[170,1301,1302,1303,1307,1308,1311,1312,1315,1316,1319,1320,1322],{},"MCP Apps live in ",[174,1304,1305],{},[190,1306,225],{}," by default (not ",[190,1309,1310],{},"server\u002Fmcp\u002F","). Change the app-side directory with ",[190,1313,1314],{},"mcp.appsDir"," in ",[190,1317,1318],{},"nuxt.config.ts",". They sit on the client side of Nuxt because they author Vue components — but the ",[190,1321,1287],{}," you declare runs server-side, just like a tool.",[250,1324,1328],{"className":1325,"code":1326,"language":1327,"meta":256,"style":256},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","app\u002F\n└── mcp\u002F\n    ├── color-picker.vue    # → tool: color-picker, resource: ui:\u002F\u002Fmcp-app\u002Fcolor-picker\n    └── admin\u002F\n        └── audit-log.vue   # → tool: audit-log\n","bash",[190,1329,1330,1335,1343,1355,1363],{"__ignoreMap":256},[260,1331,1332],{"class":262,"line":263},[260,1333,1334],{"class":437},"app\u002F\n",[260,1336,1337,1340],{"class":262,"line":269},[260,1338,1339],{"class":437},"└──",[260,1341,1342],{"class":391}," mcp\u002F\n",[260,1344,1345,1348,1351],{"class":262,"line":276},[260,1346,1347],{"class":437},"    ├──",[260,1349,1350],{"class":391}," color-picker.vue",[260,1352,1354],{"class":1353},"sHwdD","    # → tool: color-picker, resource: ui:\u002F\u002Fmcp-app\u002Fcolor-picker\n",[260,1356,1357,1360],{"class":262,"line":282},[260,1358,1359],{"class":437},"    └──",[260,1361,1362],{"class":391}," admin\u002F\n",[260,1364,1365,1368,1371],{"class":262,"line":288},[260,1366,1367],{"class":437},"        └──",[260,1369,1370],{"class":391}," audit-log.vue",[260,1372,1373],{"class":1353},"   # → tool: audit-log\n",[1375,1376,1379,1380,1383,1384,1387,1388,1391],"callout",{"color":1377,"icon":1378},"info","i-lucide-info","Co-locate helpers next to the SFC (e.g. ",[190,1381,1382],{},"format.ts",") — the bundler inlines them. Keep data generation in ",[190,1385,1386],{},"server\u002Fapi\u002F"," and call it via ",[190,1389,1390],{},"$fetch"," from the handler.",[1393,1394,1396],"h3",{"id":1395},"auto-generated-name-title","Auto-Generated Name & Title",[170,1398,1399,1400,1250,1403,1406],{},"Like tools and resources, ",[190,1401,1402],{},"name",[190,1404,1405],{},"title"," are inferred from the filename:",[1408,1409,1410,1426],"table",{},[1411,1412,1413],"thead",{},[1414,1415,1416,1420,1423],"tr",{},[1417,1418,1419],"th",{},"File",[1417,1421,1422],{},"Name",[1417,1424,1425],{},"Title",[1427,1428,1429,1446,1463],"tbody",{},[1414,1430,1431,1437,1441],{},[1432,1433,1434],"td",{},[190,1435,1436],{},"color-picker.vue",[1432,1438,1439],{},[190,1440,1257],{},[1432,1442,1443],{},[190,1444,1445],{},"Color Picker",[1414,1447,1448,1453,1458],{},[1432,1449,1450],{},[190,1451,1452],{},"weather-card.vue",[1432,1454,1455],{},[190,1456,1457],{},"weather-card",[1432,1459,1460],{},[190,1461,1462],{},"Weather Card",[1414,1464,1465,1470,1475],{},[1432,1466,1467],{},[190,1468,1469],{},"admin\u002Faudit-log.vue",[1432,1471,1472],{},[190,1473,1474],{},"audit-log",[1432,1476,1477],{},[190,1478,1479],{},"Audit Log",[170,1481,1482,1483,1485,1486,1488,1489,205],{},"Override either by passing ",[190,1484,1402],{}," \u002F ",[190,1487,1405],{}," to ",[190,1490,231],{},[165,1492,1494],{"id":1493},"definemcpapp",[190,1495,231],{},[170,1497,1498,1499,1502,1503,1506],{},"A macro — like ",[190,1500,1501],{},"definePageMeta"," — extracted at build time and ",[174,1504,1505],{},"stripped from the browser bundle",". The fields it accepts:",[250,1508,1511],{"className":1509,"code":1510,"language":392,"meta":256,"style":256},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","defineMcpApp({\n  name?: string                          \u002F\u002F Override auto-derived name\n  title?: string                         \u002F\u002F Override auto-derived title\n  description?: string                   \u002F\u002F Shown to the LLM to help it pick this app\n  inputSchema?: ZodRawShape              \u002F\u002F Validates tool input on the server\n  handler?: (args, extra) => Result      \u002F\u002F Runs server-side; defaults to (args) => ({ structuredContent: args })\n  csp?: McpAppCsp | false                \u002F\u002F Tighten or disable iframe CSP\n  _meta?: Record\u003Cstring, unknown>        \u002F\u002F Extra _meta fields surfaced to the host\n})\n",[190,1512,1513,1521,1534,1548,1560,1572,1599,1619,1641],{"__ignoreMap":256},[260,1514,1515,1517,1519],{"class":262,"line":263},[260,1516,231],{"class":498},[260,1518,501],{"class":409},[260,1520,504],{"class":370},[260,1522,1523,1526,1528,1531],{"class":262,"line":269},[260,1524,1525],{"class":409},"  name?",[260,1527,449],{"class":370},[260,1529,1530],{"class":409}," string                          ",[260,1532,1533],{"class":1353},"\u002F\u002F Override auto-derived name\n",[260,1535,1536,1539,1542,1545],{"class":262,"line":276},[260,1537,1538],{"class":409},"  title",[260,1540,1541],{"class":370},"?:",[260,1543,1544],{"class":409}," string                         ",[260,1546,1547],{"class":1353},"\u002F\u002F Override auto-derived title\n",[260,1549,1550,1552,1554,1557],{"class":262,"line":282},[260,1551,509],{"class":409},[260,1553,1541],{"class":370},[260,1555,1556],{"class":409}," string                   ",[260,1558,1559],{"class":1353},"\u002F\u002F Shown to the LLM to help it pick this app\n",[260,1561,1562,1564,1566,1569],{"class":262,"line":288},[260,1563,527],{"class":409},[260,1565,1541],{"class":370},[260,1567,1568],{"class":409}," ZodRawShape              ",[260,1570,1571],{"class":1353},"\u002F\u002F Validates tool input on the server\n",[260,1573,1574,1576,1578,1581,1584,1586,1589,1591,1593,1596],{"class":262,"line":294},[260,1575,577],{"class":409},[260,1577,1541],{"class":370},[260,1579,1580],{"class":370}," (",[260,1582,1583],{"class":588},"args",[260,1585,472],{"class":370},[260,1587,1588],{"class":588}," extra",[260,1590,565],{"class":370},[260,1592,611],{"class":378},[260,1594,1595],{"class":409}," Result      ",[260,1597,1598],{"class":1353},"\u002F\u002F Runs server-side; defaults to (args) => ({ structuredContent: args })\n",[260,1600,1601,1604,1606,1609,1612,1616],{"class":262,"line":300},[260,1602,1603],{"class":409},"  csp",[260,1605,1541],{"class":370},[260,1607,1608],{"class":409}," McpAppCsp ",[260,1610,1611],{"class":370},"|",[260,1613,1615],{"class":1614},"sfNiH"," false",[260,1617,1618],{"class":1353},"                \u002F\u002F Tighten or disable iframe CSP\n",[260,1620,1621,1624,1626,1629,1631,1633,1635,1638],{"class":262,"line":306},[260,1622,1623],{"class":409},"  _meta",[260,1625,1541],{"class":370},[260,1627,1628],{"class":409}," Record",[260,1630,371],{"class":370},[260,1632,545],{"class":409},[260,1634,472],{"class":370},[260,1636,1637],{"class":409}," unknown>        ",[260,1639,1640],{"class":1353},"\u002F\u002F Extra _meta fields surfaced to the host\n",[260,1642,1643,1645],{"class":262,"line":312},[260,1644,727],{"class":370},[260,1646,691],{"class":409},[1393,1648,1650],{"id":1649},"server-handler","Server Handler",[170,1652,1653,1654,1656,1657,1659,1660,1663,1664,449],{},"The ",[190,1655,1287],{}," runs in your Nitro server, not in the iframe. It receives validated input and returns ",[190,1658,1291],{}," that the UI hydrates from. ",[174,1661,1662],{},"Treat it like a tool handler"," — call APIs, query a database, hit ",[190,1665,1390],{},[250,1667,1669],{"className":1509,"code":1668,"language":392,"meta":256,"style":256},"defineMcpApp({\n  description: 'Pick a colour and preview a 5-tone palette.',\n  inputSchema: {\n    base: z.string().describe('Hex colour to anchor the palette, e.g. #2563eb'),\n  },\n  handler: async ({ base }) => {\n    const swatches = await $fetch('\u002Fapi\u002Fpalette', { query: { base } })\n    return { structuredContent: { base, swatches } }\n  },\n})\n",[190,1670,1671,1679,1693,1701,1731,1735,1754,1793,1815,1819],{"__ignoreMap":256},[260,1672,1673,1675,1677],{"class":262,"line":263},[260,1674,231],{"class":498},[260,1676,501],{"class":409},[260,1678,504],{"class":370},[260,1680,1681,1683,1685,1687,1689,1691],{"class":262,"line":269},[260,1682,509],{"class":374},[260,1684,449],{"class":370},[260,1686,419],{"class":370},[260,1688,516],{"class":391},[260,1690,519],{"class":370},[260,1692,522],{"class":370},[260,1694,1695,1697,1699],{"class":262,"line":276},[260,1696,527],{"class":374},[260,1698,449],{"class":370},[260,1700,441],{"class":370},[260,1702,1703,1705,1707,1709,1711,1713,1715,1717,1719,1721,1723,1725,1727,1729],{"class":262,"line":282},[260,1704,536],{"class":374},[260,1706,449],{"class":370},[260,1708,410],{"class":409},[260,1710,205],{"class":370},[260,1712,545],{"class":498},[260,1714,548],{"class":409},[260,1716,205],{"class":370},[260,1718,553],{"class":498},[260,1720,501],{"class":409},[260,1722,519],{"class":370},[260,1724,560],{"class":391},[260,1726,519],{"class":370},[260,1728,565],{"class":409},[260,1730,522],{"class":370},[260,1732,1733],{"class":262,"line":288},[260,1734,572],{"class":370},[260,1736,1737,1739,1741,1743,1745,1747,1750,1752],{"class":262,"line":294},[260,1738,577],{"class":498},[260,1740,449],{"class":370},[260,1742,582],{"class":378},[260,1744,585],{"class":370},[260,1746,589],{"class":588},[260,1748,1749],{"class":370}," })",[260,1751,611],{"class":378},[260,1753,441],{"class":370},[260,1755,1756,1758,1760,1762,1764,1766,1768,1770,1772,1774,1776,1778,1781,1783,1785,1787,1789,1791],{"class":262,"line":300},[260,1757,618],{"class":378},[260,1759,621],{"class":409},[260,1761,624],{"class":370},[260,1763,627],{"class":402},[260,1765,630],{"class":498},[260,1767,501],{"class":374},[260,1769,519],{"class":370},[260,1771,661],{"class":391},[260,1773,519],{"class":370},[260,1775,472],{"class":370},[260,1777,406],{"class":370},[260,1779,1780],{"class":374}," query",[260,1782,449],{"class":370},[260,1784,406],{"class":370},[260,1786,589],{"class":409},[260,1788,413],{"class":370},[260,1790,413],{"class":370},[260,1792,691],{"class":374},[260,1794,1795,1797,1799,1801,1803,1805,1807,1809,1811,1813],{"class":262,"line":306},[260,1796,697],{"class":402},[260,1798,406],{"class":370},[260,1800,601],{"class":374},[260,1802,449],{"class":370},[260,1804,406],{"class":370},[260,1806,589],{"class":409},[260,1808,472],{"class":370},[260,1810,621],{"class":409},[260,1812,413],{"class":370},[260,1814,716],{"class":370},[260,1816,1817],{"class":262,"line":312},[260,1818,572],{"class":370},[260,1820,1821,1823],{"class":262,"line":318},[260,1822,727],{"class":370},[260,1824,691],{"class":409},[1375,1826,1829,1830,1832,1833,1836,1837,1840],{"color":1827,"icon":1828},"primary","i-lucide-zap","Returning ",[190,1831,1291],{}," from the handler ",[174,1834,1835],{},"inlines the data into the HTML"," as a ",[190,1838,1839],{},"\u003Cscript type=\"application\u002Fjson\">",". The iframe boots with full data already present — no extra fetch, no flicker.",[170,1842,1843,1844,1846,1847,1850],{},"If you omit ",[190,1845,1287],{},", the toolkit defaults to ",[190,1848,1849],{},"(args) => ({ structuredContent: args })",". Useful for stateless apps that only need the input echoed back.",[1393,1852,1854],{"id":1853},"sharing-types-between-server-ui","Sharing Types Between Server & UI",[170,1856,1857,1858,1861,1862,1865,1866,1868],{},"Place shared types in Nuxt's ",[190,1859,1860],{},"shared\u002Ftypes\u002F"," directory — they're ",[174,1863,1864],{},"auto-imported globally"," in both the SFC and your API endpoints, no ",[190,1867,403],{}," statement required:",[250,1870,1873],{"className":1509,"code":1871,"filename":1872,"language":392,"meta":256,"style":256},"export interface Swatch { name: string, hex: string }\nexport interface PalettePayload { base: string, swatches: Swatch[] }\n","shared\u002Ftypes\u002Fpalette.ts",[190,1874,1875,1904],{"__ignoreMap":256},[260,1876,1877,1880,1883,1886,1888,1890,1892,1894,1896,1898,1900,1902],{"class":262,"line":263},[260,1878,1879],{"class":402},"export",[260,1881,1882],{"class":378}," interface",[260,1884,1885],{"class":437}," Swatch",[260,1887,406],{"class":370},[260,1889,464],{"class":374},[260,1891,449],{"class":370},[260,1893,469],{"class":437},[260,1895,472],{"class":370},[260,1897,475],{"class":374},[260,1899,449],{"class":370},[260,1901,469],{"class":437},[260,1903,716],{"class":370},[260,1905,1906,1908,1910,1912,1914,1916,1918,1920,1922,1924,1926,1928,1931],{"class":262,"line":269},[260,1907,1879],{"class":402},[260,1909,1882],{"class":378},[260,1911,438],{"class":437},[260,1913,406],{"class":370},[260,1915,589],{"class":374},[260,1917,449],{"class":370},[260,1919,469],{"class":437},[260,1921,472],{"class":370},[260,1923,621],{"class":374},[260,1925,449],{"class":370},[260,1927,1885],{"class":437},[260,1929,1930],{"class":409},"[] ",[260,1932,489],{"class":370},[250,1934,1937],{"className":1509,"code":1935,"filename":1936,"language":392,"meta":256,"style":256},"export default defineEventHandler(async (event): Promise\u003CPalettePayload> => {\n  const { base } = getQuery(event)\n  return { base: String(base), swatches: buildPalette(String(base)) }\n})\n","server\u002Fapi\u002Fpalette.get.ts",[190,1938,1939,1974,1996,2040],{"__ignoreMap":256},[260,1940,1941,1943,1946,1949,1951,1954,1956,1959,1962,1964,1966,1968,1970,1972],{"class":262,"line":263},[260,1942,1879],{"class":402},[260,1944,1945],{"class":402}," default",[260,1947,1948],{"class":498}," defineEventHandler",[260,1950,501],{"class":409},[260,1952,1953],{"class":378},"async",[260,1955,1580],{"class":370},[260,1957,1958],{"class":588},"event",[260,1960,1961],{"class":370},"):",[260,1963,595],{"class":437},[260,1965,371],{"class":370},[260,1967,767],{"class":437},[260,1969,654],{"class":370},[260,1971,611],{"class":378},[260,1973,441],{"class":370},[260,1975,1976,1979,1981,1983,1985,1987,1990,1992,1994],{"class":262,"line":269},[260,1977,1978],{"class":378},"  const",[260,1980,406],{"class":370},[260,1982,589],{"class":409},[260,1984,413],{"class":370},[260,1986,624],{"class":370},[260,1988,1989],{"class":498}," getQuery",[260,1991,501],{"class":374},[260,1993,1958],{"class":409},[260,1995,691],{"class":374},[260,1997,1998,2001,2003,2005,2007,2010,2012,2015,2017,2019,2021,2023,2026,2028,2031,2033,2035,2038],{"class":262,"line":276},[260,1999,2000],{"class":402},"  return",[260,2002,406],{"class":370},[260,2004,589],{"class":374},[260,2006,449],{"class":370},[260,2008,2009],{"class":498}," String",[260,2011,501],{"class":374},[260,2013,2014],{"class":409},"base",[260,2016,565],{"class":374},[260,2018,472],{"class":370},[260,2020,621],{"class":374},[260,2022,449],{"class":370},[260,2024,2025],{"class":498}," buildPalette",[260,2027,501],{"class":374},[260,2029,2030],{"class":498},"String",[260,2032,501],{"class":374},[260,2034,2014],{"class":409},[260,2036,2037],{"class":374},")) ",[260,2039,489],{"class":370},[260,2041,2042,2044],{"class":262,"line":282},[260,2043,727],{"class":370},[260,2045,691],{"class":409},[250,2047,2049],{"className":360,"code":2048,"filename":362,"language":363,"meta":256,"style":256},"\u003Cscript setup lang=\"ts\">\ndefineMcpApp({\n  inputSchema: { base: z.string() },\n  handler: async ({ base }): Promise\u003C{ structuredContent: PalettePayload }> => ({\n    structuredContent: await $fetch('\u002Fapi\u002Fpalette', { query: { base } }),\n  }),\n})\n\nconst { data } = useMcpApp\u003CPalettePayload>()\n\u003C\u002Fscript>\n",[190,2050,2051,2071,2079,2103,2135,2175,2184,2190,2194,2217],{"__ignoreMap":256},[260,2052,2053,2055,2057,2059,2061,2063,2065,2067,2069],{"class":262,"line":263},[260,2054,371],{"class":370},[260,2056,375],{"class":374},[260,2058,379],{"class":378},[260,2060,382],{"class":378},[260,2062,385],{"class":370},[260,2064,388],{"class":370},[260,2066,392],{"class":391},[260,2068,388],{"class":370},[260,2070,397],{"class":370},[260,2072,2073,2075,2077],{"class":262,"line":269},[260,2074,231],{"class":498},[260,2076,501],{"class":409},[260,2078,504],{"class":370},[260,2080,2081,2083,2085,2087,2089,2091,2093,2095,2097,2100],{"class":262,"line":276},[260,2082,527],{"class":374},[260,2084,449],{"class":370},[260,2086,406],{"class":370},[260,2088,589],{"class":374},[260,2090,449],{"class":370},[260,2092,410],{"class":409},[260,2094,205],{"class":370},[260,2096,545],{"class":498},[260,2098,2099],{"class":409},"() ",[260,2101,2102],{"class":370},"},\n",[260,2104,2105,2107,2109,2111,2113,2115,2117,2119,2121,2123,2125,2127,2129,2131,2133],{"class":262,"line":282},[260,2106,577],{"class":498},[260,2108,449],{"class":370},[260,2110,582],{"class":378},[260,2112,585],{"class":370},[260,2114,589],{"class":588},[260,2116,592],{"class":370},[260,2118,595],{"class":437},[260,2120,598],{"class":370},[260,2122,601],{"class":374},[260,2124,449],{"class":370},[260,2126,438],{"class":437},[260,2128,608],{"class":370},[260,2130,611],{"class":378},[260,2132,1580],{"class":409},[260,2134,504],{"class":370},[260,2136,2137,2140,2142,2144,2146,2148,2150,2152,2154,2156,2158,2160,2162,2164,2167,2169,2171,2173],{"class":262,"line":288},[260,2138,2139],{"class":374},"    structuredContent",[260,2141,449],{"class":370},[260,2143,627],{"class":402},[260,2145,630],{"class":498},[260,2147,501],{"class":409},[260,2149,519],{"class":370},[260,2151,661],{"class":391},[260,2153,519],{"class":370},[260,2155,472],{"class":370},[260,2157,406],{"class":370},[260,2159,1780],{"class":374},[260,2161,449],{"class":370},[260,2163,406],{"class":370},[260,2165,2166],{"class":409}," base ",[260,2168,727],{"class":370},[260,2170,413],{"class":370},[260,2172,565],{"class":409},[260,2174,522],{"class":370},[260,2176,2177,2180,2182],{"class":262,"line":294},[260,2178,2179],{"class":370},"  }",[260,2181,565],{"class":409},[260,2183,522],{"class":370},[260,2185,2186,2188],{"class":262,"line":300},[260,2187,727],{"class":370},[260,2189,691],{"class":409},[260,2191,2192],{"class":262,"line":306},[260,2193,273],{"emptyLinePlaceholder":272},[260,2195,2196,2198,2200,2203,2205,2207,2209,2211,2213,2215],{"class":262,"line":312},[260,2197,740],{"class":378},[260,2199,406],{"class":370},[260,2201,2202],{"class":409}," data ",[260,2204,727],{"class":370},[260,2206,624],{"class":370},[260,2208,762],{"class":498},[260,2210,371],{"class":370},[260,2212,767],{"class":437},[260,2214,654],{"class":370},[260,2216,772],{"class":409},[260,2218,2219,2221,2223],{"class":262,"line":318},[260,2220,778],{"class":370},[260,2222,375],{"class":374},[260,2224,397],{"class":370},[170,2226,2227],{},"Type-only references are stripped from the browser bundle by esbuild — nothing has to resolve inside the iframe at runtime.",[165,2229,2231],{"id":2230},"usemcpapp",[190,2232,241],{},[170,2234,2235,2236,2239],{},"The single client-side composable, ",[174,2237,2238],{},"auto-imported into every MCP App SFC",". It returns everything the iframe needs to talk to the host:",[250,2241,2243],{"className":1509,"code":2242,"language":392,"meta":256,"style":256},"const {\n  data,         \u002F\u002F Ref\u003CT | null>          — hydrated from structuredContent, refreshed by callTool\n  loading,      \u002F\u002F Ref\u003Cboolean>           — true until first payload arrives\n  error,        \u002F\u002F Ref\u003CError | null>      — bridge \u002F transport \u002F payload errors\n  pending,      \u002F\u002F Ref\u003Cboolean>           — true while a callTool() is in flight\n  hostContext,  \u002F\u002F Ref\u003CHostContext | null> — theme, displayMode, locale, …\n  callTool,     \u002F\u002F (name, params?) => Promise\u003CT | null> — re-invoke any MCP tool\n  sendPrompt,   \u002F\u002F (prompt: string) => void              — push a message into the chat\n  openLink,     \u002F\u002F (url: string) => void                 — ask the host to open a URL\n} = useMcpApp\u003CMyPayload>()\n",[190,2244,2245,2251,2261,2271,2281,2291,2301,2311,2321,2331],{"__ignoreMap":256},[260,2246,2247,2249],{"class":262,"line":263},[260,2248,740],{"class":378},[260,2250,441],{"class":370},[260,2252,2253,2256,2258],{"class":262,"line":269},[260,2254,2255],{"class":409},"  data",[260,2257,472],{"class":370},[260,2259,2260],{"class":1353},"         \u002F\u002F Ref\u003CT | null>          — hydrated from structuredContent, refreshed by callTool\n",[260,2262,2263,2266,2268],{"class":262,"line":276},[260,2264,2265],{"class":409},"  loading",[260,2267,472],{"class":370},[260,2269,2270],{"class":1353},"      \u002F\u002F Ref\u003Cboolean>           — true until first payload arrives\n",[260,2272,2273,2276,2278],{"class":262,"line":282},[260,2274,2275],{"class":409},"  error",[260,2277,472],{"class":370},[260,2279,2280],{"class":1353},"        \u002F\u002F Ref\u003CError | null>      — bridge \u002F transport \u002F payload errors\n",[260,2282,2283,2286,2288],{"class":262,"line":288},[260,2284,2285],{"class":409},"  pending",[260,2287,472],{"class":370},[260,2289,2290],{"class":1353},"      \u002F\u002F Ref\u003Cboolean>           — true while a callTool() is in flight\n",[260,2292,2293,2296,2298],{"class":262,"line":294},[260,2294,2295],{"class":409},"  hostContext",[260,2297,472],{"class":370},[260,2299,2300],{"class":1353},"  \u002F\u002F Ref\u003CHostContext | null> — theme, displayMode, locale, …\n",[260,2302,2303,2306,2308],{"class":262,"line":300},[260,2304,2305],{"class":409},"  callTool",[260,2307,472],{"class":370},[260,2309,2310],{"class":1353},"     \u002F\u002F (name, params?) => Promise\u003CT | null> — re-invoke any MCP tool\n",[260,2312,2313,2316,2318],{"class":262,"line":306},[260,2314,2315],{"class":409},"  sendPrompt",[260,2317,472],{"class":370},[260,2319,2320],{"class":1353},"   \u002F\u002F (prompt: string) => void              — push a message into the chat\n",[260,2322,2323,2326,2328],{"class":262,"line":312},[260,2324,2325],{"class":409},"  openLink",[260,2327,472],{"class":370},[260,2329,2330],{"class":1353},"     \u002F\u002F (url: string) => void                 — ask the host to open a URL\n",[260,2332,2333,2335,2337,2339,2341,2344,2346],{"class":262,"line":318},[260,2334,727],{"class":370},[260,2336,624],{"class":370},[260,2338,762],{"class":498},[260,2340,371],{"class":370},[260,2342,2343],{"class":437},"MyPayload",[260,2345,654],{"class":370},[260,2347,772],{"class":409},[170,2349,2350],{},"Pass your payload type as the generic to get full inference downstream.",[1393,2352,2354,2356,2357],{"id":2353},"data-loading",[190,2355,875],{}," & ",[190,2358,838],{},[170,2360,2361,2363,2364,2367,2368,2370,2371,2373,2374,2377,2378,2381,2382,2385,2386,2389],{},[190,2362,875],{}," is ",[174,2365,2366],{},"already populated on first render"," when the handler returns ",[190,2369,1291],{},". ",[190,2372,838],{}," starts as ",[190,2375,2376],{},"true"," and becomes ",[190,2379,2380],{},"false"," after the first payload arrives. Use ",[190,2383,2384],{},"pending"," for in-flight ",[190,2387,2388],{},"callTool()"," refreshes:",[250,2391,2393],{"className":360,"code":2392,"language":363,"meta":256,"style":256},"\u003Ctemplate>\n  \u003Csection v-if=\"loading\" class=\"skeleton\" \u002F>\n  \u003Csection v-else-if=\"data\" class=\"content\">\n    {{ data.swatches.length }} swatches from {{ data.base }}\n  \u003C\u002Fsection>\n\u003C\u002Ftemplate>\n",[190,2394,2395,2403,2434,2463,2468,2476],{"__ignoreMap":256},[260,2396,2397,2399,2401],{"class":262,"line":263},[260,2398,371],{"class":370},[260,2400,795],{"class":374},[260,2402,397],{"class":370},[260,2404,2405,2407,2410,2412,2414,2416,2418,2420,2422,2424,2426,2429,2431],{"class":262,"line":269},[260,2406,803],{"class":370},[260,2408,2409],{"class":374},"section",[260,2411,831],{"class":378},[260,2413,385],{"class":370},[260,2415,388],{"class":370},[260,2417,838],{"class":391},[260,2419,388],{"class":370},[260,2421,809],{"class":378},[260,2423,385],{"class":370},[260,2425,388],{"class":370},[260,2427,2428],{"class":391},"skeleton",[260,2430,388],{"class":370},[260,2432,2433],{"class":370}," \u002F>\n",[260,2435,2436,2438,2440,2442,2444,2446,2448,2450,2452,2454,2456,2459,2461],{"class":262,"line":276},[260,2437,803],{"class":370},[260,2439,2409],{"class":374},[260,2441,868],{"class":378},[260,2443,385],{"class":370},[260,2445,388],{"class":370},[260,2447,875],{"class":391},[260,2449,388],{"class":370},[260,2451,809],{"class":378},[260,2453,385],{"class":370},[260,2455,388],{"class":370},[260,2457,2458],{"class":391},"content",[260,2460,388],{"class":370},[260,2462,397],{"class":370},[260,2464,2465],{"class":262,"line":282},[260,2466,2467],{"class":409},"    {{ data.swatches.length }} swatches from {{ data.base }}\n",[260,2469,2470,2472,2474],{"class":262,"line":288},[260,2471,1026],{"class":370},[260,2473,2409],{"class":374},[260,2475,397],{"class":370},[260,2477,2478,2480,2482],{"class":262,"line":294},[260,2479,778],{"class":370},[260,2481,795],{"class":374},[260,2483,397],{"class":370},[1393,2485,2487],{"id":2486},"hostcontext",[190,2488,2489],{},"hostContext",[170,2491,2492,2493,2496,2497,449],{},"The host hands the iframe a context object during the ",[190,2494,2495],{},"ui\u002Finitialize"," handshake. Use it to ",[174,2498,2499],{},"adapt to dark mode, fullscreen, or a fixed iframe size",[250,2501,2503],{"className":1509,"code":2502,"language":392,"meta":256,"style":256},"interface HostContext {\n  theme?: 'light' | 'dark'\n  displayMode?: 'inline' | 'fullscreen' | 'pip'\n  containerDimensions?: { width?: number, height?: number, maxWidth?: number, maxHeight?: number }\n  locale?: string\n  timeZone?: string\n  platform?: 'web' | 'desktop' | 'mobile'\n}\n",[190,2504,2505,2514,2538,2570,2615,2624,2633,2665],{"__ignoreMap":256},[260,2506,2507,2509,2512],{"class":262,"line":263},[260,2508,434],{"class":378},[260,2510,2511],{"class":437}," HostContext",[260,2513,441],{"class":370},[260,2515,2516,2519,2521,2523,2526,2528,2531,2533,2536],{"class":262,"line":269},[260,2517,2518],{"class":374},"  theme",[260,2520,1541],{"class":370},[260,2522,419],{"class":370},[260,2524,2525],{"class":391},"light",[260,2527,519],{"class":370},[260,2529,2530],{"class":370}," |",[260,2532,419],{"class":370},[260,2534,2535],{"class":391},"dark",[260,2537,425],{"class":370},[260,2539,2540,2543,2545,2547,2550,2552,2554,2556,2559,2561,2563,2565,2568],{"class":262,"line":276},[260,2541,2542],{"class":374},"  displayMode",[260,2544,1541],{"class":370},[260,2546,419],{"class":370},[260,2548,2549],{"class":391},"inline",[260,2551,519],{"class":370},[260,2553,2530],{"class":370},[260,2555,419],{"class":370},[260,2557,2558],{"class":391},"fullscreen",[260,2560,519],{"class":370},[260,2562,2530],{"class":370},[260,2564,419],{"class":370},[260,2566,2567],{"class":391},"pip",[260,2569,425],{"class":370},[260,2571,2572,2575,2577,2579,2581,2583,2586,2588,2591,2593,2595,2597,2600,2602,2604,2606,2609,2611,2613],{"class":262,"line":282},[260,2573,2574],{"class":374},"  containerDimensions",[260,2576,1541],{"class":370},[260,2578,406],{"class":370},[260,2580,1182],{"class":374},[260,2582,1541],{"class":370},[260,2584,2585],{"class":437}," number",[260,2587,472],{"class":370},[260,2589,2590],{"class":374}," height",[260,2592,1541],{"class":370},[260,2594,2585],{"class":437},[260,2596,472],{"class":370},[260,2598,2599],{"class":374}," maxWidth",[260,2601,1541],{"class":370},[260,2603,2585],{"class":437},[260,2605,472],{"class":370},[260,2607,2608],{"class":374}," maxHeight",[260,2610,1541],{"class":370},[260,2612,2585],{"class":437},[260,2614,716],{"class":370},[260,2616,2617,2620,2622],{"class":262,"line":288},[260,2618,2619],{"class":374},"  locale",[260,2621,1541],{"class":370},[260,2623,452],{"class":437},[260,2625,2626,2629,2631],{"class":262,"line":294},[260,2627,2628],{"class":374},"  timeZone",[260,2630,1541],{"class":370},[260,2632,452],{"class":437},[260,2634,2635,2638,2640,2642,2645,2647,2649,2651,2654,2656,2658,2660,2663],{"class":262,"line":300},[260,2636,2637],{"class":374},"  platform",[260,2639,1541],{"class":370},[260,2641,419],{"class":370},[260,2643,2644],{"class":391},"web",[260,2646,519],{"class":370},[260,2648,2530],{"class":370},[260,2650,419],{"class":370},[260,2652,2653],{"class":391},"desktop",[260,2655,519],{"class":370},[260,2657,2530],{"class":370},[260,2659,419],{"class":370},[260,2661,2662],{"class":391},"mobile",[260,2664,425],{"class":370},[260,2666,2667],{"class":262,"line":306},[260,2668,489],{"class":370},[250,2670,2672],{"className":360,"code":2671,"language":363,"meta":256,"style":256},"\u003Cscript setup lang=\"ts\">\nconst { hostContext } = useMcpApp()\nconst isDark = computed(() => hostContext.value?.theme === 'dark')\nconst isFullscreen = computed(() => hostContext.value?.displayMode === 'fullscreen')\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cmain :data-theme=\"isDark ? 'dark' : 'light'\" :data-mode=\"isFullscreen ? 'fullscreen' : 'inline'\">\n    …\n  \u003C\u002Fmain>\n\u003C\u002Ftemplate>\n",[190,2673,2674,2694,2711,2754,2792,2800,2804,2812,2844,2849,2857],{"__ignoreMap":256},[260,2675,2676,2678,2680,2682,2684,2686,2688,2690,2692],{"class":262,"line":263},[260,2677,371],{"class":370},[260,2679,375],{"class":374},[260,2681,379],{"class":378},[260,2683,382],{"class":378},[260,2685,385],{"class":370},[260,2687,388],{"class":370},[260,2689,392],{"class":391},[260,2691,388],{"class":370},[260,2693,397],{"class":370},[260,2695,2696,2698,2700,2703,2705,2707,2709],{"class":262,"line":269},[260,2697,740],{"class":378},[260,2699,406],{"class":370},[260,2701,2702],{"class":409}," hostContext ",[260,2704,727],{"class":370},[260,2706,624],{"class":370},[260,2708,762],{"class":498},[260,2710,772],{"class":409},[260,2712,2713,2715,2718,2720,2723,2725,2727,2729,2732,2734,2737,2740,2743,2746,2748,2750,2752],{"class":262,"line":276},[260,2714,740],{"class":378},[260,2716,2717],{"class":409}," isDark ",[260,2719,385],{"class":370},[260,2721,2722],{"class":498}," computed",[260,2724,501],{"class":409},[260,2726,548],{"class":370},[260,2728,611],{"class":378},[260,2730,2731],{"class":409}," hostContext",[260,2733,205],{"class":370},[260,2735,2736],{"class":409},"value",[260,2738,2739],{"class":370},"?.",[260,2741,2742],{"class":409},"theme ",[260,2744,2745],{"class":370},"===",[260,2747,419],{"class":370},[260,2749,2535],{"class":391},[260,2751,519],{"class":370},[260,2753,691],{"class":409},[260,2755,2756,2758,2761,2763,2765,2767,2769,2771,2773,2775,2777,2779,2782,2784,2786,2788,2790],{"class":262,"line":282},[260,2757,740],{"class":378},[260,2759,2760],{"class":409}," isFullscreen ",[260,2762,385],{"class":370},[260,2764,2722],{"class":498},[260,2766,501],{"class":409},[260,2768,548],{"class":370},[260,2770,611],{"class":378},[260,2772,2731],{"class":409},[260,2774,205],{"class":370},[260,2776,2736],{"class":409},[260,2778,2739],{"class":370},[260,2780,2781],{"class":409},"displayMode ",[260,2783,2745],{"class":370},[260,2785,419],{"class":370},[260,2787,2558],{"class":391},[260,2789,519],{"class":370},[260,2791,691],{"class":409},[260,2793,2794,2796,2798],{"class":262,"line":288},[260,2795,778],{"class":370},[260,2797,375],{"class":374},[260,2799,397],{"class":370},[260,2801,2802],{"class":262,"line":294},[260,2803,273],{"emptyLinePlaceholder":272},[260,2805,2806,2808,2810],{"class":262,"line":300},[260,2807,371],{"class":370},[260,2809,795],{"class":374},[260,2811,397],{"class":370},[260,2813,2814,2816,2818,2821,2823,2825,2828,2830,2833,2835,2837,2840,2842],{"class":262,"line":306},[260,2815,803],{"class":370},[260,2817,806],{"class":374},[260,2819,2820],{"class":378}," :data-theme",[260,2822,385],{"class":370},[260,2824,388],{"class":370},[260,2826,2827],{"class":391},"isDark ? 'dark' : 'light'",[260,2829,388],{"class":370},[260,2831,2832],{"class":378}," :data-mode",[260,2834,385],{"class":370},[260,2836,388],{"class":370},[260,2838,2839],{"class":391},"isFullscreen ? 'fullscreen' : 'inline'",[260,2841,388],{"class":370},[260,2843,397],{"class":370},[260,2845,2846],{"class":262,"line":312},[260,2847,2848],{"class":409},"    …\n",[260,2850,2851,2853,2855],{"class":262,"line":318},[260,2852,1026],{"class":370},[260,2854,806],{"class":374},[260,2856,397],{"class":370},[260,2858,2859,2861,2863],{"class":262,"line":324},[260,2860,778],{"class":370},[260,2862,795],{"class":374},[260,2864,397],{"class":370},[1375,2866,2867,2363,2869,2872],{"color":1377,"icon":1378},[190,2868,2489],{},[190,2870,2871],{},"null"," on the very first paint and populates after the handshake (typically \u003C50 ms). Always use a fallback in your template.",[1393,2874,2876,2879],{"id":2875},"sendpromptprompt-follow-ups",[190,2877,2878],{},"sendPrompt(prompt)"," — Follow-Ups",[170,2881,2882],{},"Push a message into the chat as if the user had typed it. The LLM then routes it like any other request — including invoking another MCP App:",[250,2884,2886],{"className":360,"code":2885,"language":363,"meta":256,"style":256},"\u003Cbutton @click=\"sendPrompt(`Use ${swatch.name} (${swatch.hex}) as the brand colour.`)\">\n  Use this colour\n\u003C\u002Fbutton>\n",[190,2887,2888,2951,2956],{"__ignoreMap":256},[260,2889,2890,2892,2894,2897,2900,2902,2904,2907,2909,2912,2915,2918,2921,2923,2925,2927,2929,2931,2933,2935,2938,2940,2943,2945,2947,2949],{"class":262,"line":263},[260,2891,371],{"class":370},[260,2893,946],{"class":374},[260,2895,2896],{"class":370}," @",[260,2898,2899],{"class":378},"click",[260,2901,385],{"class":370},[260,2903,388],{"class":370},[260,2905,2906],{"class":498},"sendPrompt",[260,2908,501],{"class":409},[260,2910,2911],{"class":370},"`",[260,2913,2914],{"class":391},"Use ",[260,2916,2917],{"class":370},"${",[260,2919,2920],{"class":409},"swatch",[260,2922,205],{"class":370},[260,2924,1402],{"class":409},[260,2926,727],{"class":370},[260,2928,1580],{"class":391},[260,2930,2917],{"class":370},[260,2932,2920],{"class":409},[260,2934,205],{"class":370},[260,2936,2937],{"class":409},"hex",[260,2939,727],{"class":370},[260,2941,2942],{"class":391},") as the brand colour.",[260,2944,2911],{"class":370},[260,2946,565],{"class":409},[260,2948,388],{"class":370},[260,2950,397],{"class":370},[260,2952,2953],{"class":262,"line":269},[260,2954,2955],{"class":409},"  Use this colour\n",[260,2957,2958,2960,2962],{"class":262,"line":276},[260,2959,778],{"class":370},[260,2961,946],{"class":374},[260,2963,397],{"class":370},[170,2965,2966,2967,2970],{},"The host receives the prompt as if the user had typed it. The LLM may reply, call another tool, or open a different MCP App in response — ",[174,2968,2969],{},"app-to-app workflows"," fall out of this primitive.",[1375,2972,2975,2976,2979],{"color":2973,"icon":2974},"warning","i-lucide-triangle-alert","Follow-ups are best-effort. Hosts that implement ",[190,2977,2978],{},"ui\u002Fmessage"," forward the prompt cleanly. ChatGPT acknowledges the request but doesn't always re-render the next tool inline (an upstream limitation).",[1393,2981,2983,2986],{"id":2982},"calltoolname-params-in-place-refresh",[190,2984,2985],{},"callTool(name, params)"," — In-Place Refresh",[170,2988,2989,2990,2992],{},"Re-invoke any MCP tool from the iframe. The result replaces ",[190,2991,875],{}," automatically:",[250,2994,2996],{"className":360,"code":2995,"language":363,"meta":256,"style":256},"\u003Cscript setup lang=\"ts\">\nconst { data, pending, callTool } = useMcpApp\u003CPalettePayload>()\n\nasync function refresh(base: string) {\n  await callTool('color-picker', { base })\n}\n\u003C\u002Fscript>\n",[190,2997,2998,3018,3050,3054,3076,3102,3106],{"__ignoreMap":256},[260,2999,3000,3002,3004,3006,3008,3010,3012,3014,3016],{"class":262,"line":263},[260,3001,371],{"class":370},[260,3003,375],{"class":374},[260,3005,379],{"class":378},[260,3007,382],{"class":378},[260,3009,385],{"class":370},[260,3011,388],{"class":370},[260,3013,392],{"class":391},[260,3015,388],{"class":370},[260,3017,397],{"class":370},[260,3019,3020,3022,3024,3026,3028,3031,3033,3036,3038,3040,3042,3044,3046,3048],{"class":262,"line":269},[260,3021,740],{"class":378},[260,3023,406],{"class":370},[260,3025,745],{"class":409},[260,3027,472],{"class":370},[260,3029,3030],{"class":409}," pending",[260,3032,472],{"class":370},[260,3034,3035],{"class":409}," callTool ",[260,3037,727],{"class":370},[260,3039,624],{"class":370},[260,3041,762],{"class":498},[260,3043,371],{"class":370},[260,3045,767],{"class":437},[260,3047,654],{"class":370},[260,3049,772],{"class":409},[260,3051,3052],{"class":262,"line":276},[260,3053,273],{"emptyLinePlaceholder":272},[260,3055,3056,3058,3061,3064,3066,3068,3070,3072,3074],{"class":262,"line":282},[260,3057,1953],{"class":378},[260,3059,3060],{"class":378}," function",[260,3062,3063],{"class":498}," refresh",[260,3065,501],{"class":370},[260,3067,2014],{"class":588},[260,3069,449],{"class":370},[260,3071,469],{"class":437},[260,3073,565],{"class":370},[260,3075,441],{"class":370},[260,3077,3078,3081,3084,3086,3088,3090,3092,3094,3096,3098,3100],{"class":262,"line":288},[260,3079,3080],{"class":402},"  await",[260,3082,3083],{"class":498}," callTool",[260,3085,501],{"class":374},[260,3087,519],{"class":370},[260,3089,1257],{"class":391},[260,3091,519],{"class":370},[260,3093,472],{"class":370},[260,3095,406],{"class":370},[260,3097,589],{"class":409},[260,3099,413],{"class":370},[260,3101,691],{"class":374},[260,3103,3104],{"class":262,"line":294},[260,3105,489],{"class":370},[260,3107,3108,3110,3112],{"class":262,"line":300},[260,3109,778],{"class":370},[260,3111,375],{"class":374},[260,3113,397],{"class":370},[170,3115,3116],{},"Use this for filters, pagination, refresh buttons — anything that changes the query without a full chat round-trip.",[1393,3118,3120],{"id":3119},"openlinkurl",[190,3121,3122],{},"openLink(url)",[170,3124,3125,3126,3129],{},"Sandbox iframes can't open windows. ",[190,3127,3128],{},"openLink"," asks the host to do it for you (e.g. open a booking confirmation in a new browser tab):",[250,3131,3133],{"className":360,"code":3132,"language":363,"meta":256,"style":256},"\u003Cbutton @click=\"openLink(`https:\u002F\u002Fexample.com\u002Fcolors\u002F${swatch.hex.slice(1)}`)\">\n  View on the web\n\u003C\u002Fbutton>\n",[190,3134,3135,3187,3192],{"__ignoreMap":256},[260,3136,3137,3139,3141,3143,3145,3147,3149,3151,3153,3155,3158,3160,3162,3164,3166,3168,3171,3173,3176,3178,3181,3183,3185],{"class":262,"line":263},[260,3138,371],{"class":370},[260,3140,946],{"class":374},[260,3142,2896],{"class":370},[260,3144,2899],{"class":378},[260,3146,385],{"class":370},[260,3148,388],{"class":370},[260,3150,3128],{"class":498},[260,3152,501],{"class":409},[260,3154,2911],{"class":370},[260,3156,3157],{"class":391},"https:\u002F\u002Fexample.com\u002Fcolors\u002F",[260,3159,2917],{"class":370},[260,3161,2920],{"class":409},[260,3163,205],{"class":370},[260,3165,2937],{"class":409},[260,3167,205],{"class":370},[260,3169,3170],{"class":498},"slice",[260,3172,501],{"class":409},[260,3174,3175],{"class":1075},"1",[260,3177,565],{"class":409},[260,3179,3180],{"class":370},"}`",[260,3182,565],{"class":409},[260,3184,388],{"class":370},[260,3186,397],{"class":370},[260,3188,3189],{"class":262,"line":269},[260,3190,3191],{"class":409},"  View on the web\n",[260,3193,3194,3196,3198],{"class":262,"line":276},[260,3195,778],{"class":370},[260,3197,946],{"class":374},[260,3199,397],{"class":370},[1375,3201,3202,3203,3206,3207,3210],{"color":1377,"icon":1378},"Add the target host to ",[190,3204,3205],{},"csp.connectDomains"," if you also need to ",[190,3208,3209],{},"fetch()"," it from the iframe.",[165,3212,3214],{"id":3213},"csp-resource-allow-lists","CSP & Resource Allow-Lists",[170,3216,3217,3218,3221],{},"The toolkit injects a ",[174,3219,3220],{},"conservative Content Security Policy"," into every app HTML. By default the iframe can:",[213,3223,3224,3227,3230],{},[216,3225,3226],{},"Run only its own inline script.",[216,3228,3229],{},"Render images and styles only from the same response.",[216,3231,3232,3233,3235],{},"Talk over ",[190,3234,204],{}," to its parent host.",[170,3237,3238],{},"If your UI needs external assets or APIs, allow them explicitly:",[250,3240,3242],{"className":360,"code":3241,"filename":362,"language":363,"meta":256,"style":256},"\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",[190,3243,3244,3264,3272,3287,3295,3317,3337,3341,3403,3409],{"__ignoreMap":256},[260,3245,3246,3248,3250,3252,3254,3256,3258,3260,3262],{"class":262,"line":263},[260,3247,371],{"class":370},[260,3249,375],{"class":374},[260,3251,379],{"class":378},[260,3253,382],{"class":378},[260,3255,385],{"class":370},[260,3257,388],{"class":370},[260,3259,392],{"class":391},[260,3261,388],{"class":370},[260,3263,397],{"class":370},[260,3265,3266,3268,3270],{"class":262,"line":269},[260,3267,231],{"class":498},[260,3269,501],{"class":409},[260,3271,504],{"class":370},[260,3273,3274,3276,3278,3280,3283,3285],{"class":262,"line":276},[260,3275,509],{"class":374},[260,3277,449],{"class":370},[260,3279,419],{"class":370},[260,3281,3282],{"class":391},"Pick a colour and preview a palette.",[260,3284,519],{"class":370},[260,3286,522],{"class":370},[260,3288,3289,3291,3293],{"class":262,"line":282},[260,3290,1603],{"class":374},[260,3292,449],{"class":370},[260,3294,441],{"class":370},[260,3296,3297,3300,3302,3305,3307,3310,3312,3315],{"class":262,"line":288},[260,3298,3299],{"class":374},"    resourceDomains",[260,3301,449],{"class":370},[260,3303,3304],{"class":409}," [",[260,3306,519],{"class":370},[260,3308,3309],{"class":391},"https:\u002F\u002Fimages.unsplash.com",[260,3311,519],{"class":370},[260,3313,3314],{"class":409},"]",[260,3316,522],{"class":370},[260,3318,3319,3322,3324,3326,3328,3331,3333,3335],{"class":262,"line":294},[260,3320,3321],{"class":374},"    connectDomains",[260,3323,449],{"class":370},[260,3325,3304],{"class":409},[260,3327,519],{"class":370},[260,3329,3330],{"class":391},"https:\u002F\u002Fapi.example.com",[260,3332,519],{"class":370},[260,3334,3314],{"class":409},[260,3336,522],{"class":370},[260,3338,3339],{"class":262,"line":300},[260,3340,572],{"class":370},[260,3342,3343,3345,3347,3349,3351,3353,3355,3357,3359,3362,3364,3366,3368,3370,3372,3374,3376,3378,3380,3382,3384,3386,3388,3390,3392,3394,3397,3399,3401],{"class":262,"line":306},[260,3344,577],{"class":498},[260,3346,449],{"class":370},[260,3348,582],{"class":378},[260,3350,585],{"class":370},[260,3352,589],{"class":588},[260,3354,1749],{"class":370},[260,3356,611],{"class":378},[260,3358,1580],{"class":409},[260,3360,3361],{"class":370},"{",[260,3363,601],{"class":374},[260,3365,449],{"class":370},[260,3367,627],{"class":402},[260,3369,630],{"class":498},[260,3371,501],{"class":409},[260,3373,519],{"class":370},[260,3375,661],{"class":391},[260,3377,519],{"class":370},[260,3379,472],{"class":370},[260,3381,406],{"class":370},[260,3383,1780],{"class":374},[260,3385,449],{"class":370},[260,3387,406],{"class":370},[260,3389,2166],{"class":409},[260,3391,727],{"class":370},[260,3393,413],{"class":370},[260,3395,3396],{"class":409},") ",[260,3398,727],{"class":370},[260,3400,565],{"class":409},[260,3402,522],{"class":370},[260,3404,3405,3407],{"class":262,"line":312},[260,3406,727],{"class":370},[260,3408,691],{"class":409},[260,3410,3411,3413,3415],{"class":262,"line":318},[260,3412,778],{"class":370},[260,3414,375],{"class":374},[260,3416,397],{"class":370},[170,3418,3419,3420,3423,3424,3427],{},"The CSP is mirrored into ",[190,3421,3422],{},"_meta.ui.csp"," (and ",[190,3425,3426],{},"openai\u002FwidgetCSP"," for ChatGPT) so hosts that enforce CSP at the iframe level pick up the same rules.",[1375,3429,3430,3431,3434],{"color":2973,"icon":94},"Pass ",[190,3432,3433],{},"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.",[1408,3436,3437,3447],{},[1411,3438,3439],{},[1414,3440,3441,3444],{},[1417,3442,3443],{},"Field",[1417,3445,3446],{},"What it allows",[1427,3448,3449,3469],{},[1414,3450,3451,3456],{},[1432,3452,3453],{},[190,3454,3455],{},"resourceDomains",[1432,3457,3458,3461,3462,3461,3465,3468],{},[190,3459,3460],{},"\u003Cimg>",", ",[190,3463,3464],{},"\u003Cstyle>",[190,3466,3467],{},"\u003Clink>",", fonts loaded from these origins",[1414,3470,3471,3476],{},[1432,3472,3473],{},[190,3474,3475],{},"connectDomains",[1432,3477,3478,3461,3480,3461,3483,3461,3486,3489],{},[190,3479,3209],{},[190,3481,3482],{},"XHR",[190,3484,3485],{},"WebSocket",[190,3487,3488],{},"EventSource"," to these origins",[170,3491,3492,3493,3496,3497,3500],{},"Origins should use ",[190,3494,3495],{},"http(s):\u002F\u002F"," or ",[190,3498,3499],{},"ws(s):\u002F\u002F",". The toolkit rejects empty values, unsupported URL schemes, whitespace, quotes, and semicolons before the app response is served.",[165,3502,3504],{"id":3503},"how-its-wired","How It's Wired",[170,3506,3507,3508,3511,3512,3515],{},"Behind the scenes, each ",[190,3509,3510],{},".vue"," file under the configured apps directory becomes ",[174,3513,3514],{},"three artifacts"," at build time:",[1243,3517,3518,3524,3534],{},[216,3519,228,3520,3523],{},[174,3521,3522],{},"tool definition"," registered on your MCP handler (input schema, description, server handler).",[216,3525,228,3526,1265,3528,3531,3532,205],{},[174,3527,1264],{},[190,3529,3530],{},"ui:\u002F\u002Fmcp-app\u002F\u003Cname>"," returning ",[190,3533,192],{},[216,3535,228,3536,3539],{},[174,3537,3538],{},"single-file HTML bundle"," of the Vue SFC (Vue runtime, your code, scoped CSS, assets) inlined into the resource response.",[170,3541,3542],{},"When the LLM calls the tool:",[1243,3544,3545,3553,3559,3568],{},[216,3546,3547,3548,3550,3551,205],{},"Your ",[190,3549,1287],{}," runs on the server and produces ",[190,3552,1291],{},[216,3554,3555,3556,205],{},"The toolkit injects that data into the bundled HTML as ",[190,3557,3558],{},"\u003Cscript type=\"application\u002Fjson\" id=\"__mcp_app_data__\">…\u003C\u002Fscript>",[216,3560,3561,3562,3564,3565,3567],{},"The host returns the resource to the user; its iframe boots and ",[190,3563,241],{}," reads the inline data into ",[190,3566,875],{}," synchronously.",[216,3569,3570,3571,3461,3574,3461,3576,3578],{},"From there, the iframe and the host exchange messages over a JSON-RPC bridge for ",[190,3572,3573],{},"callTool",[190,3575,2906],{},[190,3577,3128],{},", and theme\u002Fsize updates.",[1375,3580,3581,3582,3585],{"color":1827,"icon":1828},"Everything ships in ",[174,3583,3584],{},"one HTML response",". No extra HTTP request from the iframe, no waterfall, no flicker.",[165,3587,3589],{"id":3588},"host-compatibility","Host Compatibility",[1408,3591,3592,3617],{},[1411,3593,3594],{},[1414,3595,3596,3599,3602,3606,3610,3614],{},[1417,3597,3598],{},"Host",[1417,3600,3601],{},"Render",[1417,3603,3604],{},[190,3605,2906],{},[1417,3607,3608],{},[190,3609,3573],{},[1417,3611,3612],{},[190,3613,3128],{},[1417,3615,3616],{},"Notes",[1427,3618,3619,3638,3661],{},[1414,3620,3621,3626,3629,3631,3633,3635],{},[1432,3622,3623],{},[174,3624,3625],{},"Cursor",[1432,3627,3628],{},"✅",[1432,3630,3628],{},[1432,3632,3628],{},[1432,3634,3628],{},[1432,3636,3637],{},"Tested with the JSON-RPC bridge and legacy ready\u002Fresize messages.",[1414,3639,3640,3645,3647,3650,3652,3654],{},[1432,3641,3642],{},[174,3643,3644],{},"ChatGPT (Apps SDK)",[1432,3646,3628],{},[1432,3648,3649],{},"⚠️",[1432,3651,3628],{},[1432,3653,3628],{},[1432,3655,3656,3657,3660],{},"Uses ",[190,3658,3659],{},"window.openai"," when available. Follow-ups are sent, but the next tool is not always rendered inline.",[1414,3662,3663,3668,3670,3673,3675,3677],{},[1432,3664,3665],{},[174,3666,3667],{},"MCP UI \u002F Inspector-style hosts",[1432,3669,3628],{},[1432,3671,3672],{},"varies",[1432,3674,3672],{},[1432,3676,3672],{},[1432,3678,3679,3680,3683],{},"The bridge emits spec JSON-RPC messages plus legacy ",[190,3681,3682],{},"mcp-ui"," envelopes where useful. Verify each host before documenting support.",[170,3685,3686,3687,3689,3690,205],{},"The bridge auto-detects the host on handshake and adapts to its protocol — modern JSON-RPC for MCP UI hosts, the legacy ",[190,3688,3682],{}," envelope for older clients, the ChatGPT Apps SDK globals when present. Your code just calls ",[190,3691,241],{},[165,3693,3695],{"id":3694},"patterns","Patterns",[1393,3697,3699,3700],{"id":3698},"skeletons-during-calltool","Skeletons during ",[190,3701,3573],{},[170,3703,3704,3706,3707,3709,3710,3712],{},[190,3705,2384],{}," flips to ",[190,3708,2376],{}," only during in-flight ",[190,3711,3573],{}," calls — perfect for partial UI updates without losing the previous data:",[250,3714,3716],{"className":360,"code":3715,"language":363,"meta":256,"style":256},"\u003Cbutton :disabled=\"pending\" @click=\"callTool('color-picker', { base: nextBase })\">\n  {{ pending ? 'Mixing…' : 'Try this colour' }}\n\u003C\u002Fbutton>\n",[190,3717,3718,3775,3780],{"__ignoreMap":256},[260,3719,3720,3722,3724,3727,3730,3732,3734,3736,3738,3740,3742,3744,3746,3748,3750,3752,3754,3756,3758,3760,3762,3764,3767,3769,3771,3773],{"class":262,"line":263},[260,3721,371],{"class":370},[260,3723,946],{"class":374},[260,3725,3726],{"class":370}," :",[260,3728,3729],{"class":378},"disabled",[260,3731,385],{"class":370},[260,3733,388],{"class":370},[260,3735,2384],{"class":409},[260,3737,388],{"class":370},[260,3739,2896],{"class":370},[260,3741,2899],{"class":378},[260,3743,385],{"class":370},[260,3745,388],{"class":370},[260,3747,3573],{"class":498},[260,3749,501],{"class":409},[260,3751,519],{"class":370},[260,3753,1257],{"class":391},[260,3755,519],{"class":370},[260,3757,472],{"class":370},[260,3759,406],{"class":370},[260,3761,589],{"class":374},[260,3763,449],{"class":370},[260,3765,3766],{"class":409}," nextBase ",[260,3768,727],{"class":370},[260,3770,565],{"class":409},[260,3772,388],{"class":370},[260,3774,397],{"class":370},[260,3776,3777],{"class":262,"line":269},[260,3778,3779],{"class":409},"  {{ pending ? 'Mixing…' : 'Try this colour' }}\n",[260,3781,3782,3784,3786],{"class":262,"line":276},[260,3783,778],{"class":370},[260,3785,946],{"class":374},[260,3787,397],{"class":370},[1393,3789,3791],{"id":3790},"adapting-to-fullscreen-vs-inline","Adapting to fullscreen vs inline",[170,3793,3794],{},"Hosts can mount your app inline (small) or expand it fullscreen. Switch layout primitives:",[250,3796,3798],{"className":360,"code":3797,"language":363,"meta":256,"style":256},"\u003Csection :class=\"['rail', isFullscreen && 'rail-grid']\">\n  \u003C!-- horizontal scroll inline, CSS grid in fullscreen -->\n\u003C\u002Fsection>\n",[190,3799,3800,3845,3850],{"__ignoreMap":256},[260,3801,3802,3804,3806,3808,3811,3813,3815,3818,3820,3823,3825,3827,3829,3832,3834,3837,3839,3841,3843],{"class":262,"line":263},[260,3803,371],{"class":370},[260,3805,2409],{"class":374},[260,3807,3726],{"class":370},[260,3809,3810],{"class":378},"class",[260,3812,385],{"class":370},[260,3814,388],{"class":370},[260,3816,3817],{"class":409},"[",[260,3819,519],{"class":370},[260,3821,3822],{"class":391},"rail",[260,3824,519],{"class":370},[260,3826,472],{"class":370},[260,3828,2760],{"class":409},[260,3830,3831],{"class":370},"&&",[260,3833,419],{"class":370},[260,3835,3836],{"class":391},"rail-grid",[260,3838,519],{"class":370},[260,3840,3314],{"class":409},[260,3842,388],{"class":370},[260,3844,397],{"class":370},[260,3846,3847],{"class":262,"line":269},[260,3848,3849],{"class":409},"  \u003C!-- horizontal scroll inline, CSS grid in fullscreen -->\n",[260,3851,3852,3854,3856],{"class":262,"line":276},[260,3853,778],{"class":370},[260,3855,2409],{"class":374},[260,3857,397],{"class":370},[1393,3859,3861],{"id":3860},"app-to-app-workflows","App-to-app workflows",[170,3863,2914,3864,3866],{},[190,3865,2906],{}," from app A and let the LLM dispatch to app B. The user perceives a smooth transition; the LLM stays in the loop and can carry parameters through:",[250,3868,3870],{"className":360,"code":3869,"language":363,"meta":256,"style":256},"\u003Cbutton @click=\"sendPrompt(`Generate a typography scale for ${swatch.hex}.`)\">\n  Pair with type\n\u003C\u002Fbutton>\n",[190,3871,3872,3915,3920],{"__ignoreMap":256},[260,3873,3874,3876,3878,3880,3882,3884,3886,3888,3890,3892,3895,3897,3899,3901,3903,3905,3907,3909,3911,3913],{"class":262,"line":263},[260,3875,371],{"class":370},[260,3877,946],{"class":374},[260,3879,2896],{"class":370},[260,3881,2899],{"class":378},[260,3883,385],{"class":370},[260,3885,388],{"class":370},[260,3887,2906],{"class":498},[260,3889,501],{"class":409},[260,3891,2911],{"class":370},[260,3893,3894],{"class":391},"Generate a typography scale for ",[260,3896,2917],{"class":370},[260,3898,2920],{"class":409},[260,3900,205],{"class":370},[260,3902,2937],{"class":409},[260,3904,727],{"class":370},[260,3906,205],{"class":391},[260,3908,2911],{"class":370},[260,3910,565],{"class":409},[260,3912,388],{"class":370},[260,3914,397],{"class":370},[260,3916,3917],{"class":262,"line":269},[260,3918,3919],{"class":409},"  Pair with type\n",[260,3921,3922,3924,3926],{"class":262,"line":276},[260,3923,778],{"class":370},[260,3925,946],{"class":374},[260,3927,397],{"class":370},[170,3929,3930],{},"The LLM picks the right tool from the prompt — keep names predictable.",[1393,3932,3934],{"id":3933},"co-locating-css","Co-locating CSS",[170,3936,3937,3938,205],{},"Use scoped styles or any CSS-in-JS solution that emits inline styles. The bundler inlines all styles into the HTML; ",[174,3939,3940],{},"no external CSS request fires from the iframe",[165,3942,3944],{"id":3943},"what-you-cannot-do-yet","What You Cannot Do (Yet)",[170,3946,3947,3948,3950],{},"MCP Apps run inside an isolated ",[190,3949,200],{}," with no access to your Nuxt runtime context. That means:",[213,3952,3953,3960,3978,3984],{},[216,3954,3955,3956,3959],{},"❌ ",[174,3957,3958],{},"Nuxt UI \u002F Nuxt Image \u002F NuxtLink"," — they need the parent Nuxt app's runtime.",[216,3961,3955,3962,1580,3965,3461,3968,3461,3971,3461,3974,3977],{},[174,3963,3964],{},"Auto-imported Nuxt composables",[190,3966,3967],{},"useFetch",[190,3969,3970],{},"useState",[190,3972,3973],{},"useRoute",[190,3975,3976],{},"useNuxtApp",", …).",[216,3979,3955,3980,3983],{},[174,3981,3982],{},"Pinia stores or app-level plugins"," — different module graph.",[216,3985,3955,3986,3989],{},[174,3987,3988],{},"Cookies, headers, session from the parent page"," — sandboxed origin.",[170,3991,3992],{},"What you can use:",[213,3994,3995,4010,4016,4024,4035],{},[216,3996,3997,3998,3461,4001,3461,4004,3461,4007,3977],{},"✅ Vue 3 + Composition API (auto-imported: ",[190,3999,4000],{},"ref",[190,4002,4003],{},"computed",[190,4005,4006],{},"watch",[190,4008,4009],{},"onMounted",[216,4011,4012,4013,4015],{},"✅ ",[190,4014,241],{}," — the only toolkit composable in the iframe.",[216,4017,4012,4018,4020,4021,4023],{},[190,4019,1390],{}," inside ",[190,4022,1287],{}," (server side) — call any Nuxt API.",[216,4025,4026,4027,4030,4031,4034],{},"✅ Co-located ",[190,4028,4029],{},".ts","\u002F",[190,4032,4033],{},".css"," helpers next to the SFC (the bundler inlines them).",[216,4036,4037],{},"✅ Headless UI libraries (Reka UI, Headless UI Vue, Floating UI) — they're framework-agnostic.",[1375,4039,4040,4041,4044],{"color":1377,"icon":1378},"Need rich components? Build a small co-located design system in your apps directory, such as ",[190,4042,4043],{},"app\u002Fmcp\u002F_components\u002F"," — it gets bundled into every app that imports it. Or pull in a headless library that doesn't depend on the host runtime.",[165,4046,4048],{"id":4047},"reference","Reference",[1408,4050,4051,4064],{},[1411,4052,4053],{},[1414,4054,4055,4058,4061],{},[1417,4056,4057],{},"API",[1417,4059,4060],{},"Where",[1417,4062,4063],{},"Purpose",[1427,4065,4066,4080,4106,4120,4141],{},[1414,4067,4068,4073,4077],{},[1432,4069,4070],{},[190,4071,4072],{},"defineMcpApp()",[1432,4074,4075],{},[190,4076,235],{},[1432,4078,4079],{},"Declare the tool, schema, handler, CSP. Stripped from the browser bundle.",[1414,4081,4082,4087,4090],{},[1432,4083,4084],{},[190,4085,4086],{},"useMcpApp\u003CT>()",[1432,4088,4089],{},"SFC body",[1432,4091,4092,4093,1485,4095,1485,4097,4099,4100,3461,4102,3461,4104,205],{},"Reactive ",[190,4094,875],{},[190,4096,838],{},[190,4098,2489],{}," + ",[190,4101,3573],{},[190,4103,2906],{},[190,4105,3128],{},[1414,4107,4108,4113,4117],{},[1432,4109,4110],{},[190,4111,4112],{},"csp.resourceDomains",[1432,4114,4115],{},[190,4116,231],{},[1432,4118,4119],{},"Allow-list image \u002F font \u002F style origins.",[1414,4121,4122,4126,4130],{},[1432,4123,4124],{},[190,4125,3205],{},[1432,4127,4128],{},[190,4129,231],{},[1432,4131,4132,4133,1485,4136,1485,4138,4140],{},"Allow-list ",[190,4134,4135],{},"fetch",[190,4137,3482],{},[190,4139,3485],{}," origins.",[1414,4142,4143,4148,4152],{},[1432,4144,4145],{},[190,4146,4147],{},"_meta",[1432,4149,4150],{},[190,4151,231],{},[1432,4153,4154,4155,4157,4158,1250,4161,205],{},"Extra ",[190,4156,4147],{}," fields surfaced to the host alongside ",[190,4159,4160],{},"ui.resourceUri",[190,4162,4163],{},"ui.csp",[170,4165,4166,4167,1250,4169,205],{},"Looking for the underlying tool \u002F resource APIs? See ",[182,4168,46],{"href":47},[182,4170,51],{"href":52},[1052,4172,4173],{},"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 .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}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 .sqsOY, html code.shiki .sqsOY{--shiki-light:#8796B0;--shiki-default:#B2CCD6;--shiki-dark:#B2CCD6}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}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 pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":256,"searchDepth":269,"depth":269,"links":4175},[4176,4177,4178,4181,4185,4195,4196,4197,4198,4205,4206],{"id":167,"depth":269,"text":168},{"id":353,"depth":269,"text":354},{"id":1298,"depth":269,"text":1299,"children":4179},[4180],{"id":1395,"depth":276,"text":1396},{"id":1493,"depth":269,"text":231,"children":4182},[4183,4184],{"id":1649,"depth":276,"text":1650},{"id":1853,"depth":276,"text":1854},{"id":2230,"depth":269,"text":241,"children":4186},[4187,4189,4190,4192,4194],{"id":2353,"depth":276,"text":4188},"data & loading",{"id":2486,"depth":276,"text":2489},{"id":2875,"depth":276,"text":4191},"sendPrompt(prompt) — Follow-Ups",{"id":2982,"depth":276,"text":4193},"callTool(name, params) — In-Place Refresh",{"id":3119,"depth":276,"text":3122},{"id":3213,"depth":269,"text":3214},{"id":3503,"depth":269,"text":3504},{"id":3588,"depth":269,"text":3589},{"id":3694,"depth":269,"text":3695,"children":4199},[4200,4202,4203,4204],{"id":3698,"depth":276,"text":4201},"Skeletons during callTool",{"id":3790,"depth":276,"text":3791},{"id":3860,"depth":276,"text":3861},{"id":3933,"depth":276,"text":3934},{"id":3943,"depth":269,"text":3944},{"id":4047,"depth":269,"text":4048},"Build interactive UI widgets that AI hosts render alongside chat — written as Vue SFCs, served as MCP UI resources.","md",null,{},{"icon":69},{"title":4213,"description":4214},"MCP Apps","Author MCP UI Apps as Vue Single-File Components. Auto-bundled, served from a real Nuxt endpoint, and rendered inside MCP Apps-compatible hosts.","NfFGwnC643bawPoPx3Iu3qJI7tZFnnSbzHgQTWhXKJs",[4217,4219],{"title":61,"path":62,"stem":63,"description":4218,"icon":64,"children":-1},"Create custom MCP endpoints with their own tools, resources, and prompts.",{"title":76,"path":77,"stem":78,"description":4220,"icon":79,"children":-1},"Customize where the module looks for MCP definitions.",1777293382162]