--- title: Roots author: jeffhandley description: How to provide filesystem roots from clients to MCP servers. uid: roots --- ## Roots MCP [roots] allow clients to inform servers about the relevant locations in the filesystem or other hierarchical data sources. Roots are a client-provided feature—the client declares its root URIs during initialization, and the server can request them to understand the working context. [roots]: https://modelcontextprotocol.io/specification/2025-11-25/client/roots > [!IMPORTANT] > Roots are **deprecated** as of MCP specification revision `2026-07-28` ([SEP-2577](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577), [MCP9005](xref:list-of-diagnostics#obsolete-apis)) and may be removed in a future version. ### Overview Roots provide a mechanism for the client to tell the server which directories, projects, or repositories are relevant to the current session. A server might use roots to: - Scope file searches to the user's project directories - Understand which repositories are being worked on - Focus operations on relevant filesystem locations Each root is represented by a with a URI and an optional human-readable name. ### Declaring roots capability on the client Clients advertise their support for roots in the capabilities sent during initialization. The roots capability is created automatically when a roots handler is provided. Configure the handler through : ```csharp var options = new McpClientOptions { Handlers = new McpClientHandlers { RootsHandler = (request, cancellationToken) => { return ValueTask.FromResult(new ListRootsResult { Roots = [ new Root { Uri = "file:///home/user/projects/my-app", Name = "My Application" }, new Root { Uri = "file:///home/user/projects/shared-lib", Name = "Shared Library" } ] }); } } }; await using var client = await McpClient.CreateAsync(transport, options); ``` ### Requesting roots from the server Servers can request the client's root list using . This is a server-to-client request, so it requires [stateful mode or stdio](xref:stateless) — it is not available in [stateless mode](xref:stateless#stateless-mode-recommended). For a stateless-compatible alternative, throw `InputRequiredException` from your handler through MRTR — see [Multi round-trip requests (MRTR)](#multi-round-trip-requests-mrtr). ```csharp [McpServerTool, Description("Lists the user's project roots")] public static async Task ListProjectRoots(McpServer server, CancellationToken cancellationToken) { var result = await server.RequestRootsAsync(new ListRootsRequestParams(), cancellationToken); var summary = new StringBuilder(); foreach (var root in result.Roots) { summary.AppendLine($"- {root.Name ?? root.Uri}: {root.Uri}"); } return summary.ToString(); } ``` ### Roots change notifications When the set of roots changes (for example, the user opens a new project), the client notifies the server so it can update its understanding of the working context. #### Sending change notifications from the client Roots change notifications are automatically sent when the client's roots handler is updated. However, clients can also send the notification explicitly: ```csharp await mcpClient.SendNotificationAsync( NotificationMethods.RootsListChangedNotification, new RootsListChangedNotificationParams()); ``` #### Handling change notifications on the server Servers can register a handler to respond when the client's roots change: ```csharp server.RegisterNotificationHandler( NotificationMethods.RootsListChangedNotification, async (notification, cancellationToken) => { // Re-request the roots list to get the updated set var result = await server.RequestRootsAsync(new ListRootsRequestParams(), cancellationToken); Console.WriteLine($"Roots updated. {result.Roots.Count} roots available."); }); ``` ### Multi round-trip requests (MRTR) [MRTR](xref:mrtr) is the SEP-2322 mechanism for server-driven input requests, finalized in protocol revision `2026-07-28`. In that revision, the server-to-client `roots/list` request method is removed; the recommended way to ask the client for its roots from a server handler is to throw and let the SDK emit an on the wire. > [!IMPORTANT] > `RequestRootsAsync` throws `InvalidOperationException("Roots are not supported in stateless mode.")` whenever the server is running stateless — including every Streamable HTTP request served under `2026-07-28`. Stdio servers and initialize-handshake stateful Streamable HTTP sessions continue to work via the initialize-era server-to-client `roots/list` request flow; an HTTP server set to `SessionMode = HttpServerSessionMode.Stateful` refuses `2026-07-28` so dual-path clients can fall back before using that flow, while `HttpServerSessionMode.StatefulForInitializeClients` instead serves `2026-07-28` statelessly on the same endpoint (see [hybrid mode](xref:stateless#hybrid-mode-sessions-for-initialize-clients-only)), so those requests use MRTR while `initialize`-handshake sessions keep this flow. For code that needs to run on stateless servers — including `2026-07-28` Streamable HTTP — throw `InputRequiredException` from your handler instead. It works across both protocol eras and all three HTTP `SessionMode` configurations. For example: ```csharp [McpServerTool, Description("Tool that requests roots via MRTR")] public static string ListRootsWithMrtr( McpServer server, RequestContext context) { // On retry, process the client's roots response if (context.Params!.InputResponses?.TryGetValue("get_roots", out var response) is true) { var roots = response.Deserialize(InputResponse.ListRootsResultJsonTypeInfo)?.Roots ?? []; return $"Found {roots.Count} roots: {string.Join(", ", roots.Select(r => r.Uri))}"; } if (!server.IsMrtrSupported) { return "This tool requires MRTR support (2026-07-28, or a stateful session using protocol revision 2025-11-25)."; } // First call — request the client's root list throw new InputRequiredException( inputRequests: new Dictionary { ["get_roots"] = InputRequest.ForRootsList(new ListRootsRequestParams()) }, requestState: "awaiting-roots"); } ``` > [!TIP] > For the full protocol details, including load shedding, multiple round trips, and the compatibility matrix, see [Multi Round-Trip Requests (MRTR)](xref:mrtr).