MCP Client | Multi Round-Trip Requests

In the MCP protocol version 2026-07-28 a server cannot send requests to the client (roots, sampling or elicitation) in the middle of a tool call, because there is no session. The server answers tools/call, prompts/get or resources/read with resultType input_required and a list of inputRequests. The client collects the answers and repeats the same request with a new id, the answers in inputResponses and the exact requestState received from the server. This is a Multi Round-Trip Request (MRTR). TsgcWSAPIClient_MCP runs the whole loop for you inside RequestTool, RequestPrompt and RequestResource.

 

How the inputs are answered

 

When the loop stops without an answer, the caller receives the input_required response (its ResultType is aimcprtInputRequired) and no error is raised. If the server asks for input more than MCPOptions.MRTR.MaxRounds times, the loop stops and the error is reported through OnError.

MCPOptions.MRTR

PropertyDescription
MaxRoundsMaximum number of rounds for one request. Default 10.
ElicitationDeclares the elicitation client capability. Default False.
SamplingDeclares the sampling client capability. Default False.
RootsDeclares the roots client capability. Default False.

 

The client declares a capability in _meta.clientCapabilities (and in the legacy initialize) when the matching handler (OnMCPElicitationCreate, OnMCPSamplingCreateMessage or OnMCPListRoots) is assigned or the MRTR option is True. Enable the options when you answer the inputs only from OnMCPInputRequired, because a server does not ask for inputs the client did not declare.

TsgcAI_MCP_Client_InputRequests

MemberDescription
CountNumber of inputs requested by the server.
Keys[i]Key of the input, used to match the answer.
Methods[i]Method of the input, for example elicitation/create.
Params[i]Params of the input as raw JSON.
Responses[i]Answer already assigned (raw JSON), empty when there is none.
SetResponse(aKey, aResultJSON)Sets the answer of an input as a raw JSON result.
SetElicitationAccept(aKey, aContentJSON)Answers an elicitation with action accept and the form content (JSON object).
SetElicitationDecline(aKey)Answers an elicitation with action decline.
SetRoots(aKey, aRootsJSON)Answers a roots request with a JSON array of roots.
IndexOfKey(aKey)Returns the index of a key or -1.
IsCompletedTrue when every input has an answer.

 

The server side of this feature is described in MCP Server | Multi Round-Trip Requests.

Sample code

Answer an elicitation that asks for the user name and publish one root. Declare both capabilities because no legacy handler is assigned.

procedure TForm1.FormCreate(Sender: TObject);
begin
  MCP.MCPOptions.MRTR.Elicitation := True;
  MCP.MCPOptions.MRTR.Roots := True;
  MCP.MCPOptions.MRTR.MaxRounds := 5;
  MCP.OnMCPInputRequired := MCPInputRequired;
end;

procedure TForm1.MCPInputRequired(Sender: TObject; const aMethod: string;
  const aInputRequests: TsgcAI_MCP_Client_InputRequests; var Accept: Boolean);
var
  i: Integer;
begin
  for i := 0 to aInputRequests.Count - 1 do
  begin
    if aInputRequests.Responses[i] <> '' then
      Continue;
    if aInputRequests.Methods[i] = 'elicitation/create' then
      aInputRequests.SetElicitationAccept(aInputRequests.Keys[i],
        '{"name":"John"}')
    else if aInputRequests.Methods[i] = 'roots/list' then
      aInputRequests.SetRoots(aInputRequests.Keys[i],
        '[{"uri":"file:///c:/projects/app","name":"App"}]');
  end;
  Accept := aInputRequests.IsCompleted;
end;