MCP Tool Annotations Explained: What the Four Hints Actually Mean

MCP Tool Annotations Explained: What the Four Hints Actually Mean

Todd Mercer

A cobalt core remains unchanged while four translucent blue, coral, amber, and green forms reveal different properties around it.

MCP Tool Annotations Explained: What the Four Hints Actually Mean

MCP tool annotations are optional metadata that describe four aspects of a tool's intended behavior: whether it is read-only, potentially destructive, idempotent, and open-world. They help clients present warnings and choose safer defaults. They are not permissions, guarantees, or a substitute for checking the exact tool, input, identity, and consequence.

The current Model Context Protocol tools specification is explicit about the trust boundary: clients must treat annotations as untrusted unless they come from a trusted server. A client that sees readOnlyHint: true should not silently grant access to data or assume every accepted input is side-effect free.

The annotations object can also include a human-readable title. This guide focuses on the four behavioral hints:

Annotation

What true means

Default when omitted

What it does not prove

readOnlyHint

The tool does not modify its environment

false

That returned data is harmless or within the user's scope

destructiveHint

A modifying tool may perform destructive rather than additive updates

true

That false makes a write reversible or automatically safe

idempotentHint

Repeating the same modifying call has no additional effect

false

That retries are safe after the input or server state changes

openWorldHint

The tool may interact with an unpredictable set of external entities

true

That a closed-world tool is authorized or trustworthy

Those defaults are deliberately conservative. An unannotated tool is treated as potentially modifying, destructive, non-idempotent, and open-world. The official MCP article on tool annotations as risk vocabulary describes the same posture: use the hints for client UX, but keep actual safety guarantees in deterministic controls.

readOnlyHint: Does the Tool Change State?

Set readOnlyHint: true only when the tool performs no side effect beyond consuming computational resources. A search, list, or get operation can qualify, but its name is not enough.

Inspect the input schema for fields that can change the consequence. A message-retrieval tool with markAsRead: true, a get-named tool that starts an export, or a list operation that refreshes a remote cache may alter state. If any accepted input can do that, a blanket read-only annotation is misleading unless the server splits the behavior into separate tools or constrains the schema.

Read-only also does not mean low-risk. A tool can reveal customer records, source code, credentials, private messages, or commercially sensitive analytics without changing the provider. Authorization still has to limit which account, collection, fields, filters, and date range the agent may read.

A narrowly scoped read tool might declare:

{
  "name": "get_campaign_summary",
  "annotations": {
    "readOnlyHint": true,
    "openWorldHint": true
  }
}

That says the operation is intended not to modify state and reaches an external system. It does not say which campaign the caller may inspect.

destructiveHint: Is a Write Additive or Destructive?

destructiveHint matters when readOnlyHint is false. A destructive operation can overwrite, delete, revoke, pause, replace, or otherwise remove an existing state. An additive operation creates something new without altering what was already there.

The difference is useful for confirmation UX, but destructiveHint: false is not a universal safety label. Creating a CRM contact, sending a message, opening a ticket, or adding a calendar event can still have a significant business consequence. Additive writes can create duplicates, trigger downstream automation, expose data, or contact a person.

Classify the business result, not only the HTTP method. A POST can perform an idempotent update. A PATCH can overwrite a critical value. A create-named tool can start a paid asynchronous job.

idempotentHint: Can the Exact Call Be Repeated?

Set idempotentHint: true only when repeating the same tool call with the same arguments has no additional effect. This hint is most meaningful for modifying tools.

For example, setting an existing record's status to paused may be idempotent if the provider guarantees that a second identical request leaves the same state. Appending a note, sending an email, or creating a lead usually is not idempotent without a stable provider-supported idempotency key or duplicate-prevention contract.

Even a correctly annotated idempotent operation needs a bounded retry policy. Before retrying, preserve the same arguments, request identity, and idempotency key. Stop when the first call may have succeeded but the response was lost and no read-back can determine the terminal state.

Do not infer idempotency from a successful test. It is a provider contract that should be documented and verified under the same inputs and version.

openWorldHint: Does the Tool Reach External Entities?

openWorldHint: true means a tool may interact with an unpredictable or dynamic set of entities. Web search, email, social networks, external APIs, and customer workspaces are common open-world examples. A tool limited to a fixed local memory store is closer to closed-world.

This hint affects both sides of the call:

  • Before execution, open-world inputs may transmit data outside the agent's local boundary.

  • After execution, open-world results may contain untrusted instructions, links, files, or content controlled by someone else.

A closed-world annotation does not make the server itself trusted. It only describes the intended domain of interaction. The client still needs transport authentication, server identity, output validation, and a policy for which returned content can reach the model.

Why Annotations Are Not a Permission System

Annotations are supplied by the server that defines the tool. A malicious server can lie. A well-meaning server can be wrong. A tool can also change behavior while retaining an old annotation.

That is why a safe client keeps authorization elsewhere:

  1. Identity: verify the server, connection, workspace, and account.

  2. Allowlist: approve the exact current tool, not an entire integration by name.

  3. Input policy: restrict resource IDs, fields, filters, limits, recipients, and date ranges.

  4. Consequence review: explain what can be read, created, changed, sent, exported, or deleted.

  5. Execution control: require confirmation for sensitive operations and bind it to the exact input.

  6. Read-back: verify the smallest terminal state that proves the result stayed in scope.

  7. Audit: record the request, decision, provider result, cost boundary, and retry history.

The specification's security guidance also keeps a human denial path for tool invocations and recommends showing sensitive inputs before a call. Use annotations to improve that experience, not to bypass it.

Audit One MCP Tool Annotation Contract

Review a server one tool at a time. For each current tool definition:

  1. Record the name, description, input schema, output schema, and all annotations.

  2. Compare readOnlyHint with every accepted input, including optional booleans and modes.

  3. If the tool writes, decide whether destructiveHint matches the worst allowed consequence.

  4. Verify idempotentHint against provider documentation, duplicate behavior, and retry keys.

  5. Decide whether inputs or results cross into an open world of external entities.

  6. Test one bounded example and one invalid input without using production data.

  7. Diff the approved definition whenever the server or provider contract changes.

The MCP Inspector guide shows how to inspect a server's exposed tools and schemas. Continue with the risk-versus-spend approval workflow when the consequence needs human review, even if the call is free.

Inspect the Current Action, Not a Remembered Name

When an MCP tool is represented through Aident Loadout, search by the job and inspect the exact current public Action before preflight:

aident account auth status

aident capabilities search \
  --query "list campaigns read only" \
  --types '["action"]' \
  --targetEnv staging

aident capabilities get \
  --name "<PUBLIC_ACTION_NAME>"

aident capabilities preflight \
  --name "<PUBLIC_ACTION_NAME>" \
  --input '{"limit":5}'

Copy the exact public name returned by search. Review the full schema and exact input rather than relying on the annotation, provider label, or verb in the name. Preflight can validate the input and quote platform cost, but a valid schema and free quote do not authorize data access or prove the operation is harmless.

After execution, use the Aident Action usage audit to reconcile the external operation with its status, source, and cost record.

A Minimal Review Record

Keep one compact record for each approved tool version:

Field

Record

Tool identity

Server, tool name, schema version, and provider

Annotation claim

All four values, including defaults applied when absent

Exact approved input

Resource scope, limits, filters, and sensitive fields

Expected consequence

Read, create, update, send, export, pause, or delete

Trust basis

Why the server and its current definition are trusted

Retry contract

Idempotency key, duplicate prevention, and stop condition

Verification

Smallest read-back or receipt that proves the terminal result

Refresh trigger

Server, schema, provider, policy, or client-behavior change

The durable rule is simple: annotations describe intent; policy grants authority. Use both, but never confuse one for the other.

Inspect One MCP Tool Contract

Follow https://aident.ai/SETUP.md

Set up Aident Loadout, inspect one current public Action and its exact input schema, then preflight a bounded read-only request. Treat annotations as context for review, not as permission to execute.

Set up Loadout and inspect one MCP tool contract

Sources

Refresh this guide when the MCP specification changes the annotation fields, defaults, trust guidance, or client requirements, or when Aident changes its public Action schema, preflight, approval, or audit contract.

About the author

Illustrated editorial avatar of Todd Mercer

Todd Mercer

Todd Mercer is an editorial pen name used by Aident's developer-tools team. This column covers agent CLI configuration, MCP connectivity, authentication, permissions, and troubleshooting. Guides focus on observable symptoms, documented fixes, reproducible checks where available, and the limits of each workaround.

Home

Home

Home

Integrations

Integrations

Integrations

Vault

Vault

Vault

Audit

Audit

Audit

Arana Grande

Arana Grande

Arana Grande

Free

Free

Free

30-day audit summary

30-day audit summary

30-day audit summary

Daily action-call volume and the latest receipts from the Loadout audit trail.

Daily action-call volume and the latest receipts from the Loadout audit trail.

Daily action-call volume and the latest receipts from the Loadout audit trail.

View Audit

View Audit

View Audit

Loadout usage

Loadout usage

Loadout usage

617 action calls in the last 30 days

617 action calls in the last 30 days

617 action calls in the last 30 days

May 19 - Jun 17

May 19 - Jun 17

May 19 - Jun 17

10 active days

10 active days

10 active days

Less

Less

Less

More

More

More

Recent activity

Recent activity

Recent activity

Latest action-call receipts from connected agents

Latest action-call receipts from connected agents

Latest action-call receipts from connected agents

Apr 23, 09:23 AM

Apr 23, 09:23 AM

Apr 23, 09:23 AM

Shopify

Shopify

Shopify

Creates Or Updates An Asset For A Theme

Creates Or Updates An Asset For A Theme

Creates Or Updates An Asset For A Theme

Success

Success

Success

Apr 23, 09:21 AM

Apr 23, 09:21 AM

Apr 23, 09:21 AM

Shopify

Shopify

Shopify

Update Products Param Product Id

Update Products Param Product Id

Update Products Param Product Id

Success

Success

Success

Apr 23, 08:53 AM

Apr 23, 08:53 AM

Apr 23, 08:53 AM

Shopify

Shopify

Shopify

Update Products Param Product Id

Update Products Param Product Id

Update Products Param Product Id

Failed

Failed

Failed

Apr 22, 22:13 PM

Apr 22, 22:13 PM

Apr 22, 22:13 PM

Shopify

Shopify

Shopify

Create Product Image

Create Product Image

Create Product Image

Success

Success

Success

Apr 22, 22:12 PM

Apr 22, 22:12 PM

Apr 22, 22:12 PM

Shopify

Shopify

Shopify

Create Product Image

Create Product Image

Create Product Image

Success

Success

Success

Connected integration coverage

Connected integration coverage

Connected integration coverage

162

162

162

of 753 accessible connected

of 753 accessible connected

of 753 accessible connected

Callable actions

Callable actions

Callable actions

1,126

1,126

1,126

Vault credentials

Vault credentials

Vault credentials

8

8

8

Explore what's possible

Explore what's possible

Explore what's possible

See all Integrations

See all Integrations

See all Integrations

Google Ads

Google Ads

Google Ads

All available Goolge Ads tools via...

All available Goolge Ads tools via...

All available Goolge Ads tools via...

X (twitter)

X (twitter)

X (twitter)

All available X tools via...

All available X tools via...

All available X tools via...

Github

Github

Github

All available Github tools via...

All available Github tools via...

All available Github tools via...

Notion

Notion

Notion

All available Notion tools via...

All available Notion tools via...

All available Notion tools via...

Slack

Slack

Slack

All available Slack tools via...

All available Slack tools via...

All available Slack tools via...

Firecrawl

Firecrawl

Firecrawl

All available Firecrawl tools via...

All available Firecrawl tools via...

All available Firecrawl tools via...

753 integrations are available for loadouts.

753 integrations are available for loadouts.

753 integrations are available for loadouts.

The one tool

for every tool

your agent needs.

Give any AI agent real capabilities in seconds. Connect 27,000+ tools once, skip the setup headache, and let your agents execute.

Try Aident Loadout

Empower your Codex or OpenClaws to get real jobs done. Connect 27,000+ tools in one prompt, and let your agents deliver real results.

Try Aident Loadout

Empower your Codex or OpenClaws to get real jobs done. Connect 27,000+ tools in one prompt, and let your agents deliver real results.

Try Aident Loadout

Empower your Codex or OpenClaws to get real jobs done. Connect 27,000+ tools in one prompt, and let your agents deliver real results.