Skip to content

Commit d59fb7e

Browse files
authored
Merge pull request modelcontextprotocol#316 from modelcontextprotocol/basil/tool_annotation_docs
Add documentation for ToolAnnotations
2 parents 4a7eb21 + 16fb5f1 commit d59fb7e

File tree

1 file changed

+163
-0
lines changed

1 file changed

+163
-0
lines changed

docs/docs/concepts/tools.mdx

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ Each tool is defined with the following structure:
3030
inputSchema: { // JSON Schema for the tool's parameters
3131
type: "object",
3232
properties: { ... } // Tool-specific parameters
33+
},
34+
annotations?: { // Optional hints about tool behavior
35+
title?: string; // Human-readable title for the tool
36+
readOnlyHint?: boolean; // If true, the tool does not modify its environment
37+
destructiveHint?: boolean; // If true, the tool may perform destructive updates
38+
idempotentHint?: boolean; // If true, repeated calls with same args have no additional effect
39+
openWorldHint?: boolean; // If true, tool interacts with external entities
3340
}
3441
}
3542
```
@@ -302,6 +309,162 @@ Here's an example of proper error handling for tools:
302309

303310
This approach allows the LLM to see that an error occurred and potentially take corrective action or request human intervention.
304311

312+
## Tool annotations
313+
314+
Tool annotations provide additional metadata about a tool's behavior, helping clients understand how to present and manage tools. These annotations are hints that describe the nature and impact of a tool, but should not be relied upon for security decisions.
315+
316+
### Purpose of tool annotations
317+
318+
Tool annotations serve several key purposes:
319+
320+
1. Provide UX-specific information without affecting model context
321+
2. Help clients categorize and present tools appropriately
322+
3. Convey information about a tool's potential side effects
323+
4. Assist in developing intuitive interfaces for tool approval
324+
325+
### Available tool annotations
326+
327+
The MCP specification defines the following annotations for tools:
328+
329+
| Annotation | Type | Default | Description |
330+
|------------|------|---------|-------------|
331+
| `title` | string | - | A human-readable title for the tool, useful for UI display |
332+
| `readOnlyHint` | boolean | false | If true, indicates the tool does not modify its environment |
333+
| `destructiveHint` | boolean | true | If true, the tool may perform destructive updates (only meaningful when `readOnlyHint` is false) |
334+
| `idempotentHint` | boolean | false | If true, calling the tool repeatedly with the same arguments has no additional effect (only meaningful when `readOnlyHint` is false) |
335+
| `openWorldHint` | boolean | true | If true, the tool may interact with an "open world" of external entities |
336+
337+
### Example usage
338+
339+
Here's how to define tools with annotations for different scenarios:
340+
341+
```typescript
342+
// A read-only search tool
343+
{
344+
name: "web_search",
345+
description: "Search the web for information",
346+
inputSchema: {
347+
type: "object",
348+
properties: {
349+
query: { type: "string" }
350+
},
351+
required: ["query"]
352+
},
353+
annotations: {
354+
title: "Web Search",
355+
readOnlyHint: true,
356+
openWorldHint: true
357+
}
358+
}
359+
360+
// A destructive file deletion tool
361+
{
362+
name: "delete_file",
363+
description: "Delete a file from the filesystem",
364+
inputSchema: {
365+
type: "object",
366+
properties: {
367+
path: { type: "string" }
368+
},
369+
required: ["path"]
370+
},
371+
annotations: {
372+
title: "Delete File",
373+
readOnlyHint: false,
374+
destructiveHint: true,
375+
idempotentHint: true,
376+
openWorldHint: false
377+
}
378+
}
379+
380+
// A non-destructive database record creation tool
381+
{
382+
name: "create_record",
383+
description: "Create a new record in the database",
384+
inputSchema: {
385+
type: "object",
386+
properties: {
387+
table: { type: "string" },
388+
data: { type: "object" }
389+
},
390+
required: ["table", "data"]
391+
},
392+
annotations: {
393+
title: "Create Database Record",
394+
readOnlyHint: false,
395+
destructiveHint: false,
396+
idempotentHint: false,
397+
openWorldHint: false
398+
}
399+
}
400+
```
401+
402+
### Integrating annotations in server implementation
403+
404+
<Tabs>
405+
<Tab title="TypeScript">
406+
```typescript
407+
server.setRequestHandler(ListToolsRequestSchema, async () => {
408+
return {
409+
tools: [{
410+
name: "calculate_sum",
411+
description: "Add two numbers together",
412+
inputSchema: {
413+
type: "object",
414+
properties: {
415+
a: { type: "number" },
416+
b: { type: "number" }
417+
},
418+
required: ["a", "b"]
419+
},
420+
annotations: {
421+
title: "Calculate Sum",
422+
readOnlyHint: true,
423+
openWorldHint: false
424+
}
425+
}]
426+
};
427+
});
428+
```
429+
</Tab>
430+
<Tab title="Python">
431+
```python
432+
from mcp.server.fastmcp import FastMCP
433+
434+
mcp = FastMCP("example-server")
435+
436+
@mcp.tool(
437+
annotations={
438+
"title": "Calculate Sum",
439+
"readOnlyHint": True,
440+
"openWorldHint": False
441+
}
442+
)
443+
async def calculate_sum(a: float, b: float) -> str:
444+
"""Add two numbers together.
445+
446+
Args:
447+
a: First number to add
448+
b: Second number to add
449+
"""
450+
result = a + b
451+
return str(result)
452+
```
453+
</Tab>
454+
</Tabs>
455+
456+
### Best practices for tool annotations
457+
458+
1. **Be accurate about side effects**: Clearly indicate whether a tool modifies its environment and whether those modifications are destructive.
459+
460+
2. **Use descriptive titles**: Provide human-friendly titles that clearly describe the tool's purpose.
461+
462+
3. **Indicate idempotency properly**: Mark tools as idempotent only if repeated calls with the same arguments truly have no additional effect.
463+
464+
4. **Set appropriate open/closed world hints**: Indicate whether a tool interacts with a closed system (like a database) or an open system (like the web).
465+
466+
5. **Remember annotations are hints**: All properties in ToolAnnotations are hints and not guaranteed to provide a faithful description of tool behavior. Clients should never make security-critical decisions based solely on annotations.
467+
305468
## Testing tools
306469

307470
A comprehensive testing strategy for MCP tools should cover:

0 commit comments

Comments
 (0)