What it does
The `notifications/resources/list_changed` notification is emitted by the server and delivered to the connected client whenever the server's set of available resources changes in a meaningful way. Triggers include resources being added, removed, or having their URIs or metadata altered — for example, a filesystem-backed server detecting a new file, a database server gaining or losing a table, or a dynamic resource registry being updated at runtime. The notification carries no payload beyond the method name itself; it is a pure signal, not a diff. Upon receiving this notification, the client is expected to re-issue a `resources/list` request to fetch the updated catalogue. The client must not assume any particular change was made; the notification is intentionally coarse-grained, so the client always fetches the full list to reconcile its local state. Any previously cached resource URIs or metadata should be considered stale until the new list is retrieved and processed. Before a server may send this notification, it must have declared the `resources.listChanged` capability during the `initialize` handshake. Clients that did not advertise support for this notification in their own capabilities may safely ignore it, but well-behaved clients should subscribe and refresh. Because the notification is fire-and-forget with no acknowledgment, servers should emit it promptly after the state change to minimize the window during which the client operates on a stale resource list.
When to use
When the resource list grows or shrinks.
When NOT to use
For content changes within a single resource — use notifications/resources/updated.
Notes
Capability gating is mandatory
A server MUST declare `resources.listChanged: true` inside the `capabilities.resources` object during the `initialize` response before it is permitted to emit this notification. Sending the notification without this declaration is a protocol violation. Clients that see the notification from a server that did not advertise the capability should treat it as an unexpected message and may log a warning rather than acting on it.
Race conditions between notification and list response
Because `notifications/resources/list_changed` carries no diff payload, a second state change can occur between the moment the client receives the notification and the moment the `resources/list` response arrives. Clients must treat the list response as the authoritative snapshot at response time, not at notification time, and should be prepared for the list to differ from whatever change they anticipated. Coalescing multiple rapid notifications into a single re-fetch is a valid and recommended client optimization.
Ordering is not guaranteed across transports
On stdio transports, message ordering is strictly sequential and the notification will always precede any subsequent list response. On SSE or WebSocket transports, in-flight responses to unrelated requests may arrive interleaved with the notification. Clients should not rely on the notification arriving before a concurrent `resources/list` response; instead, they should track a generation counter or timestamp to discard stale responses.
SDK handling varies by language
The official TypeScript MCP SDK automatically registers an event emitter for `notifications/resources/list_changed` and re-fetches the resource list when a handler is attached via `client.onResourceListChanged(...)`. The Python SDK exposes a lower-level callback that the application must wire manually. In both cases, if the capability was not negotiated, the SDK suppresses the notification silently rather than surfacing an error, so missing capability declarations can go unnoticed without explicit logging.
Examples
Resources changed
{ "method": "notifications/resources/list_changed" }