|
1 | | -# Advanced Tool Config |
| 1 | +# Advanced Tools |
| 2 | + |
| 3 | +## Tool Annotations |
| 4 | + |
| 5 | +Tool annotations are metadata attached to each tool definition. They help clients and users understand the tool's behavior, especially regarding side effects, safety, and intended use. Annotations do **not** affect the tool's execution. They are hints for UI, approval flows, and documentation. |
| 6 | + |
| 7 | +<callout-warning> |
| 8 | + Annotations are *not* security features. They are advisory only and should not |
| 9 | + be relied on for access control or sandboxing. |
| 10 | +</callout-warning> |
| 11 | + |
| 12 | +### Why Use Annotations? |
| 13 | + |
| 14 | +- **UX clarity:** Help users understand what a tool does before approving its use. |
| 15 | +- **Safety:** Warn about potentially destructive or open-world actions. |
| 16 | +- **Automation:** Allow clients to group, filter, or require extra approval for certain tools. |
| 17 | + |
| 18 | +### Example Tool Definition: Launch Real-Life Confetti |
| 19 | + |
| 20 | +Here's a fun (and slightly dangerous) example of a tool that launches a real confetti cannon in the physical world: |
| 21 | + |
| 22 | +```ts |
| 23 | +{ |
| 24 | + name: 'launch_confetti', |
| 25 | + description: |
| 26 | + 'Launch a real confetti cannon in the physical world to celebrate! (Warning: may make a mess)', |
| 27 | + inputSchema: { |
| 28 | + type: 'object', |
| 29 | + properties: { |
| 30 | + color: { type: 'string', description: 'The color of the confetti' }, |
| 31 | + intensity: { |
| 32 | + type: 'string', |
| 33 | + enum: ['low', 'medium', 'high'], |
| 34 | + description: 'How much confetti to launch', |
| 35 | + }, |
| 36 | + location: { |
| 37 | + type: 'string', |
| 38 | + description: |
| 39 | + "Where to launch the confetti (e.g., 'main office', 'living room')", |
| 40 | + }, |
| 41 | + }, |
| 42 | + required: ['color', 'location'], |
| 43 | + }, |
| 44 | + annotations: { |
| 45 | + title: 'Launch Real-Life Confetti', |
| 46 | + readOnlyHint: false, |
| 47 | + destructiveHint: true, |
| 48 | + idempotentHint: false, |
| 49 | + openWorldHint: true, |
| 50 | + }, |
| 51 | +} |
| 52 | +``` |
| 53 | + |
| 54 | +- `readOnlyHint: false` - This tool physically changes the environment (and makes a mess!). |
| 55 | +- `destructiveHint: true` - Launching confetti can be considered a destructive action (cleanup required). |
| 56 | +- `openWorldHint: true` - This tool literally interacts with the real world, not just the local system/service provider. |
| 57 | +- `idempotentHint: false` - This tool is not idempotent because it makes a mess (and the cannon may need a reload to work again). |
| 58 | + |
| 59 | +<callout-warning> |
| 60 | + A tool like this should require explicit user approval and be used with |
| 61 | + caution. Imagine the consequences of launching confetti in the wrong place at |
| 62 | + the wrong time! |
| 63 | +</callout-warning> |
| 64 | + |
| 65 | +### How Annotations Affect the Client |
| 66 | + |
| 67 | +Clients can use annotations to: |
| 68 | + |
| 69 | +- Display warnings or require confirmation for destructive tools |
| 70 | +- Group or filter tools (e.g., show only read-only tools) |
| 71 | +- Provide friendlier names in the UI |
| 72 | +- Decide when to allow automation or require human approval |
| 73 | + |
| 74 | +<callout-success> |
| 75 | + Annotations make it easier to build safe, user-friendly interfaces for tool |
| 76 | + invocation. |
| 77 | +</callout-success> |
| 78 | + |
| 79 | +### Best Practices |
| 80 | + |
| 81 | +1. **Be accurate about side effects:** Mark tools as `readOnlyHint: true` only if they never modify state. |
| 82 | +2. **Use descriptive titles:** The `title` annotation should be clear and human-friendly. |
| 83 | +3. **Indicate idempotency:** Use `idempotentHint: true` only if repeated calls with the same arguments are safe and have no extra effect. |
| 84 | +4. **Set open/closed world hints:** Use `openWorldHint: true` for tools that interact with the internet or external systems. |
| 85 | +5. **Remember: annotations are hints!** Never rely on them for security or correctness. |
| 86 | + |
| 87 | +<callout-muted> |
| 88 | + Annotations are for humans and UIs, not for enforcing security or correctness. |
| 89 | +</callout-muted> |
| 90 | + |
| 91 | +### Learn More 📜 |
| 92 | + |
| 93 | +For a full list of available annotations and their meanings, see the [official MCP documentation on tool annotations](https://modelcontextprotocol.io/docs/concepts/tools#tool-annotations). |
| 94 | + |
| 95 | +## Structured Output and Output Schemas |
| 96 | + |
| 97 | +Structured output allows tools to return rich, machine-validated data instead of just plain text. By defining an `outputSchema` for a tool, the server ensures that all tool responses conform to a specific structure, making it easier for clients and LLMs to consume, validate, and act on the results. |
| 98 | + |
| 99 | +### Why Use Structured Output? |
| 100 | + |
| 101 | +- **Reliability:** Ensures tool responses are predictable and machine-parseable. |
| 102 | +- **Validation:** Automatic schema validation prevents malformed or incomplete data from propagating. |
| 103 | +- **Automation:** Enables downstream automation, UI rendering, and chaining of tool results. |
| 104 | +- **Safety:** Reduces the risk of misinterpretation or injection by strictly defining expected output. |
| 105 | + |
| 106 | +### How It Works |
| 107 | + |
| 108 | +1. **Tool Definition:** The tool specifies an `outputSchema` (JSON Schema) describing the expected result structure. |
| 109 | +2. **Tool Execution:** When the tool is called, the server validates the output against the schema before returning it to the client. |
| 110 | +3. **Client Consumption:** Clients and LLMs can safely parse and use the structured result, knowing it matches the schema. |
| 111 | +4. **Error Handling:** If the output does not match the schema, an error is returned instead of invalid data. |
| 112 | + |
| 113 | +### Example Tool with Output Schema |
| 114 | + |
| 115 | +Suppose we have a tool that generates a random fantasy character profile: |
| 116 | + |
| 117 | +```ts |
| 118 | +{ |
| 119 | + name: 'generate_fantasy_character', |
| 120 | + description: |
| 121 | + 'Creates a random fantasy character profile for games or stories.', |
| 122 | + inputSchema: { |
| 123 | + type: 'object', |
| 124 | + properties: { |
| 125 | + theme: { |
| 126 | + type: 'string', |
| 127 | + description: |
| 128 | + 'Optional theme for the character (e.g., "forest", "fire", "ice")', |
| 129 | + }, |
| 130 | + }, |
| 131 | + required: [], |
| 132 | + }, |
| 133 | + outputSchema: { |
| 134 | + type: 'object', |
| 135 | + properties: { |
| 136 | + name: { type: 'string', description: "The character's name" }, |
| 137 | + species: { |
| 138 | + type: 'string', |
| 139 | + description: 'The fantasy species (e.g., elf, orc, dragon)', |
| 140 | + }, |
| 141 | + characterClass: { |
| 142 | + type: 'string', |
| 143 | + description: |
| 144 | + "The character's class or role (e.g., wizard, rogue, paladin)", |
| 145 | + }, |
| 146 | + abilities: { |
| 147 | + type: 'array', |
| 148 | + items: { type: 'string' }, |
| 149 | + description: 'A list of special abilities or powers', |
| 150 | + }, |
| 151 | + }, |
| 152 | + required: ['name', 'species', 'characterClass', 'abilities'], |
| 153 | + }, |
| 154 | +} |
| 155 | +``` |
| 156 | + |
| 157 | +### Example Request/Response with Structured Content |
| 158 | + |
| 159 | +#### Request |
| 160 | + |
| 161 | +```json |
| 162 | +{ |
| 163 | + "jsonrpc": "2.0", |
| 164 | + "id": 99, |
| 165 | + "method": "tools/call", |
| 166 | + "params": { |
| 167 | + "name": "generate_fantasy_character", |
| 168 | + "arguments": { |
| 169 | + "theme": "forest" |
| 170 | + } |
| 171 | + } |
| 172 | +} |
| 173 | +``` |
| 174 | + |
| 175 | +#### Response |
| 176 | + |
| 177 | +```json |
| 178 | +{ |
| 179 | + "jsonrpc": "2.0", |
| 180 | + "id": 99, |
| 181 | + "result": { |
| 182 | + "content": [ |
| 183 | + { |
| 184 | + "type": "text", |
| 185 | + "text": "{\"name\": \"Lirael Mosswhisper\", \"species\": \"Elf\", \"characterClass\": \"Druid\", \"abilities\": [\"Speak with Animals\", \"Vine Whip\", \"Forest Camouflage\"]}" |
| 186 | + } |
| 187 | + ], |
| 188 | + "structuredContent": { |
| 189 | + "name": "Lirael Mosswhisper", |
| 190 | + "species": "Elf", |
| 191 | + "characterClass": "Druid", |
| 192 | + "abilities": ["Speak with Animals", "Vine Whip", "Forest Camouflage"] |
| 193 | + } |
| 194 | + } |
| 195 | +} |
| 196 | +``` |
| 197 | + |
| 198 | +### Validation Flow |
| 199 | + |
| 200 | +Below is a sequence diagram showing how structured content is validated: |
| 201 | + |
| 202 | +```mermaid |
| 203 | +sequenceDiagram |
| 204 | + participant User |
| 205 | + participant App |
| 206 | + participant LLM |
| 207 | + participant Client |
| 208 | + participant Server |
| 209 | + User->>App: Enter prompt |
| 210 | + App->>LLM: Send prompt |
| 211 | + LLM-->>App: Tool call request (expects structured output) |
| 212 | + App->>Client: Forward tool call |
| 213 | + Client->>Server: JSON-RPC tool call |
| 214 | + Server-->>Client: JSON-RPC response (with structuredContent) |
| 215 | + Note right of Server: Validate output against outputSchema |
| 216 | + alt Output valid |
| 217 | + Client-->>App: Structured result |
| 218 | + App->>LLM: Structured result |
| 219 | + LLM-->>App: Generation (uses structured data) |
| 220 | + App-->>User: Display structured result |
| 221 | + else Output invalid |
| 222 | + Client-->>App: Error (schema validation failed) |
| 223 | + App->>User: Show error |
| 224 | + end |
| 225 | +``` |
| 226 | + |
| 227 | +### Best Practices |
| 228 | + |
| 229 | +1. **Define clear output schemas:** Use JSON Schema to describe all possible fields and types. |
| 230 | +2. **Validate on the server:** Always validate tool output before returning to the client (the SDK does this for us). |
| 231 | +3. **Handle validation errors gracefully:** Inform users or clients when output does not match the schema (the SDK does this for us). |
| 232 | + |
| 233 | +For more details, see the [official MCP documentation on structured content and output schemas](https://modelcontextprotocol.io/specification/2025-06-18/server/tools#structured-content). |
0 commit comments