Listing Definitions
Overview
The toolkit auto-discovers every tool, resource, and prompt under server/mcp/. From your own server routes you sometimes need to read that catalog back — to render an /.well-known/mcp/server-card.json, an admin dashboard, an API catalog, or a sitemap.
Use the listMcp* helpers from @nuxtjs/mcp-toolkit/server to get JSON-friendly summaries of every discovered definition without duplicating their names and descriptions in your own code.
| Helper | Returns |
|---|---|
listMcpTools(options?) | McpToolSummary[] (JSON-friendly) |
listMcpResources(options?) | McpResourceSummary[] (JSON-friendly) |
listMcpPrompts(options?) | McpPromptSummary[] (JSON-friendly) |
listMcpDefinitions(options?) | { tools, resources, prompts } |
getMcpTools(options?) | McpToolDefinitionListItem[] (raw, with handlers + Zod schemas) |
getMcpResources(options?) | McpResourceDefinition[] (raw) |
getMcpPrompts(options?) | McpPromptDefinition[] (raw) |
Each summary contains name, title, description, group, tags, and handler (plus uri for resources). Names auto-generated from the filename are already resolved, so what you get matches exactly what the MCP client sees in tools/list.
listMcp* for summaries (JSON catalog endpoints). Use getMcp* to feed raw definitions back into defineMcpHandler({ tools: ev => getMcpTools(...) }).Usage
Server card
Expose the toolkit's catalog as a server-card.json so other agents can discover what your server provides:
import { listMcpDefinitions } from '@nuxtjs/mcp-toolkit/server'
export default defineEventHandler(async (event) => {
const { tools, resources, prompts } = await listMcpDefinitions({ event })
return {
name: 'My MCP Server',
description: 'Tools, resources and prompts exposed by my Nuxt app.',
tools: tools.map(t => ({ name: t.name, description: t.description })),
resources: resources.map(r => ({ name: r.name, uri: r.uri, description: r.description })),
prompts: prompts.map(p => ({ name: p.name, description: p.description })),
}
})
Tool catalog
Render a public list of available tools, optionally grouped:
import { listMcpTools } from '@nuxtjs/mcp-toolkit/server'
export default defineEventHandler(async (event) => {
const tools = await listMcpTools({ event })
return Object.groupBy(tools, t => t.group ?? 'default')
})
Options
Every helper accepts the same ListMcpDefinitionsOptions object. All keys are optional and combine with AND semantics — a definition must pass every active filter.
| Option | Type | Description |
|---|---|---|
event | H3Event | Apply per-definition enabled() guards using the request context. |
group | string | string[] | Keep only definitions whose group matches one of these (OR). |
tags | string | string[] | Keep only definitions tagged with at least one of these (OR). |
handler | string | string[] | Keep only definitions attached to one of these named handlers via folder convention. |
orphansOnly | boolean | Return only orphan definitions (those not attached to any named handler). Mutually exclusive with handler. |
Filter by enabled()
Pass the current H3Event to apply per-definition enabled guards. Definitions hidden for the current request are excluded so the catalog you expose matches what the request would actually see in tools/list:
const all = await listMcpTools()
const visible = await listMcpTools({ event })
Filter by group
Auto-inferred from the directory structure (e.g. server/mcp/tools/admin/foo.ts → 'admin') or set explicitly on the definition.
const adminTools = await listMcpTools({ group: 'admin' })
const adminOrContent = await listMcpTools({ group: ['admin', 'content'] })
Filter by tags
Tags use OR-match — pass several to widen the result. To require every listed tag (AND), post-filter the result with Array.filter.
const publicTools = await listMcpTools({ tags: 'public' })
const publicOrDocs = await listMcpTools({ tags: ['public', 'docs'] })
const publicAndStable = (await listMcpTools({ tags: 'public' }))
.filter(t => t.tags?.includes('stable'))
Filter by handler attribution
Use handler to scope the catalog to a single named handler, or orphansOnly: true to enumerate definitions only exposed via the default route:
const adminCatalog = await listMcpTools({ handler: 'admin' })
const adminOrPublic = await listMcpTools({ handler: ['admin', 'public'] })
const orphans = await listMcpTools({ orphansOnly: true })
Combine everything
Filters compose freely — request-aware visibility plus group, tag, and handler narrowing in one call:
const adminDestructive = await listMcpTools({
event,
handler: 'admin',
tags: 'destructive',
})
Caching
Listings are cheap (in-memory reads of the auto-generated registry), but if you expose them on a public route you can still wrap the handler with defineCachedEventHandler to add HTTP cache headers:
import { listMcpDefinitions } from '@nuxtjs/mcp-toolkit/server'
export default defineCachedEventHandler(async (event) => {
const definitions = await listMcpDefinitions({ event })
return { name: 'My MCP Server', ...definitions }
}, {
maxAge: 60 * 60,
swr: true,
})
event to apply enabled() guards that depend on per-request context (auth, headers). Caching would freeze the response for the first request's context.Next Steps
- Dynamic Definitions — Hide or show definitions per request with
enabled()guards. - Hooks — Add extra directories to scan for definitions.
- Handlers — Define custom MCP endpoints with their own subset of tools.