Proposal: Add cacheControl hint to ToolAnnotations for volatile data
#686
Replies: 1 comment
-
|
May 2026 update Since filing this in February, the MCP team published Tool Annotations as Risk Vocabulary (March 16), which introduced a Tool Annotations Interest Group and a formal evaluation framework for new annotation proposals. That post also lists the five SEPs currently under active review - all addressing trust, sensitivity, and security boundaries. None of them address result volatility. I want to use their framework to sharpen the two open questions I left unresolved. On Q2: Is The Interest Group has explicitly placed on its agenda whether annotations should live on tool responses as well as tool definitions. That question is directly relevant here.
This also makes On Q4: Are there simpler native solutions? The Interest Group's own post answers this directly:
The failure mode here is not deployment-specific. Any MCP client - regardless of vendor - that does not distinguish between volatile and durable tool results will exhibit temporal blindness after out-of-band mutations. On the trust profile One concern that tends to come up with new annotations is how much trust they require to be useful.
Compare this to The evaluation framework in the March post ends with: "If you're thinking of proposing a new annotation, the questions above are a good place to start shaping it." This comment is that exercise. The next step from my side would be a formal SEP draft. Is there a preferred path to bring this to the Tool Annotations Interest Group? |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Pre-submission Checklist
Your Idea
While building a multi-agent architecture on top of MCP for a SaaS product, I ran into a consistent failure mode with stale context in multi-turn conversations. I'd love to get the community's input on a small addition to the spec.
The Problem: Out-of-band mutations
The scenario is straightforward:
sprints.get, gets "Nov 1 to Nov 10", replies correctly.The agent operates under a closed-world assumption — it behaves as if it's the only actor mutating data. This failure mode has been formally studied: Cheng et al. (arXiv:2510.23853) coined the term Temporal Blindness for exactly this, showing that no tested model achieved better than 65% alignment with real-world state after out-of-band mutations. Singh (Preprints:202601.0910) formalized State Drift — the persistent, hidden misalignment between an agent's internal state and the environment — showing that increasing context capacity alone does not prevent it. The causal variant, where the agent's own writes create contradictory representations within the same context window, is particularly dangerous in agentic MCP workflows.
The core issue in MCP
Right now, the protocol treats all tool results as equally durable. A tool returning "The capital of France" and a tool returning "Current Sprint Status" carry the same epistemological weight in context. There's no standard way for the server to communicate data volatility to the client.
The Proposal
Extend
ToolAnnotationswith acacheControlhint:Semantics map to RFC 7234 conventions:
immutable— result will never change (git commit hash, country codes, ICD-10 codes). Safe to reuse across turns.no-store— result is volatile. The model should re-invoke the tool on the next relevant turn rather than answering from context.The rationale for borrowing RFC 7234 vocabulary is that these terms carry strong pre-existing semantic weight from LLM training data. The association between
no-storeand "do not reuse this response" is already embedded in the model's weights from exposure to HTTP documentation, API specs, and developer discussions. There is intentionally nomax-age— LLMs have no clock, so time-based expiration is meaningless inside a context window.Related work in the spec
I noticed SEP-1862 (Tool Resolution) by @SamMorrowDrums proposes a
tools/resolvemechanism for argument-aware annotation refinement. These two proposals are complementary rather than overlapping:If both land, they compose naturally:
tools/listcould declare a staticcacheControl: 'no-store', andtools/resolvecould refine it — e.g., amanage_datatool might beno-storeforaction: 'get_balance'butimmutableforaction: 'get_currency_code'.Prior art / reference implementation
I've been running this pattern in production and open-sourced a layer that implements it today as a workaround: vinkius-labs/mcp-state-sync. It decorates tool descriptions with
[Cache-Control: no-store]attools/listtime and injects causal invalidation signals into write responses. It's not a spec replacement — it's an application-layer patch that demonstrates the mechanism works in practice across fintech, healthcare, and infrastructure scenarios.Questions for the community
ToolAnnotationsthe right place for this, or should volatility hints live elsewhere in the spec?tools/resolvefor argument-aware cache hints?Scope
Beta Was this translation helpful? Give feedback.
All reactions