---
title: "Structure & options"
description: "Required fields and every defineMcpHandler option, including tools, resources, and prompts."
canonical_url: "https://mcp-toolkit.nuxt.dev/handlers/structure-and-options"
---
# Structure & options

> Required fields and every defineMcpHandler option, including tools, resources, and prompts.

## Handler Structure

A handler definition consists of:

<code-group>

```typescript [Required Fields]
import { defineMcpHandler } from '@nuxtjs/mcp-toolkit/server'

export default defineMcpHandler({
  name: 'handler-name',  // Unique identifier
})
```

```typescript [Optional Fields]
import { defineMcpHandler } from '@nuxtjs/mcp-toolkit/server'

export default defineMcpHandler({
  name: 'handler-name',
  version: '1.0.0',              // Handler version
  description: 'Admin tools',    // serverInfo description shown by clients
  instructions: 'Always …',      // System-prompt guidance for LLMs
  icons: [ ... ],                 // Server icons shown in client UIs
  route: '/mcp/custom',          // Custom route
  browserRedirect: '/',          // Browser redirect URL
  middleware: async (event) => { ... }, // Request interception
  tools: [ ... ],                 // Array of tools
  resources: [ ... ],            // Array of resources
  prompts: [ ... ],               // Array of prompts
  experimental_codeMode: true,    // Enable code mode (experimental)
})
```

</code-group>

## Handler Options

### `name` (required)

Unique identifier for the handler. The `name` determines where the handler will be mounted. By default, the handler will be accessible at `/mcp/:name`.

```typescript
import { defineMcpHandler } from '@nuxtjs/mcp-toolkit/server'

export default defineMcpHandler({
  name: 'migration', // Handler mounted at /mcp/migration
})
```

### `version` (optional)

Version of the handler. Defaults to the module's configured version.

```typescript
import { defineMcpHandler } from '@nuxtjs/mcp-toolkit/server'

export default defineMcpHandler({
  name: 'migration',
  version: '2.0.0',
})
```

### `description` (optional)

Human-readable description sent as part of `serverInfo` during MCP initialization. Clients use it to identify the handler in UIs (server lists, install prompts, tooltips). Falls back to `mcp.description` from `nuxt.config.ts`.

```typescript
import { defineMcpHandler } from '@nuxtjs/mcp-toolkit/server'

export default defineMcpHandler({
  name: 'admin',
  description: 'Admin tools — destructive operations gated by Bearer auth.',
})
```

### `instructions` (optional)

Operational guidance for AI agents — typically injected by clients into the model's system prompt. Use this to describe workflows, constraints, or relationships between tools (use `description` to identify the handler). Falls back to `mcp.instructions` from `nuxt.config.ts`.

```typescript
import { defineMcpHandler } from '@nuxtjs/mcp-toolkit/server'

export default defineMcpHandler({
  name: 'admin',
  instructions: 'Always call list-users before delete-user. Confirm with the operator before any destructive action.',
})
```

### `icons` (optional)

Icons displayed by clients in their UIs. Each entry needs `src` and `mimeType`, with optional `sizes` and `theme` (`'light' | 'dark'`). Falls back to `mcp.icons` from `nuxt.config.ts`.

```typescript
import { defineMcpHandler } from '@nuxtjs/mcp-toolkit/server'

export default defineMcpHandler({
  name: 'admin',
  icons: [
    { src: 'https://example.com/admin.png', mimeType: 'image/png', sizes: ['64x64'] },
  ],
})
```

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

`description`, `instructions`, and `icons` are part of the [MCP lifecycle spec](https://modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle#initialization). Set them at the module level for shared metadata, override per-handler when a specific endpoint needs different identity.

</callout>

### `route` (optional)

Custom route for the handler. Defaults to `/mcp/:name`.

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

This option is only used for **custom handlers**. For the default handler override (`index.ts`), use `mcp.route` in `nuxt.config.ts` instead.

</callout>

```typescript
import { defineMcpHandler } from '@nuxtjs/mcp-toolkit/server'

export default defineMcpHandler({
  name: 'migration',
  route: '/api/mcp/migration', // Custom route
})
```

### `browserRedirect` (optional)

URL to redirect browsers when they access the handler endpoint. Defaults to the module's configured `browserRedirect`.

```typescript
import { defineMcpHandler } from '@nuxtjs/mcp-toolkit/server'

export default defineMcpHandler({
  name: 'migration',
  browserRedirect: '/docs/migration',
})
```

### `middleware` (optional)

Function to intercept requests before/after they are processed. Useful for authentication, logging, and setting context.

```typescript [server/mcp/custom.ts]
import { defineMcpHandler } from '@nuxtjs/mcp-toolkit/server'

export default defineMcpHandler({
  name: 'custom',
  middleware: async (event) => {
    event.context.userId = 'user-123'
  },
})
```

<callout color="primary" icon="i-lucide-book-open">

See the [Middleware guide](https://mcp-toolkit.nuxt.dev/advanced/middleware) for detailed documentation and examples.

</callout>

### `experimental_codeMode` (optional)

Enable [Code Mode](https://mcp-toolkit.nuxt.dev/advanced/code-mode) to let LLMs orchestrate multiple tool calls in a single JavaScript execution. Pass `true` for defaults or an options object:

```typescript
import { defineMcpHandler } from '@nuxtjs/mcp-toolkit/server'

export default defineMcpHandler({
  name: 'custom',
  experimental_codeMode: {
    progressive: true,
    memoryLimit: 128,
  },
})
```

Code Mode requires `secure-exec` and Node.js `>=18.16.0`.

<callout color="primary" icon="i-lucide-book-open">

See the [Code Mode guide](https://mcp-toolkit.nuxt.dev/advanced/code-mode) for full documentation, security details, and configuration options.

</callout>

### `tools` (optional)

Accepts three shapes — pick whichever matches your use case:

<code-group>

```typescript [Auto (default)]
// server/mcp/handlers/admin/index.ts
import { defineMcpHandler } from '@nuxtjs/mcp-toolkit/server'

// `tools` omitted → every tool under handlers/admin/tools/
// is auto-registered (folder convention).
export default defineMcpHandler({
  middleware: requireAdmin,
})
```

```typescript [Static array]
import { defineMcpTool, defineMcpHandler } from '@nuxtjs/mcp-toolkit/server'

const tool1 = defineMcpTool({ ... })
const tool2 = defineMcpTool({ ... })

export default defineMcpHandler({
  name: 'custom',
  tools: [tool1, tool2],
})
```

```typescript [Dynamic function]
import { defineMcpHandler, getMcpTools } from '@nuxtjs/mcp-toolkit/server'

export default defineMcpHandler({
  // Every tool tagged 'searchable', regardless of folder.
  tools: event => getMcpTools({ event, tags: ['searchable'] }),
})
```

</code-group>

<callout color="primary" icon="i-lucide-book-open">

See [multi-handler organization](https://mcp-toolkit.nuxt.dev/handlers/organization) for the folder convention, and [`getMcpTools`](https://mcp-toolkit.nuxt.dev/advanced/listing-definitions) for ad-hoc filtering. Per-tool `enabled()` guards apply automatically — see [Dynamic Definitions](https://mcp-toolkit.nuxt.dev/advanced/dynamic-definitions).

</callout>

### `resources` (optional)

Same shapes as [`tools`](#tools-optional): omit for folder-convention auto-attribution, pass an array, or pass `event => getMcpResources({ event, ... })`.

```typescript
import { defineMcpResource, defineMcpHandler } from '@nuxtjs/mcp-toolkit/server'

const resource1 = defineMcpResource({ ... })
const resource2 = defineMcpResource({ ... })

export default defineMcpHandler({
  name: 'custom',
  resources: [resource1, resource2],
})
```

### `prompts` (optional)

Same shapes as [`tools`](#tools-optional): omit for folder-convention auto-attribution, pass an array, or pass `event => getMcpPrompts({ event, ... })`.

```typescript
import { defineMcpPrompt, defineMcpHandler } from '@nuxtjs/mcp-toolkit/server'

const prompt1 = defineMcpPrompt({ ... })
const prompt2 = defineMcpPrompt({ ... })

export default defineMcpHandler({
  name: 'custom',
  prompts: [prompt1, prompt2],
})
```


## Sitemap

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