Skip to content

Commit 36b5717

Browse files
crivetimihairakdutta1
authored andcommitted
744 annotations (IBM#784)
* Fix annotations edit Signed-off-by: Mihai Criveti <[email protected]> * Fix annotations edit Signed-off-by: Mihai Criveti <[email protected]> --------- Signed-off-by: Mihai Criveti <[email protected]>
1 parent 4221c43 commit 36b5717

File tree

3 files changed

+260
-0
lines changed

3 files changed

+260
-0
lines changed

docs/docs/using/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ This section focuses on how to use MCP Gateway effectively as a developer, integ
1717

1818
| Page | Description |
1919
|------|-------------|
20+
| [Tool Annotations](tool-annotations.md) | Configure behavior hints for tools (safety, idempotency, etc.) |
2021
| [mcpgateway-wrapper](mcpgateway-wrapper.md) | Wrap CLI tools or subprocesses to expose them via SSE/stdio |
2122
| [Clients](clients/index.md) | Compatible UIs and developer tools |
2223
| [Agents](agents/index.md) | LangChain, LangGraph, CrewAI, and other frameworks |

docs/docs/using/tool-annotations.md

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
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.

mcpgateway/admin.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1972,6 +1972,7 @@ async def admin_add_tool(
19721972
"integration_type": integration_type,
19731973
"headers": json.loads(form.get("headers") or "{}"),
19741974
"input_schema": json.loads(form.get("input_schema") or "{}"),
1975+
"annotations": json.loads(form.get("annotations") or "{}"),
19751976
"jsonpath_filter": form.get("jsonpath_filter", ""),
19761977
"auth_type": form.get("auth_type", ""),
19771978
"auth_username": form.get("auth_username", ""),
@@ -2210,6 +2211,7 @@ async def admin_edit_tool(
22102211
"description": form.get("description"),
22112212
"headers": json.loads(form.get("headers") or "{}"),
22122213
"input_schema": json.loads(form.get("input_schema") or "{}"),
2214+
"annotations": json.loads(form.get("annotations") or "{}"),
22132215
"jsonpath_filter": form.get("jsonpathFilter", ""),
22142216
"auth_type": form.get("auth_type", ""),
22152217
"auth_username": form.get("auth_username", ""),

0 commit comments

Comments
 (0)