|
| 1 | +# Tool Annotations |
| 2 | + |
| 3 | +Tool annotations provide metadata hints about tool behavior, helping clients and UIs make informed decisions about how to present and use tools. MCP Gateway supports the standard MCP annotation types for enhanced tool interaction. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +Tool annotations are optional metadata that can be attached to tools to provide behavioral hints such as: |
| 8 | + |
| 9 | +- **Safety indicators**: Whether a tool is read-only or potentially destructive |
| 10 | +- **Execution hints**: Whether a tool is idempotent or operates in an open-world assumption |
| 11 | +- **UI hints**: How tools should be presented in user interfaces |
| 12 | + |
| 13 | +## Supported Annotation Types |
| 14 | + |
| 15 | +| Annotation | Type | Description | |
| 16 | +|------------|------|-------------| |
| 17 | +| `readOnlyHint` | `boolean` | Indicates the tool only reads data and doesn't modify state | |
| 18 | +| `destructiveHint` | `boolean` | Warns that the tool may cause irreversible changes | |
| 19 | +| `idempotentHint` | `boolean` | Indicates the tool can be called multiple times safely | |
| 20 | +| `openWorldHint` | `boolean` | Suggests the tool operates under open-world assumptions | |
| 21 | + |
| 22 | +## Setting Annotations via Admin UI |
| 23 | + |
| 24 | +Use the Admin UI to set tool annotations through the web interface: |
| 25 | + |
| 26 | +1. Navigate to **Tools** section in the Admin UI |
| 27 | +2. Click **Edit** on the desired tool |
| 28 | +3. In the **Annotations** field, enter JSON: |
| 29 | + |
| 30 | +```json |
| 31 | +{ |
| 32 | + "readOnlyHint": true, |
| 33 | + "destructiveHint": false, |
| 34 | + "idempotentHint": true, |
| 35 | + "openWorldHint": false |
| 36 | +} |
| 37 | +``` |
| 38 | + |
| 39 | +4. Click **Save** to persist the annotations |
| 40 | + |
| 41 | +## Setting Annotations via API |
| 42 | + |
| 43 | +### Complete Annotation Example |
| 44 | + |
| 45 | +Here's a comprehensive example showing all available annotation types: |
| 46 | + |
| 47 | +```bash |
| 48 | +curl -X POST /tools \ |
| 49 | + -H "Content-Type: application/json" \ |
| 50 | + -H "Authorization: Bearer $TOKEN" \ |
| 51 | + -d '{ |
| 52 | + "name": "file-reader", |
| 53 | + "url": "http://example.com/api/read-file", |
| 54 | + "description": "Safely reads file contents", |
| 55 | + "annotations": { |
| 56 | + "readOnlyHint": true, |
| 57 | + "destructiveHint": false, |
| 58 | + "idempotentHint": true, |
| 59 | + "openWorldHint": false |
| 60 | + } |
| 61 | + }' |
| 62 | +``` |
| 63 | + |
| 64 | +### Individual Annotation Examples |
| 65 | + |
| 66 | +#### Read-Only Tool |
| 67 | +```json |
| 68 | +{ |
| 69 | + "name": "get-user-info", |
| 70 | + "url": "http://api.example.com/users", |
| 71 | + "annotations": { |
| 72 | + "readOnlyHint": true |
| 73 | + } |
| 74 | +} |
| 75 | +``` |
| 76 | + |
| 77 | +#### Destructive Tool |
| 78 | +```json |
| 79 | +{ |
| 80 | + "name": "delete-file", |
| 81 | + "url": "http://api.example.com/files/delete", |
| 82 | + "annotations": { |
| 83 | + "destructiveHint": true, |
| 84 | + "idempotentHint": false |
| 85 | + } |
| 86 | +} |
| 87 | +``` |
| 88 | + |
| 89 | +#### Idempotent Tool |
| 90 | +```json |
| 91 | +{ |
| 92 | + "name": "create-user", |
| 93 | + "url": "http://api.example.com/users", |
| 94 | + "annotations": { |
| 95 | + "idempotentHint": true, |
| 96 | + "readOnlyHint": false |
| 97 | + } |
| 98 | +} |
| 99 | +``` |
| 100 | + |
| 101 | +### Updating Existing Tool Annotations |
| 102 | + |
| 103 | +```bash |
| 104 | +curl -X PUT /tools/{tool_id} \ |
| 105 | + -H "Content-Type: application/json" \ |
| 106 | + -H "Authorization: Bearer $TOKEN" \ |
| 107 | + -d '{ |
| 108 | + "annotations": { |
| 109 | + "readOnlyHint": true, |
| 110 | + "destructiveHint": false |
| 111 | + } |
| 112 | + }' |
| 113 | +``` |
| 114 | + |
| 115 | +## Gateway-Discovered Tools |
| 116 | + |
| 117 | +When registering MCP servers via `/gateways`, tools are automatically discovered. To add annotations: |
| 118 | + |
| 119 | +### Step 1: Register the Gateway |
| 120 | +```bash |
| 121 | +curl -X POST /gateways \ |
| 122 | + -H "Content-Type: application/json" \ |
| 123 | + -H "Authorization: Bearer $TOKEN" \ |
| 124 | + -d '{ |
| 125 | + "name": "my-mcp-server", |
| 126 | + "url": "http://localhost:8080/sse" |
| 127 | + }' |
| 128 | +``` |
| 129 | + |
| 130 | +### Step 2: Add Annotations to Discovered Tools |
| 131 | +```bash |
| 132 | +# First, get the tool ID from the tools list |
| 133 | +curl -H "Authorization: Bearer $TOKEN" http://localhost:4444/tools |
| 134 | + |
| 135 | +# Then update the specific tool with annotations |
| 136 | +curl -X PUT /tools/{discovered_tool_id} \ |
| 137 | + -H "Content-Type: application/json" \ |
| 138 | + -H "Authorization: Bearer $TOKEN" \ |
| 139 | + -d '{ |
| 140 | + "annotations": { |
| 141 | + "readOnlyHint": true, |
| 142 | + "destructiveHint": false, |
| 143 | + "idempotentHint": true |
| 144 | + } |
| 145 | + }' |
| 146 | +``` |
| 147 | + |
| 148 | +## Complex Annotation Scenarios |
| 149 | + |
| 150 | +### Mixed Safety Tool |
| 151 | +A tool that reads configuration but may modify cache: |
| 152 | + |
| 153 | +```json |
| 154 | +{ |
| 155 | + "annotations": { |
| 156 | + "readOnlyHint": false, |
| 157 | + "destructiveHint": false, |
| 158 | + "idempotentHint": true, |
| 159 | + "openWorldHint": true |
| 160 | + } |
| 161 | +} |
| 162 | +``` |
| 163 | + |
| 164 | +### High-Risk Administrative Tool |
| 165 | +A tool that performs system-level operations: |
| 166 | + |
| 167 | +```json |
| 168 | +{ |
| 169 | + "annotations": { |
| 170 | + "readOnlyHint": false, |
| 171 | + "destructiveHint": true, |
| 172 | + "idempotentHint": false, |
| 173 | + "openWorldHint": false |
| 174 | + } |
| 175 | +} |
| 176 | +``` |
| 177 | + |
| 178 | +### Information Gathering Tool |
| 179 | +A tool that queries external APIs safely: |
| 180 | + |
| 181 | +```json |
| 182 | +{ |
| 183 | + "annotations": { |
| 184 | + "readOnlyHint": true, |
| 185 | + "destructiveHint": false, |
| 186 | + "idempotentHint": true, |
| 187 | + "openWorldHint": true |
| 188 | + } |
| 189 | +} |
| 190 | +``` |
| 191 | + |
| 192 | +## Best Practices |
| 193 | + |
| 194 | +### 1. **Be Conservative with Safety Hints** |
| 195 | +- Default to `destructiveHint: true` if uncertain |
| 196 | +- Only set `readOnlyHint: true` for genuinely safe operations |
| 197 | + |
| 198 | +### 2. **Consider Idempotency Carefully** |
| 199 | +- Set `idempotentHint: true` only if multiple calls are truly safe |
| 200 | +- Database writes are typically not idempotent unless using upsert patterns |
| 201 | + |
| 202 | +### 3. **Use Open-World Hints Appropriately** |
| 203 | +- Set `openWorldHint: true` for tools that query external data sources |
| 204 | +- Set `openWorldHint: false` for tools operating on known, closed datasets |
| 205 | + |
| 206 | +### 4. **Combine Annotations Logically** |
| 207 | +```json |
| 208 | +// ✅ Good: Read-only tool that's safe to retry |
| 209 | +{ |
| 210 | + "readOnlyHint": true, |
| 211 | + "destructiveHint": false, |
| 212 | + "idempotentHint": true |
| 213 | +} |
| 214 | + |
| 215 | +// ❌ Avoid: Contradictory annotations |
| 216 | +{ |
| 217 | + "readOnlyHint": true, |
| 218 | + "destructiveHint": true // Contradicts read-only |
| 219 | +} |
| 220 | +``` |
| 221 | + |
| 222 | +## Viewing Annotations |
| 223 | + |
| 224 | +Annotations appear in tool JSON responses: |
| 225 | + |
| 226 | +```bash |
| 227 | +curl -H "Authorization: Bearer $TOKEN" \ |
| 228 | + http://localhost:4444/tools/{tool_id} |
| 229 | +``` |
| 230 | + |
| 231 | +Response: |
| 232 | +```json |
| 233 | +{ |
| 234 | + "id": "tool_123", |
| 235 | + "name": "file-reader", |
| 236 | + "url": "http://example.com/api/read-file", |
| 237 | + "annotations": { |
| 238 | + "readOnlyHint": true, |
| 239 | + "destructiveHint": false, |
| 240 | + "idempotentHint": true, |
| 241 | + "openWorldHint": false |
| 242 | + }, |
| 243 | + "description": "Safely reads file contents", |
| 244 | + ... |
| 245 | +} |
| 246 | +``` |
| 247 | + |
| 248 | +## Integration with Clients |
| 249 | + |
| 250 | +Many MCP clients use annotations to: |
| 251 | + |
| 252 | +- **Show warning dialogs** for destructive tools |
| 253 | +- **Enable auto-retry** for idempotent tools |
| 254 | +- **Cache results** from read-only tools |
| 255 | +- **Adjust UI presentation** based on safety hints |
| 256 | + |
| 257 | +Properly annotated tools provide better user experiences and safer AI agent interactions. |
0 commit comments