SEP-2549: TTL for List Results changedseps/2549-TTL-for-list-results
Nearest release: v2.1.252, published under an hour after upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
Upstream edited this page at 31 Aug 2026 16:44 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 28 Sep 2026 22:07 UTC.
Upstream edited
Recorded here
Lines+29added
Lines−29removed
From line
20
where the diff opens
First seen
14 Aug 2026
this site's first read of the page
Recorded edits4to this page, all time
The whole hunk
from line 20, old and new numbered
/
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | ------------------------------------------------------------------------------- |
25| **SEP** | 2549 |
26| **Title** | TTL for List Results |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2026-04-09 |
30| **Author(s)** | Caitie McCaffrey ([@CaitieM20](https://github.com/CaitieM20)) |
31| **Sponsor** | [@CaitieM20](https://github.com/CaitieM20) |
32| **PR** | [#2549](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2549) |
23| Field | Value |
24| - | - |
25| **SEP** | 2549 |
26| **Title** | TTL for List Results |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2026-04-09 |
30| **Author(s)** | Caitie McCaffrey ([@CaitieM20](https://github.com/CaitieM20)) |
31| **Sponsor** | [@CaitieM20](https://github.com/CaitieM20) |
32| **PR** | [#2549](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2549) |
3333
3434***
3535
from line 41
4141
4242Today, MCP clients discover server features by invoking methods on the server. These calls return the current set of features. To learn about changes, clients rely on push notifications from the server. The below table maps the Server Method to Notification Type.
4343
44| Server Methods | Notification Type |
45| -------------------------- | -------------------------------------- |
46| `tools/list` | `notifications/tools/list_changed` |
47| `prompts/list` | `notifications/prompts/list_changed` |
48| `resources/list` | `notifications/resources/list_changed` |
44| Server Methods | Notification Type |
45| - | - |
46| `tools/list` | `notifications/tools/list_changed` |
47| `prompts/list` | `notifications/prompts/list_changed` |
48| `resources/list` | `notifications/resources/list_changed` |
4949| `resources/templates/list` | `notifications/resources/list_changed` |
50| `resources/read` | `notifications/resources/updated` |
50| `resources/read` | `notifications/resources/updated` |
5151
5252This approach has several limitations:
5353
from line 112
112112
113113`ttlMs` MUST be >= 0. If a server returns a negative value, clients SHOULD ignore it and treat it as 0 (immediately stale).
114114
115| Condition | Client behavior |
116| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
117| `ttlMs` = 0 | The response SHOULD be considered immediately stale, The Client MAY re-fetch every time the result is needed. |
118| `ttlMs` > 0 | Client SHOULD consider the response fresh for `ttlMs` milliseconds from receipt. |
119| Relevant notification received while TTL is active | The notification invalidates the cached response. Client SHOULD re-fetch regardless of remaining TTL. |
120| `cacheScope` = `"public"` | Any client or shared intermediary (gateway, proxy) MAY cache and serve the response to any user. |
121| `cacheScope` = `"private"` | Only the requesting user's client MAY cache. Shared caches MUST NOT serve a cached copy to a different user. |
115| Condition | Client behavior |
116| - | - |
117| `ttlMs` = 0 | The response SHOULD be considered immediately stale, The Client MAY re-fetch every time the result is needed. |
118| `ttlMs` > 0 | Client SHOULD consider the response fresh for `ttlMs` milliseconds from receipt. |
119| Relevant notification received while TTL is active | The notification invalidates the cached response. Client SHOULD re-fetch regardless of remaining TTL. |
120| `cacheScope` = `"public"` | Any client or shared intermediary (gateway, proxy) MAY cache and serve the response to any user. |
121| `cacheScope` = `"private"` | Only the requesting user's client MAY cache. Shared caches MUST NOT serve a cached copy to a different user. |
122122
123123#### Freshness calculation
124124
from line 199
199199
200200Many existing systems use integer seconds for TTLs, but some (e.g., gRPC retry pushback) use milliseconds. The key is to choose a single, consistent unit for all TTLs in MCP. Integer milliseconds provides the necessary precision while remaining simple to implement and understand.
201201
202| System | Mechanism | Notes |
203| ----------------------------- | --------------------- | ---------------------------------------------------------------- |
204| HTTP `Cache-Control: max-age` | Integer seconds | The most widely deployed freshness hint in web infrastructure |
205| DNS TTL | Integer seconds | Controls how long resolvers cache DNS records |
206| GraphQL `@cacheControl` | `maxAge` integer secs | Per-field cache hints in GraphQL responses |
207| gRPC `grpc-retry-pushback-ms` | Milliseconds | Server-provided retry hint (different use case, similar pattern) |
202| System | Mechanism | Notes |
203| - | - | - |
204| HTTP `Cache-Control: max-age` | Integer seconds | The most widely deployed freshness hint in web infrastructure |
205| DNS TTL | Integer seconds | Controls how long resolvers cache DNS records |
206| GraphQL `@cacheControl` | `maxAge` integer secs | Per-field cache hints in GraphQL responses |
207| gRPC `grpc-retry-pushback-ms` | Milliseconds | Server-provided retry hint (different use case, similar pattern) |
208208
209209### Why not use HTTP caching directly?
210210
No line in this hunk matches that.