Patterns & limits
Patterns
Skeletons during callTool
pending flips to true only during in-flight callTool calls — perfect for partial UI updates without losing the previous data:
<button :disabled="pending" @click="callTool('color-picker', { base: nextBase })">
{{ pending ? 'Mixing…' : 'Try this colour' }}
</button>
Adapting to fullscreen vs inline
Hosts can mount your app inline (small) or expand it fullscreen. Switch layout primitives:
<section :class="['rail', isFullscreen && 'rail-grid']">
<!-- horizontal scroll inline, CSS grid in fullscreen -->
</section>
App-to-app workflows
Use sendPrompt 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:
<button @click="sendPrompt(`Generate a typography scale for ${swatch.hex}.`)">
Pair with type
</button>
The LLM picks the right tool from the prompt — keep names predictable.
Co-locating CSS
Use scoped styles or any CSS-in-JS solution that emits inline styles. The bundler inlines all styles into the HTML; no external CSS request fires from the iframe.
What You Cannot Do (Yet)
MCP Apps run inside an isolated iframe with no access to your Nuxt runtime context. That means:
- ❌ Nuxt UI / Nuxt Image / NuxtLink — they need the parent Nuxt app's runtime.
- ❌ Auto-imported Nuxt composables (
useFetch,useState,useRoute,useNuxtApp, …). - ❌ Pinia stores or app-level plugins — different module graph.
- ❌ Cookies, headers, session from the parent page — sandboxed origin.
What you can use:
- ✅ Vue 3 + Composition API (auto-imported:
ref,computed,watch,onMounted, …). - ✅
useMcpApp()— the only toolkit composable in the iframe. - ✅
$fetchinsidehandler(server side) — call any Nuxt API. - ✅ Co-located
.ts/.csshelpers next to the SFC (the bundler inlines them). - ✅ Headless UI libraries (Reka UI, Headless UI Vue, Floating UI) — they're framework-agnostic.
app/mcp/_components/ — it gets bundled into every app that imports it. Or pull in a headless library that doesn't depend on the host runtime.Reference
| API | Where | Purpose |
|---|---|---|
defineMcpApp() | <script setup> | Declare the tool, schema, handler, CSP. Stripped from the browser bundle. |
useMcpApp<T>() | SFC body | Reactive data / loading / hostContext + callTool, sendPrompt, openLink. |
csp.resourceDomains | defineMcpApp | Allow-list image / font / style origins. |
csp.connectDomains | defineMcpApp | Allow-list fetch / XHR / WebSocket origins. |
_meta | defineMcpApp | Extra _meta fields surfaced to the host alongside ui.resourceUri and ui.csp. |
Looking for the underlying tool / resource APIs? See Tools and Resources.