Skip to content
This repository was archived by the owner on Apr 8, 2025. It is now read-only.

Commit fc70450

Browse files
Add documentation for annotations in MCP
- Create new annotations.mdx concept doc explaining annotations - Update tools.mdx to include annotation examples - Add annotations to sidebar navigation in docs.json 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent af2c937 commit fc70450

File tree

3 files changed

+246
-2
lines changed

3 files changed

+246
-2
lines changed

docs.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
"docs/concepts/resources",
4545
"docs/concepts/prompts",
4646
"docs/concepts/tools",
47+
"docs/concepts/annotations",
4748
"docs/concepts/sampling",
4849
"docs/concepts/roots",
4950
"docs/concepts/transports"

docs/concepts/annotations.mdx

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
---
2+
title: "Annotations"
3+
description: "Metadata for enhancing client UX without affecting model context"
4+
---
5+
6+
# Annotations
7+
8+
Annotations are a powerful feature in the Model Context Protocol (MCP) that allow servers to provide additional metadata about content without affecting what the model sees. They provide a way to separate UX concerns from the actual content presented to the model.
9+
10+
## Overview
11+
12+
Annotations serve as a bridge between what's useful for the user interface and what should be included in model context. This separation is important because:
13+
14+
1. Not all content that's useful for UI rendering belongs in the model's context
15+
2. Metadata about content (like priority, intended audience, visual hints) can improve client UX without bloating model context
16+
17+
## Annotation structure
18+
19+
The MCP specification defines the `Annotations` interface with the following structure:
20+
21+
```typescript
22+
export interface Annotations {
23+
/**
24+
* Describes who the intended customer of this object or data is.
25+
*
26+
* It can include multiple entries to indicate content useful for multiple audiences (e.g., `["user", "assistant"]`).
27+
*/
28+
audience?: Role[];
29+
30+
/**
31+
* Describes how important this data is for operating the server.
32+
*
33+
* A value of 1 means "most important," and indicates that the data is
34+
* effectively required, while 0 means "least important," and indicates that
35+
* the data is entirely optional.
36+
*
37+
* @minimum 0
38+
* @maximum 1
39+
*/
40+
priority?: number;
41+
}
42+
```
43+
44+
## Where annotations can be used
45+
46+
Annotations can be attached to various MCP objects:
47+
48+
- **Tool results** (`TextContent`, `ImageContent`, `AudioContent`) - helping clients render tool outputs properly without affecting what the model sees
49+
- **Resources** - providing additional metadata about resources
50+
- **Resource templates** - adding metadata to resource template definitions
51+
- **Embedded resources** - enhancing embedded resources with presentation hints
52+
53+
## Example: Tool with annotated results
54+
55+
Here's an example of a tool returning text content with annotations:
56+
57+
```typescript
58+
// Server-side implementation
59+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
60+
if (request.params.name === "weather_forecast") {
61+
// Tool execution logic...
62+
return {
63+
content: [
64+
{
65+
type: "text",
66+
text: "Tomorrow: Sunny, High 75°F, Low 60°F\nWinds: Light, 5mph NW",
67+
annotations: {
68+
audience: ["user"], // This is intended primarily for user viewing
69+
priority: 1.0 // This is important information
70+
}
71+
},
72+
{
73+
type: "text",
74+
text: "Weather data powered by WeatherAPI.com",
75+
annotations: {
76+
audience: ["user"], // This is intended for user viewing only
77+
priority: 0.2 // This is less important information
78+
}
79+
}
80+
]
81+
};
82+
}
83+
throw new Error("Tool not found");
84+
});
85+
```
86+
87+
## Tool annotations
88+
89+
Tools have special annotation properties defined in the `ToolAnnotations` interface:
90+
91+
```typescript
92+
export interface ToolAnnotations {
93+
/**
94+
* A human-readable title for the tool.
95+
*/
96+
title?: string;
97+
98+
/**
99+
* If true, the tool does not modify its environment.
100+
* Default: false
101+
*/
102+
readOnlyHint?: boolean;
103+
104+
/**
105+
* If true, the tool may perform destructive updates to its environment.
106+
* If false, the tool performs only additive updates.
107+
* Default: true
108+
*/
109+
destructiveHint?: boolean;
110+
111+
/**
112+
* If true, calling the tool repeatedly with the same arguments
113+
* will have no additional effect on the its environment.
114+
* Default: false
115+
*/
116+
idempotentHint?: boolean;
117+
118+
/**
119+
* If true, this tool may interact with an "open world" of external
120+
* entities. If false, the tool's domain of interaction is closed.
121+
* Default: true
122+
*/
123+
openWorldHint?: boolean;
124+
}
125+
```
126+
127+
Example usage:
128+
129+
```typescript
130+
{
131+
name: "delete_file",
132+
description: "Delete a file from the filesystem",
133+
inputSchema: {
134+
type: "object",
135+
properties: {
136+
path: { type: "string" }
137+
},
138+
required: ["path"]
139+
},
140+
annotations: {
141+
title: "Delete File",
142+
readOnlyHint: false,
143+
destructiveHint: true,
144+
idempotentHint: true,
145+
openWorldHint: false
146+
}
147+
}
148+
```
149+
150+
## Best practices
151+
152+
1. **Separate UI concerns from model context**
153+
- Use annotations for UI-specific information
154+
- Keep model context focused on necessary information
155+
156+
2. **Be judicious with audience targeting**
157+
- Use `audience: ["user"]` for content meant only for humans
158+
- Use `audience: ["assistant"]` for content meant only for the model
159+
- Use `audience: ["user", "assistant"]` for content relevant to both
160+
161+
3. **Use priority appropriately**
162+
- Set high priority (close to 1) for essential information
163+
- Set low priority (close to 0) for supplementary information
164+
165+
4. **Add semantic hints for tools**
166+
- Use tool annotations to help clients understand the nature of tools
167+
- Be accurate with hints like `readOnlyHint` and `destructiveHint`
168+
169+
## Security considerations
170+
171+
Tool annotations are just hints and should not be relied upon for security decisions. Clients should never make tool use decisions based solely on annotations received from untrusted servers.

docs/concepts/tools.mdx

Lines changed: 74 additions & 2 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 annotations for additional metadata
35+
title?: string; // Human-readable title for UI display
36+
readOnlyHint?: boolean; // If true, tool doesn't modify environment
37+
destructiveHint?: boolean; // If true, tool may perform destructive updates
38+
idempotentHint?: boolean; // If true, tool is idempotent
39+
openWorldHint?: boolean; // If true, tool interacts with external entities
3340
}
3441
}
3542
```
@@ -76,7 +83,11 @@ Here's an example of implementing a basic tool in an MCP server:
7683
content: [
7784
{
7885
type: "text",
79-
text: String(a + b)
86+
text: String(a + b),
87+
annotations: {
88+
audience: ["user", "assistant"],
89+
priority: 1.0
90+
}
8091
}
8192
]
8293
};
@@ -115,7 +126,16 @@ Here's an example of implementing a basic tool in an MCP server:
115126
a = arguments["a"]
116127
b = arguments["b"]
117128
result = a + b
118-
return [types.TextContent(type="text", text=str(result))]
129+
return [
130+
types.TextContent(
131+
type="text",
132+
text=str(result),
133+
annotations={
134+
"audience": ["user", "assistant"],
135+
"priority": 1.0
136+
}
137+
)
138+
]
119139
raise ValueError(f"Tool not found: {name}")
120140
```
121141
</Tab>
@@ -302,6 +322,58 @@ Here's an example of proper error handling for tools:
302322

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

325+
## Tool annotations
326+
327+
Tools and tool results in MCP support annotations, which provide additional metadata to guide client behavior without affecting the model's context. Annotations help separate UI concerns from model context.
328+
329+
### Tool definition annotations
330+
331+
When defining tools, you can include annotations that help clients understand the tool's characteristics:
332+
333+
```typescript
334+
{
335+
name: "update_database",
336+
description: "Update a database record",
337+
inputSchema: { /* ... */ },
338+
annotations: {
339+
title: "Update Database", // Human-readable title for UI
340+
readOnlyHint: false, // This tool modifies state
341+
destructiveHint: false, // Updates are non-destructive
342+
idempotentHint: true, // Can be called multiple times safely
343+
openWorldHint: false // Interacts with a closed system
344+
}
345+
}
346+
```
347+
348+
### Tool result annotations
349+
350+
Tool results can include annotations on content items to guide how clients should present the information:
351+
352+
```typescript
353+
return {
354+
content: [
355+
{
356+
type: "text",
357+
text: "Operation successful: Record updated",
358+
annotations: {
359+
audience: ["user", "assistant"], // Show to both user and model
360+
priority: 1.0 // High importance
361+
}
362+
},
363+
{
364+
type: "text",
365+
text: "Processed by Database Service v1.2",
366+
annotations: {
367+
audience: ["user"], // Only show to user, not to model
368+
priority: 0.2 // Low importance
369+
}
370+
}
371+
]
372+
};
373+
```
374+
375+
For more details on annotations, see the [Annotations](/docs/concepts/annotations) documentation.
376+
305377
## Testing tools
306378

307379
A comprehensive testing strategy for MCP tools should cover:

0 commit comments

Comments
 (0)