Roots mark the filesystem locations a client allows the server to explore. Each entry is a file:// URI with an optional display name, letting MCP automations honour project boundaries while the user keeps control of what is shared. Servers query the catalogue by issuing roots/list and, when the client announces listChanged, receive notifications/roots/list_changed so they can refresh cached views.
Because roots are client-owned, the server always acts as the requester. The roots capability must be present in the client’s initialise payload before you attempt a discovery call; otherwise RequestRootsList raises CapabilityNotSupported.
TsgcWSAPIServer_MCP exposes a helper that serialises roots/list and routes the reply back to your code:
The reply of the client is matched with the pending request and raises OnMCPResponseRootsList. Over HTTP the client posts the reply to the MCP endpoint and the server answers 204 without body. A client that has no handler for the request answers with the JSON-RPC error -32601 (Method not found). An error reply also resolves the pending request: the server answers 204 and raises the same OnMCPResponseRootsList event with aResponse.IsError set to True. Read ErrorCode, ErrorMessage and ErrorData of the response to know why the request failed, and check IsError before reading the result.
procedure TFRMMCPServer.MCPServerRootsList(Sender: TObject;
const aSession: TsgcAI_MCP_Session;
const aRequest: TsgcAI_MCP_Request_RootsList;
const aResponse: TsgcAI_MCP_Response_RootsList);
begin
if aResponse.IsError then
begin
MemoLog.Lines.Add(Format('roots/list failed: %d %s',
[aResponse.ErrorCode, aResponse.ErrorMessage]));
exit;
end;
// ... read the result
end;
This request only exists in the legacy era (2025-11-25 and older). Clients of the protocol version 2026-07-28 have no session, so ask them for the same input from the tool, prompt or resource handler with aResponse.InputRequired.AddRoots. See Multi Round-Trip Requests.
The snippets below request roots as soon as a session is established and log the returned entries.
procedure TFRMMCPServer.FormCreate(Sender: TObject);
begin
MCPServer.OnMCPSessionNew := MCPServerSessionNew;
MCPServer.OnMCPResponseRootsList := MCPServerRootsList;
end;
procedure TFRMMCPServer.MCPServerSessionNew(Sender: TObject;
const aSession: TsgcAI_MCP_Session);
begin
if aSession.ClientCapabilities.Roots.Enabled then
MemoLog.Lines.Add('roots/list sent id ' +
MCPServer.RequestRootsList(aSession));
end;
procedure TFRMMCPServer.MCPServerRootsList(Sender: TObject;
const aSession: TsgcAI_MCP_Session;
const aRequest: TsgcAI_MCP_Request_RootsList;
const aResponse: TsgcAI_MCP_Response_RootsList);
begin
MemoLog.Lines.Add(Format('roots/list returned %d entries',
[aResponse.Roots.Count]));
MemoLog.Lines.Add('roots/list payload ' + aResponse.Write);
end;