Tools
Errors & caching
H3 and plain errors in tool handlers, and Nitro-backed response caching.
Error Handling
Throw errors directly from your handlers — just like in Nitro event handlers. Thrown errors are automatically caught and converted into MCP-compliant isError results.
H3 Errors (Recommended)
Use createError() from H3 for errors with status codes:
server/mcp/tools/get-user.ts
import { z } from 'zod'
import { createError } from 'h3'
import { defineMcpTool } from '@nuxtjs/mcp-toolkit/server'
export default defineMcpTool({
name: 'get-user',
description: 'Get a user by ID',
inputSchema: {
id: z.string(),
},
handler: async ({ id }) => {
const user = await findUser(id)
if (!user) {
throw createError({ statusCode: 404, message: 'User not found' })
}
return user
},
})
// Error result: { isError: true, content: [{ type: 'text', text: '[404] User not found' }] }
H3 errors can also include structured data:
throw createError({
statusCode: 400,
message: 'Validation failed',
data: { fields: ['name', 'email'] },
})
// Error text: '[400] Validation failed\n{ "fields": ["name", "email"] }'
Plain Errors
Regular Error instances work too:
server/mcp/tools/safe-divide.ts
import { z } from 'zod'
import { defineMcpTool } from '@nuxtjs/mcp-toolkit/server'
export default defineMcpTool({
name: 'safe-divide',
inputSchema: {
a: z.number(),
b: z.number(),
},
handler: async ({ a, b }) => {
if (b === 0) throw new Error('Division by zero')
return a / b
},
})
Response Caching
You can cache tool responses using Nitro's caching system. The cache option accepts three formats:
Simple Duration
Use a string duration (parsed by ms) or a number in milliseconds:
server/mcp/tools/cached-data.ts
import { z } from 'zod'
import { defineMcpTool } from '@nuxtjs/mcp-toolkit/server'
export default defineMcpTool({
description: 'Fetch data with 1 hour cache',
inputSchema: {
id: z.string(),
},
cache: '1h', // or '30m', '2 days', 3600000, etc.
handler: async ({ id }) => {
return await fetchExpensiveData(id)
},
})
Full Cache Options
For more control, use an object with all Nitro cache options:
server/mcp/tools/cached-pages.ts
import { z } from 'zod'
import { defineMcpTool } from '@nuxtjs/mcp-toolkit/server'
export default defineMcpTool({
description: 'Get page with custom cache key',
inputSchema: {
path: z.string(),
},
cache: {
maxAge: '1h',
getKey: args => `page-${args.path}`,
swr: true, // stale-while-revalidate
},
handler: async ({ path }) => {
// ...
},
})
Cache Options Reference
| Option | Type | Required | Description |
|---|---|---|---|
maxAge | string | number | Yes | Cache duration (e.g., '1h', 3600000) |
getKey | (args) => string | No | Custom cache key generator |
staleMaxAge | number | No | Duration for stale-while-revalidate |
swr | boolean | No | Enable stale-while-revalidate |
name | string | No | Cache name (auto-generated from tool name) |
group | string | No | Cache group (default: 'mcp') |
See the Nitro Cache documentation for all available options.