What it does
The `notifications/roots/list_changed` notification is sent by the client to the server whenever the set of roots the client exposes changes at runtime. Concrete triggers include: the user adding or removing workspace folders in an IDE, mounting or unmounting a filesystem root, or the host application explicitly altering the root set in response to a project-level event. The notification carries no payload — it is a pure signal, not a diff — so the server learns only that something changed, not what.\n\nUpon receiving this notification, the server MUST re-issue a `roots/list` request to fetch the current, authoritative root set. Servers should treat any cached root information as immediately stale. The server is responsible for reconciling the new list against whatever in-flight operations it may have, such as resource subscriptions that reference a root that no longer exists.\n\nBoth sides must declare capability before this flow is valid. The client must advertise `roots.listChanged: true` in its `initialize` capabilities; if it does not, the server MUST NOT rely on receiving this notification and should either poll or treat the initial root list as static. No ordering guarantee is made between this notification and subsequent resource change notifications that may be caused by the same root set change.
When to use
When the user opens or closes a workspace.
When NOT to use
Spuriously — servers may rescan on every event.
Notes
Capability gating is mandatory
A client that does not include `roots.listChanged: true` in its `initialize` capabilities is not permitted to send this notification. Servers that receive it unexpectedly should log and discard it rather than acting on it, since capability negotiation is the contract boundary for the entire roots change flow.
Notification carries no diff payload
The notification body is empty — it contains no added, removed, or modified root information. The server must follow up with an explicit `roots/list` call to discover the new state. This pull-on-push pattern means transient network issues between the notification and the follow-up request can leave the server with a stale view until it retries.
Race conditions with in-flight operations
If a server has an active resource read or subscription against a root that disappears in the same change batch, it may receive the read error before or after the notification, depending on timing. Servers should defensively treat any `ResourceNotFound` error as a cue to re-check the root list, not just await the notification.
SDK differences in automatic re-listing
The TypeScript MCP SDK automatically triggers a `roots/list` call when this notification arrives if you use the high-level server wrapper, whereas the Python SDK leaves the re-fetch to application code. Check your SDK version's changelog; automatic re-listing was added in later minor releases and may not be present in older pinned dependencies.
Examples
Roots changed
{ "method": "notifications/roots/list_changed" }