---
title: "Annotations & input examples"
description: "Behavioral hints for MCP clients and concrete inputExamples for complex tools."
canonical_url: "https://mcp-toolkit.nuxt.dev/tools/annotations"
---
# Annotations & input examples

> Behavioral hints for MCP clients and concrete inputExamples for complex tools.

## Tool Annotations

Annotations are behavioral hints that tell MCP clients how a tool behaves. Clients can use them to decide when to prompt users for confirmation (human-in-the-loop).

```typescript [server/mcp/tools/delete-user.ts]
import { z } from 'zod'
import { defineMcpTool } from '@nuxtjs/mcp-toolkit/server'

export default defineMcpTool({
  name: 'delete-user',
  description: 'Delete a user account',
  inputSchema: {
    userId: z.string(),
  },
  annotations: {
    readOnlyHint: false,    // Tool modifies state
    destructiveHint: true,  // Tool performs destructive updates
    idempotentHint: true,   // Deleting the same user twice has no additional effect
    openWorldHint: false,   // Tool does not interact with external systems
  },
  handler: async ({ userId }) => {
    // ...
  },
})
```

### Annotation Reference

<table>
<thead>
  <tr>
    <th>
      Annotation
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        readOnlyHint
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      If <code>
        true
      </code>
      
      , the tool only reads data without modifying any state (safe to retry).
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        destructiveHint
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      If <code>
        true
      </code>
      
      , the tool may perform destructive operations like deleting data. Only meaningful when <code>
        readOnlyHint
      </code>
      
       is <code>
        false
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        idempotentHint
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      If <code>
        true
      </code>
      
      , calling the tool multiple times with the same arguments has no additional effect beyond the first call. Only meaningful when <code>
        readOnlyHint
      </code>
      
       is <code>
        false
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        openWorldHint
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      If <code>
        true
      </code>
      
      , the tool may interact with the outside world (external APIs, internet). If <code>
        false
      </code>
      
      , it only operates on local/internal data.
    </td>
  </tr>
</tbody>
</table>

Here are common annotation patterns for typical tools:

<code-group>

```typescript [Read-only tool]
// Search, list, lookup, calculate...
annotations: {
  readOnlyHint: true,
  destructiveHint: false,
  openWorldHint: false,
}
```

```typescript [Create tool]
// Creates a new record each time
annotations: {
  readOnlyHint: false,
  destructiveHint: false,
  idempotentHint: false,
  openWorldHint: false,
}
```

```typescript [Update tool]
// Updates are idempotent (same input → same result)
annotations: {
  readOnlyHint: false,
  destructiveHint: false,
  idempotentHint: true,
  openWorldHint: false,
}
```

```typescript [Delete tool]
// Destructive and idempotent (deleting twice is the same)
annotations: {
  readOnlyHint: false,
  destructiveHint: true,
  idempotentHint: true,
  openWorldHint: false,
}
```

</code-group>

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

All annotations are **hints** — they are not guaranteed to be respected by every MCP client. Clients should never make security-critical decisions based on annotations from untrusted servers.

</callout>

## Input Examples

You can provide concrete usage examples for your tools using `inputExamples`. These examples are type-safe (matching your `inputSchema`) and are transmitted to clients via `_meta.inputExamples`.

Input examples help AI models understand how to correctly fill in tool parameters, especially for tools with optional fields or complex inputs.

```typescript [server/mcp/tools/create-todo.ts]
import { z } from 'zod'
import { defineMcpTool } from '@nuxtjs/mcp-toolkit/server'

export default defineMcpTool({
  description: 'Create a new todo',
  inputSchema: {
    title: z.string().describe('The title of the todo'),
    content: z.string().optional().describe('Optional description'),
  },
  inputExamples: [
    { title: 'Buy groceries', content: 'Milk, eggs, bread' },
    { title: 'Fix login bug' },  // content is optional
  ],
  handler: async ({ title, content }) => {
    // ...
  },
})
```

<callout color="warning" icon="i-lucide-lightbulb">

`inputExamples` are particularly useful for tools with optional parameters, enums, or complex nested inputs where showing concrete values helps models pick the right format.

</callout>


## Sitemap

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