Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 0 additions & 55 deletions .changeset/apps-routing.md

This file was deleted.

48 changes: 0 additions & 48 deletions .changeset/nitro-runtime-hooks.md

This file was deleted.

2 changes: 1 addition & 1 deletion apps/mcp-starter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"lint:fix": "eslint . --fix"
},
"dependencies": {
"@nuxtjs/mcp-toolkit": "^0.16.1",
"@nuxtjs/mcp-toolkit": "^0.17.0",
"nuxt": "^4.4.5",
"zod": "^4.1.13"
},
Expand Down
103 changes: 103 additions & 0 deletions packages/nuxt-mcp-toolkit/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,108 @@
# @nuxtjs/mcp-toolkit

## 0.17.0

### Minor Changes

- [#248](https://github.com/nuxt-modules/mcp-toolkit/pull/248) [`067ab3e`](https://github.com/nuxt-modules/mcp-toolkit/commit/067ab3e3e0164b0b69da16f5394dd1f870bf68ff) Thanks [@HugoRCD](https://github.com/HugoRCD)! - Route MCP Apps to any named handler — no manual filtering required. Until now every `defineMcpApp` SFC was hard-attributed to the implicit `apps` handler, so multiple `app/mcp/*.vue` files could only be exposed together on `/mcp/apps`. Two new mechanisms (consistent with the rest of the module) let you split apps across handlers.

### Sub-folder convention

The first sub-directory under `app/mcp/` becomes the named-handler attribution — same idea as `server/mcp/handlers/<name>/` for tools, resources, and prompts:

```bash
app/mcp/
├── color-picker.vue # → /mcp/apps (default)
├── finder/
│ └── stay-finder.vue # → /mcp/finder
└── checkout/
└── stay-checkout.vue # → /mcp/checkout
```

Pair each sub-folder with its handler index file (one-liner is fine):

```ts [server/mcp/handlers/finder/index.ts]
import { defineMcpHandler } from "@nuxtjs/mcp-toolkit/server";

export default defineMcpHandler({});
```

With `defaultHandlerStrategy: 'orphans'` (the default), each app surfaces on exactly one route.

### Explicit `attachTo` / `group` / `tags` overrides

Three new fields on `defineMcpApp` let an SFC opt out of the folder convention or add filterable metadata. They override any sub-folder default:

```vue [app/mcp/stay-finder.vue]
<script setup lang="ts">
defineMcpApp({
attachTo: "finder", // override → /mcp/finder
group: "stays", // top-level filter for getMcpTools({ group })
tags: ["searchable", "demo"], // top-level filter for getMcpTools({ tags })
// ...
});
</script>
```

The generated tool and resource carry `_meta.handler = 'finder'`, top-level `group` and `tags`, so `getMcpTools({ handler: 'finder' })` / `getMcpTools({ tags: ['searchable'] })` filters work the same way they do for ordinary tools.

### Build-time validation

`attachTo`, `group`, and `tags` must be **string literals** (e.g. `'finder'`, `['a', 'b']`). The toolkit reads them statically from the `defineMcpApp` macro at build time so routing decisions are deterministic across dev, build, and deploy. A dynamic expression (`attachTo: someVar`) fails the build with a clear message.

### Back-compat

100% additive — apps without sub-folders or explicit overrides keep their previous behaviour (attached to `apps`, surfaced on `/mcp/apps`). The previous "manual filter inside `defineMcpHandler`" workaround documented in [MCP Apps internals](https://mcp-toolkit.nuxt.dev/advanced/mcp-apps-internals#multiple-handlers) is no longer required.

See [Apps · Authoring → Routing apps to a specific handler](https://mcp-toolkit.nuxt.dev/apps/authoring#routing-apps-to-a-specific-handler).

- [#250](https://github.com/nuxt-modules/mcp-toolkit/pull/250) [`1ad6f3d`](https://github.com/nuxt-modules/mcp-toolkit/commit/1ad6f3d8eebd3e74e688e688a49f12734130158b) Thanks [@HugoRCD](https://github.com/HugoRCD)! - Expose two Nitro runtime hooks for the MCP request lifecycle. Subscribe from a `server/plugins/*.ts` plugin to inject custom logic without owning a `defineMcpHandler` — listeners that throw are logged via consola and the request continues.

```
defineMcpHandler middleware → mcp:config:resolved → createMcpServer → mcp:server:created → transport
```

### `mcp:config:resolved`

Fires per request after dynamic `tools` / `resources` / `prompts` resolvers and `enabled(event)` guards have run, **before** the per-request `McpServer` is built. Mutate `ctx.config` in place to add, remove or transform definitions for this request only.

```ts [server/plugins/mcp-filter.ts]
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook("mcp:config:resolved", ({ config, event }) => {
if (!event.context.user) {
config.tools = config.tools.filter((t) => !t.tags?.includes("admin"));
}
});
});
```

### `mcp:server:created`

Fires per request after every tool / resource / prompt has been registered, **before** the server is connected to the transport. Receives the SDK `McpServer` instance — call `server.registerTool(...)` to add definitions late, or use `getSdkServer(server)` to reach the low-level `Server` and `setRequestHandler(...)` for custom JSON-RPC methods.

```ts [server/plugins/mcp-whoami.ts]
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook("mcp:server:created", ({ server, event }) => {
server.registerTool(
"whoami",
{ description: "Return the current user id" },
async () => ({
content: [
{ type: "text", text: String(event.context.userId ?? "anonymous") },
],
})
);
});
});
```

### Public API additions

- `McpResolvedConfig` — type of the resolved per-request server config.
- `getSdkServer(server)` — reach the underlying SDK `Server` instance from an `McpServer`.

Both are exported from `@nuxtjs/mcp-toolkit/server`. See [Hooks · Runtime hooks](https://mcp-toolkit.nuxt.dev/advanced/hooks#runtime-hooks).

## 0.16.1

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/nuxt-mcp-toolkit/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nuxtjs/mcp-toolkit",
"version": "0.16.1",
"version": "0.17.0",
"description": "Create MCP servers directly in your Nuxt application. Define tools, resources, and prompts with a simple and intuitive API.",
"repository": {
"type": "git",
Expand Down