
This page is part of our MCP specification reference, a plain-English guide to the Model Context Protocol spec (version 2026-07-28), within The MCP Guide. Building a server? See MCP development.
MCP tool annotations are optional hints a server attaches to a tool to describe its behavior. They say whether the tool only reads data, whether it might delete or overwrite something, whether repeating a call is safe, and whether it reaches the outside world. Clients use them to decide how carefully to treat a call.
Status in the 2026-07-28 spec: core (optional field). Annotations are defined in the ToolAnnotations type of the 2026-07-28 schema, unchanged in shape since they were added in 2025-03-26.
The most important rule is short. Annotations are hints, not guarantees. A client should never make a trust decision based on annotations from a server it does not trust.
Key Takeaways
- Tool annotations are five optional fields:
title,readOnlyHint,destructiveHint,idempotentHintandopenWorldHint. - The defaults are cautious: a tool is assumed to write data, possibly destructively, and to touch the outside world.
destructiveHintandidempotentHintonly mean something whenreadOnlyHintis false.- The spec says clients MUST treat annotations as untrusted unless they come from trusted servers.
- Good annotations help a client decide when to ask the user for confirmation, which reduces approval fatigue.
What tool annotations are
Annotations live in the annotations field of a tool definition. Here is what each one means, with the defaults from the 2026-07-28 schema:
| Annotation | Meaning when true | Default |
|---|---|---|
readOnlyHint | The tool does not modify its environment | false |
destructiveHint | The tool may perform destructive updates; if false, it only adds | true |
idempotentHint | Repeating the call with the same arguments has no extra effect | false |
openWorldHint | The tool may interact with an open world of external entities | true |
title | A human-readable title for the tool | none |
The schema gives a clear example for the last hint. A web search tool has an open world. A memory tool does not.
Display names follow a fixed order. The schema says the precedence is title, then annotations.title, then name.
Why annotations exist
A client needs to know which tool calls deserve a pause. Reading a calendar is low risk. Deleting a customer record is not. Without hints, a client has to treat every call the same, which means either asking the user about everything or about nothing.
The 2025-03-26 changelog added "comprehensive tool annotations for better describing tool behavior, like whether it is read-only or destructive." The aim is better user experience: fewer pointless prompts for safe reads, and clearer warnings for risky writes.
How it works
A server adds the hints to its tool definition. This example is illustrative, built on the field names in the spec:
{
"name": "delete_invoice",
"title": "Delete Invoice",
"description": "Permanently delete a draft invoice by ID",
"inputSchema": {
"type": "object",
"properties": {
"invoice_id": { "type": "string" }
},
"required": ["invoice_id"]
},
"annotations": {
"readOnlyHint": false,
"destructiveHint": true,
"idempotentHint": true,
"openWorldHint": false
}
}
Deleting the same invoice twice has no extra effect, so it is idempotent. It is destructive because the data is gone. It is closed-world because it only touches the server's own system.
A client might then show a stronger confirmation for this tool than for a read-only list_invoices. The spec does not dictate a specific UI. It does say apps SHOULD present confirmation prompts for operations so a human stays in the loop, per the Tools page.
The trust rule
The Tools page carries this warning: "clients MUST consider tool annotations to be untrusted unless they come from trusted servers." The schema repeats it: "Clients should never make tool use decisions based on ToolAnnotations received from untrusted servers."
Why so strict? A malicious server can mark a destructive tool as read-only. If a client skipped confirmation because of that label, the server would get a free pass. Our guide to MCP tool poisoning covers how attackers abuse tool metadata.
In practice, treat annotations as a way to add caution, not remove it. A "destructive" hint should trigger a warning. A "read-only" hint from an unknown server should not skip one.
What changed across spec versions
| Version | Change |
|---|---|
| 2024-11-05 | No annotations; tools had only name, description and input schema (2024-11-05 Tools) |
| 2025-03-26 | annotations field added, with the untrusted-server warning |
| 2025-06-18 | Top-level title added to tools, so display names can live outside annotations (changelog) |
| 2025-11-25 and 2026-07-28 | Same five annotation fields; the 2026-07-28 changelog lists no change to them |
Note that "annotations" also means something else in MCP. Content blocks and resources have their own annotations: audience, priority and lastModified. Those describe content, not tool behavior. Don't mix them up.
Common mistakes
- Leaving defaults on a read-only tool. If you omit
readOnlyHint, clients assume the tool writes and may be destructive. Set it to true for pure reads so users are not over-prompted. - Setting
destructiveHinton a read-only tool. It only has meaning whenreadOnlyHintis false. - Using annotations as access control. They do nothing on the server. Enforce permissions in your code and your OAuth scopes.
- Trusting hints from unknown servers. That breaks a MUST rule in the spec.
- Mislabeling to reduce prompts. A wrong "read-only" label can lead users to approve calls they would have refused. It also erodes trust in your server.
If your team approves tool calls all day, annotations are one lever against approval fatigue. Our Learn MCP lesson on permissions and approvals shows where users see them.
Next step
Annotations describe what a tool does. Structured output describes what it returns. Read structured tool output in MCP next, or see all topics in the MCP specification reference.
Frequently asked questions
What does readOnlyHint mean in MCP?
readOnlyHint: true tells the client the tool does not modify its environment. The default is false. It is a hint, so clients should only rely on it for servers they trust.
What is the default for destructiveHint?
The default is true. If a tool is not read-only and does not set destructiveHint: false, clients should assume it may make destructive changes.
Are MCP tool annotations a security control?
No. They are hints that help clients decide how to present a call. The spec says clients must treat them as untrusted unless the server is trusted. Real security comes from server-side validation, access control and user confirmation.
What is openWorldHint for?
It says whether a tool may interact with external entities. A web search tool is open-world. A tool that only reads a local memory store is not. The default is true.
Did tool annotations change in the 2026-07-28 spec?
No change to the five fields is listed in the 2026-07-28 changelog. The bigger tool changes in that release were about sessions, caching, schemas and multi-round-trip requests.











