---
title: "Apps"
description: "Build interactive UI widgets that AI hosts render alongside chat — written as Vue SFCs, served as MCP UI resources."
canonical_url: "https://mcp-toolkit.nuxt.dev/apps/overview"
---
# Apps

> Build interactive UI widgets that AI hosts render alongside chat — written as Vue SFCs, served as MCP UI resources.

## What are MCP Apps?

MCP Apps are **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.

They follow the [MCP UI proposal (SEP-1865)](https://modelcontextprotocol.io): a tool returns a `text/html;profile=mcp-app` resource referenced by `ui://`, the host loads it inside a sandboxed `iframe`, and the iframe talks back over `postMessage`.

`@nuxtjs/mcp-toolkit` makes that authoring experience feel like writing a regular Nuxt page:

- One **Vue SFC** per app in `app/mcp/`.
- A `defineMcpApp` macro inside `<script setup>` declares the tool, schema, and server handler.
- A `useMcpApp()` composable gives you reactive data, host context, and a typed bridge to the host.
- The toolkit bundles the SFC into a single self-contained HTML file at build time and serves it from your MCP endpoint.

<prompt :actions="["copy","cursor","windsurf"]" description="Scaffold a new MCP App (Vue SFC)" icon="i-lucide-app-window">

Create a new MCP App in my Nuxt app using @nuxtjs/mcp-toolkit.

- Create a Vue SFC in app/mcp/ (e.g. app/mcp/color-picker.vue)
- Use defineMcpApp({ description, inputSchema, handler }) inside <script setup="" lang="ts">



</script>
- inputSchema uses Zod; handler runs server-side and returns { structuredContent }
- handler can call any Nuxt API route via $fetch — keep heavy data work on the server
- In the template, call useMcpApp<t-payload>

() to get { data, loading, hostContext, sendPrompt, callTool, openLink }

</t-payload>
- data holds structuredContent once the host pushes the tool result — guard the first render with loading
- Use sendPrompt(text) to push a follow-up into the chat that triggers another tool/app
- Use callTool(name, params) to re-invoke an MCP tool and refresh data in place
- Use openLink(url) to ask the host to open a URL outside the iframe
- Add CSP allow-lists with csp: { resourceDomains, connectDomains } if you load images or call external APIs
- To route the app to a dedicated handler, either drop the SFC under `app/mcp/<handler>/` or set `attachTo: '<handler>'` (string literal) on `defineMcpApp`. `group` and `tags` are also accepted as literals.
- Make the layout fluid (no fixed heights); hosts often render the iframe inline at variable widths

Docs: [https://mcp-toolkit.nuxt.dev/apps/overview](https://mcp-toolkit.nuxt.dev/apps/overview)

</prompt>

## Going further

<card-group>
<card color="neutral" icon="i-lucide-cog" title="MCP Apps internals" to="https://mcp-toolkit.nuxt.dev/advanced/mcp-apps-internals">

Build pipeline, host bridge protocol, security model, and advanced composition patterns.

</card>

<card color="neutral" icon="i-lucide-network" title="Multi-handler organization" to="https://mcp-toolkit.nuxt.dev/apps/authoring#routing-apps-to-a-specific-handler">

Route apps to dedicated MCP endpoints (e.g. `/mcp/finder`) via sub-folders or `attachTo`.

</card>

<card color="neutral" icon="i-lucide-shield-check" title="Authenticate clients" to="https://mcp-toolkit.nuxt.dev/examples/authentication">

Hide apps from anonymous callers with the same patterns as tools.

</card>
</card-group>

The rest of this section assumes you are comfortable with [Tools](https://mcp-toolkit.nuxt.dev/tools/overview) (Zod, handlers) and have read [Connection](https://mcp-toolkit.nuxt.dev/getting-started/connection) for MCP URLs in dev and production.

---

- [Authoring](https://mcp-toolkit.nuxt.dev/apps/authoring)
- [useMcpApp bridge](https://mcp-toolkit.nuxt.dev/apps/use-mcp-app)
- [CSP & pipeline](https://mcp-toolkit.nuxt.dev/apps/csp-and-wiring)
- [Testing & publishing](https://mcp-toolkit.nuxt.dev/apps/testing-publishing)


## Sitemap

See the full [sitemap](https://mcp-toolkit.nuxt.dev/sitemap.md) for all pages.
