SEP-2419: cache_hint well-known key in CallToolResult._meta#2419
SEP-2419: cache_hint well-known key in CallToolResult._meta#2419clouatre wants to merge 4 commits intomodelcontextprotocol:mainfrom
Conversation
…meta Standardizes cache_hint as a well-known key in CallToolResult._meta with values 'no-cache' and 'cache'. Allows servers to advise MCP clients whether to cache or skip caching a specific tool result. Pattern follows progressToken (hint-style, non-mandatory) and the well-known _meta key convention from SEP-1686 and SEP-414. No schema interface changes required; declared in specification prose only. Reference implementation: https://github.com/clouatre-labs/code-analyze-mcp Upstream issue: modelcontextprotocol#2400 Signed-off-by: Hugues Clouatre <hugues@linux.com> Signed-off-by: Hugues Clouâtre <hugues@linux.com>
Assigned PR number is 2419. Rename file per SEP process step 3. Signed-off-by: Hugues Clouatre <hugues@linux.com> Signed-off-by: Hugues Clouâtre <hugues@linux.com>
- Run npm run generate:seps to produce docs/seps/2419-cache-hint-tool-result.mdx, update docs/seps/index.mdx, docs/docs.json, and regenerate stale docs/seps/990-enable-enterprise-idp-policy-controls-during-mcp-o.mdx - Run prettier --write on seps/2419-cache-hint-tool-result.md Fixes render-seps and format CI checks. Signed-off-by: Hugues Clouâtre <hugues@linux.com>
- Abstract: remove SEP-1686 as plain-name precedent (it uses DNS-prefixed keys); clarify cache_hint is the first result-side well-known _meta key; note progressToken precedent is on request _meta, not result _meta - Semantics: expand progressToken reference to make the request-vs-result distinction explicit - Rationale: reframe modelcontextprotocol#1788 free-use zone as a proposal, not existing spec property Signed-off-by: Hugues Clouâtre <hugues@linux.com>
|
Wanted to flag a few roadmap connections that might not be immediately obvious. The Result Type Improvements section mentions "reference-based results would let clients decide when to pull large payloads into context rather than polluting it by default." The Agent Communication priority also lists "expiry policies: how long results are retained after completion." SEP-1577 (Sampling With Tools, Final) explicitly deferred a "Cache friendliness updates" section listing "introduce cache awareness" as future work. If any of this is useful for routing to the right reviewer or working group, happy to update the abstract to make the connections explicit. |
|
Production data supporting this proposal — running 452 tools with per-tool TTLs across 137 upstream providers. The
A { "_meta": { "cache_hint": "max-age=300" } }This follows HTTP Interaction with server-side caching and single-flight: When a server caches results internally (as most multi-provider gateways do), the client receives a response that may already be Single-flight deduplication: When multiple concurrent requests hit the same tool+params, the server returns the same result to all callers (thundering herd prevention). All responses should carry the same |
Summary
Standardizes
cache_hintas a well-known key inCallToolResult._meta, allowing servers to advise MCP clients whether to cache or skip caching a specific tool result.Why
MCP clients that support prompt caching (e.g. LLM-backed clients) may insert tool results into their cache to reduce token costs on repeated calls. For single-pass sessions (subagents, benchmarks, one-shot pipelines), the cache entry is written once and never read again: a net token cost with zero benefit. Today the server has no mechanism to advise the client against caching its results. The only available workaround is a global session-level opt-out, not a per-result signal.
The need generalizes beyond any single client. Any MCP client that applies caching at the tool result level faces the same mismatch. Standardizing the key in the MCP specification enables interoperability without requiring bilateral coordination between server and client authors.
This gap is documented in an upstream request (anthropics/claude-code#34334) and in the issue linked below.
What changed
seps/2419-cache-hint-tool-result.md: new SEP proposingcache_hintas a plain-name well-known key inCallToolResult._metawith values"no-cache"and"cache"cache_hintignore it; servers that do not set it are unaffectedDesign decisions
Plain name, not
io.modelcontextprotocol/cache_hint: The draftMetaObjectfrom #1788 (unmerged) places bare keys in the free-use zone. Adopting the prefix before #1788 settles would lock in a naming decision that proposal may revise. The plain name follows theCache-ControlHTTP precedent and remains upgradeable to a prefixed name without a breaking change if #1788 is eventually adopted.String enum, not boolean: Extensible -- future values (e.g.
"immutable") can be added without a breaking change.On the result, not the tool definition: Tool annotations are static. A tool may return cacheable results in some invocations and non-cacheable results in others (e.g. depending on output size or session context). Per-result placement enables per-result control.
Reference implementation
https://github.com/clouatre-labs/code-analyze-mcp (Apache-2.0) -- all four tool paths set
_meta: { "cache_hint": "no-cache" }via a shared helper; integration test validates round-trip serialization.Closes #2400