---
title: "Listing Definitions"
description: "Read the toolkit's discovered tools, resources, and prompts from your own server routes — without duplicating their names and descriptions."
canonical_url: "https://mcp-toolkit.nuxt.dev/advanced/listing-definitions"
---
# Listing Definitions

> Read the toolkit's discovered tools, resources, and prompts from your own server routes — without duplicating their names and descriptions.

## 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`](https://modelcontextprotocol.io/specification/2025-11-25/basic/server-cards), 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.

<table>
<thead>
  <tr>
    <th>
      Helper
    </th>
    
    <th>
      Returns
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        listMcpTools(options?)
      </code>
    </td>
    
    <td>
      <code>
        McpToolSummary[]
      </code>
      
       (JSON-friendly)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        listMcpResources(options?)
      </code>
    </td>
    
    <td>
      <code>
        McpResourceSummary[]
      </code>
      
       (JSON-friendly)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        listMcpPrompts(options?)
      </code>
    </td>
    
    <td>
      <code>
        McpPromptSummary[]
      </code>
      
       (JSON-friendly)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        listMcpDefinitions(options?)
      </code>
    </td>
    
    <td>
      <code>
        { tools, resources, prompts }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        getMcpTools(options?)
      </code>
    </td>
    
    <td>
      <code>
        McpToolDefinitionListItem[]
      </code>
      
       (raw, with handlers + Zod schemas)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        getMcpResources(options?)
      </code>
    </td>
    
    <td>
      <code>
        McpResourceDefinition[]
      </code>
      
       (raw)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        getMcpPrompts(options?)
      </code>
    </td>
    
    <td>
      <code>
        McpPromptDefinition[]
      </code>
      
       (raw)
    </td>
  </tr>
</tbody>
</table>

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`.

<callout color="info" icon="i-lucide-info">

Use `listMcp*` for **summaries** (JSON catalog endpoints). Use `getMcp*` to feed **raw definitions** back into [`defineMcpHandler({ tools: ev => getMcpTools(...) })`](https://mcp-toolkit.nuxt.dev/handlers/organization#b-function-form-the-escape-hatch).

</callout>

## Usage

### Server card

Expose the toolkit's catalog as a [`server-card.json`](https://modelcontextprotocol.io/specification/2025-11-25/basic/server-cards) so other agents can discover what your server provides:

```typescript [server/routes/.well-known/mcp/server-card.json.get.ts]
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:

```typescript [server/api/tools.get.ts]
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.

<table>
<thead>
  <tr>
    <th>
      Option
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        event
      </code>
    </td>
    
    <td>
      <code>
        H3Event
      </code>
    </td>
    
    <td>
      Apply per-definition <a href="https://mcp-toolkit.nuxt.dev/advanced/dynamic-definitions#the-enabled-guard">
        <code>
          enabled()
        </code>
        
         guards
      </a>
      
       using the request context.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        group
      </code>
    </td>
    
    <td>
      <code>
        string | string[]
      </code>
    </td>
    
    <td>
      Keep only definitions whose <a href="https://mcp-toolkit.nuxt.dev/tools/groups-organization">
        group
      </a>
      
       matches one of these (OR).
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        tags
      </code>
    </td>
    
    <td>
      <code>
        string | string[]
      </code>
    </td>
    
    <td>
      Keep only definitions tagged with at least one of these (OR).
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        handler
      </code>
    </td>
    
    <td>
      <code>
        string | string[]
      </code>
    </td>
    
    <td>
      Keep only definitions attached to one of these named handlers via <a href="https://mcp-toolkit.nuxt.dev/handlers/organization#a-folder-convention-the-way-to-attribute">
        folder convention
      </a>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        orphansOnly
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      Return only orphan definitions (those not attached to any named handler). Mutually exclusive with <code>
        handler
      </code>
      
      .
    </td>
  </tr>
</tbody>
</table>

### 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`:

```typescript
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.

```typescript
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`.

```typescript
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](https://mcp-toolkit.nuxt.dev/handlers/organization), or `orphansOnly: true` to enumerate definitions only exposed via the default route:

```typescript
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:

```typescript
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`](https://nitro.build/guide/cache#cached-event-handlers) to add HTTP cache headers:

```typescript [server/routes/.well-known/mcp/server-card.json.get.ts]
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,
})
```

<callout color="warning" icon="i-lucide-triangle-alert">

Skip the cache wrapper if you pass `event` to apply `enabled()` guards that depend on per-request context (auth, headers). Caching would freeze the response for the first request's context.

</callout>

## Next Steps

- [Dynamic Definitions](https://mcp-toolkit.nuxt.dev/advanced/dynamic-definitions) — Hide or show definitions per request with `enabled()` guards.
- [Hooks](https://mcp-toolkit.nuxt.dev/advanced/hooks) — Add extra directories to scan for definitions.
- [Handlers](https://mcp-toolkit.nuxt.dev/handlers/overview) — Define custom MCP endpoints with their own subset of tools.


## Sitemap

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