Annotations are hints, not permissions: reading an agent's tool list as untrusted input
Published · Updated
MCP says tool annotations are untrusted unless the server is. For an agent that directs its own tool usage, that makes the tool list, not the prompt, the thing worth reviewing.
The distinction is operational, not academic. Workflows are systems where LLMs and tools are orchestrated through predefined code paths. Agents are systems where LLMs dynamically direct their own processes and tool usage, maintaining control over how they accomplish tasks. The moment you choose the second, the tool list stops being configuration and becomes the action space. Reviewing that list is cheaper than reading the transcripts it will produce.
A tool is arbitrary code execution
The Model Context Protocol specification states it plainly: tools represent arbitrary code execution and must be treated with appropriate caution. That is a sentence worth reading with your tool list open. It is not a warning that the model might phrase something badly. It is a statement that each entry is a path into a running system, and that something other than your code decides when it is taken.
The description is not a contract
The specification is equally explicit that descriptions of tool behaviour, such as annotations, should be considered untrusted unless obtained from a trusted server. A read-only hint is a claim made by whoever wrote the server, not a property the protocol enforces. If a guardrail keys off a label like non-destructive, that guardrail is only as strong as the least trustworthy server connected to it. Trust the server first, then its annotations.
Put the authorisation decision downstream
OWASP's guidance on excessive agency is direct: implement authorisation in downstream systems rather than relying on an LLM to decide if an action is allowed or not. That moves the check out of a context window and into code that cannot be talked around. It also survives the untrusted-annotation problem, because the downstream system evaluates the caller's rights rather than a tool's self-description. The model proposes; something else authorises.
Caps that hold even when a description lies
Two controls do not depend on the tool list being honest. Stopping conditions, such as a maximum number of iterations, bound how far a single run can go. Rate limiting reduces the number of undesirable actions that can take place within a given time period. Add human-in-the-loop approval for high-impact actions, and the perimeter still holds when a tool turns out to be misdescribed. None of these require interpreting the model's reasoning.
Breadth is a budget line too
A wide tool list costs tokens before it costs anything else. In Anthropic's data, agents typically use about 4× more tokens than chat interactions, and multi-agent systems use about 15× more tokens than chats. Every additional tool adds description to context and candidates to each turn. The same engineering note warns that the autonomous nature of agents means higher costs and the potential for compounding errors, and recommends extensive testing in sandboxed environments.
Long-running tools want handles, not open calls
The specification adds Tasks: asynchronous execution of long-running operations, with polling, mid-flight input and durable handles. That shapes recovery as much as tooling. Anthropic describes building systems that can resume from where the agent was when the errors occurred, combining the adaptability of AI agents with deterministic safeguards like retry logic and regular checkpoints, and having agents summarise completed work phases into external memory before proceeding. A handle you can poll is a checkpoint you can resume.
Unsupervised runs make the list the whole review
When nobody watches a call as it happens, the constraints have to be in the list, the downstream authorisation and the caps. Our Tatano Energy platform reports manual intervention required: 0 across 4 separately indexed country domains and 7 languages served, with 8 SEO articles published every day. The personal media platform publishes articles autonomously daily behind 3 model fallback levels, at weekly content operations time of ~0 h.
Treat the tool list as untrusted input and the review becomes tractable. Enumerate what each entry can execute, verify which server it came from, and ignore annotations you cannot trace to a trusted one. Put the allow-or-deny decision in the downstream system, bound iterations, rate-limit actions, and route high-impact ones to a human. Then test in a sandbox, because the costs and the compounding errors are the documented failure mode, not a hypothetical one.
Sources
Anthropic — Building effective agents — https://www.anthropic.com/engineering/building-effective-agents
Anthropic — How we built our multi-agent research system — https://www.anthropic.com/engineering/multi-agent-research-system
Model Context Protocol — Specification (version 2026-07-28) — https://modelcontextprotocol.io/specification/2026-07-28
OWASP Gen AI Security Project — LLM06:2025 Excessive Agency — https://genai.owasp.org/llmrisk/llm062025-excessive-agency/
Neurolinks case study — Four markets, one codebase — https://neurolinks.be/work/tatano-energy
Working on a project where these methods apply?