The Model Context Protocol (MCP) supports caching on list and resource read results. This allows clients to cache responses and reduce unnecessary re-fetching. Caching is complementary to change notifications—both mechanisms can coexist.Documentation Index
Fetch the complete documentation index at: https://mcp-staging.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Cacheable Results
Servers MUST include caching hints on results returned by the following operations:tools/listprompts/listresources/listresources/templates/listresources/read
Cacheable Model
Cacheable Results in MCP use two fields to provide caching hints to clients:- The Time-to-live (TTL) Field,
ttlMs, indicates how long the client MAY consider the result fresh. - The Cache Scope Field,
cacheScope, indicates the intended scope of the cached response, either"public"or"private".
Time-to-Live (TTL) Field
ThettlMs field is a hint from the server indicating how long, in
milliseconds, the client MAY consider the result fresh. Semantics are
analogous to HTTP Cache-Control: max-age.
- If
ttlMsis0, the response SHOULD be considered immediately stale. The client MAY re-fetch every time the result is needed. - If
ttlMsis positive, the client SHOULD consider the result fresh for that many milliseconds after receiving the response. - If
ttlMsis absent, clients SHOULD assume a default of0(immediately stale) and rely on their own caching heuristics or notifications. This should only occur in older server versions. - If
ttlMsis negative, clients SHOULD ignore it and treat it as0.
ttlMs value that is >= 0.
TTL is a freshness hint, not a guarantee. Servers MAY change the
underlying data before the TTL expires. The TTL tells the client how long it
can reasonably avoid re-fetching, not how long the data is guaranteed to
remain unchanged.
Freshness Calculation
A client records the local time at which the response was received (t_received). The
response is considered fresh while:
Cache Scope Field
ThecacheScope field controls who may cache a response, analogous to HTTP
Cache-Control: public vs Cache-Control: private.
| Value | Meaning |
|---|---|
"public" | The response does not contain user-specific data. Any client, shared gateway, or caching proxy MAY store and serve the cached response to any user. |
"private" | The response contains private data that is not meant to be shared between callers. Cached responses MAY be reused for the same authorization context. Caches MUST NOT be shared across authorization contexts (e.g. a different access token requires a different cache). |
Choosing a Cache Scope
"public"is appropriate for lists of tools, prompts, and resource templates when they are identical for all users."private"is appropriate forresources/readresults that depend on the authenticated user, or for filtered list results that vary per user.
Interaction with Notifications
TTL and server-push notifications are complementary:- A server MAY provide
ttlMswithout advertisinglistChanged: truein its capabilities. In this case, the client relies entirely on TTL-based freshness. - A server MAY advertise
listChanged: trueand providettlMs. In this case, the client can use the TTL to avoid unnecessary refetches between notifications, and the notification acts as an immediate invalidation signal.
Interaction with Pagination
When a list result is paginated, each page is an independently cacheable response—consistent with how HTTPCache-Control treats paginated resources.
- Each page response carries its own
ttlMsvalue. The freshness clock for each page starts at the time that page was received. - Servers MAY return different
ttlMsvalues on different pages (e.g., a longer TTL for early pages of a stable list, a shorter TTL for the final page). - When a cached page expires, the client SHOULD re-fetch that page using its cursor.
- There is no cross-page consistency guarantee. If the underlying data changes between page fetches, clients may observe duplicates or gaps.
- Clients that require a consistent snapshot of the full list SHOULD re-fetch from the beginning (without a cursor).
- If a cursor becomes invalid (e.g., the server returns an error for a previously valid cursor), the client SHOULD discard all cached pages and re-fetch from the beginning.
Security Considerations
AcacheScope of "public" indicates that the response does not contain user-specific data and can be safely shared. Servers MUST be aware that responses with a "public" cacheScope may be shared between callers even if the Result is coming from an authenticated endpoint. For example, the Result from an authenticated tools/list call with a "public" cacheScope may be cached by a client and may be shared outside of the initial requests authorization context. (i.e. different access tokens can leverage the same cache).
Server implementors:
- should ensure that the
cacheScopecorrectly reflects the intended visibility of the primitive. - MUST apply appropriate per-primitive access controls, and MUST NOT rely on
cacheScopealone to prevent unauthorized access to primitives.