MCP Client | Subscriptions

In the MCP protocol version 2026-07-28 there is no session stream, so a client that wants to receive notifications opens a subscription with subscriptions/listen. The server keeps the response open and sends the notifications the client asked for: tools, prompts or resources list changes and updates of specific resources. For servers of the legacy era keep using SubscribeResource; the subscription methods below raise an exception in the legacy era.

 

Opening a subscription

Call SubscriptionsListen with the notifications you want and, optionally, the list of resource URIs to watch. The method returns the subscription id.

 

Events

 

Closing a subscription

Call SubscriptionsCancel with the subscription id. With HTTP the stream is closed; with stdio the client sends notifications/cancelled. All subscriptions are cancelled automatically when Initialize is called again and when the component is destroyed.

Threads

With the HTTP transports the subscription events are raised in the background thread of the subscription, not in the main thread. Do not access visual controls directly from the handler, use TThread.Queue or TThread.Synchronize. With the stdio transport the events are synchronized with the main thread.

The server side is described in MCP Server | Subscriptions.

Sample code

procedure TForm1.Subscribe;
var
  oURIs: TStringList;
begin
  MCP.OnMCPSubscriptionAcknowledged := MCPSubscriptionAcknowledged;
  MCP.OnMCPListChanged := MCPListChanged;
  MCP.OnMCPResourcesUpdated := MCPResourcesUpdated;
  MCP.OnMCPSubscriptionClosed := MCPSubscriptionClosed;
  oURIs := TStringList.Create;
  try
    oURIs.Add('file:///logs/app.log');
    FSubscriptionId := MCP.SubscriptionsListen(True, False, True, oURIs);
  finally
    oURIs.Free;
  end;
end;

procedure TForm1.MCPListChanged(Sender: TObject;
  aKind: TsgcAI_MCP_Client_ListChangedKind; const aNotification: string);
begin
  if aKind = aimcplckTools then
    TThread.Queue(nil,
      procedure
      begin
        MCP.ListTools;
      end);
end;

procedure TForm1.MCPResourcesUpdated(Sender: TObject;
  const aNotification: TsgcAI_MCP_Notification_Resources_Updated);
begin
  Log('updated: ' + aNotification.Uri);
end;

procedure TForm1.MCPSubscriptionAcknowledged(Sender: TObject;
  const aSubscriptionId, aNotifications: string);
begin
  Log('listening ' + aSubscriptionId + ': ' + aNotifications);
end;

procedure TForm1.MCPSubscriptionClosed(Sender: TObject;
  const aSubscriptionId: string; aGraceful: Boolean);
begin
  Log('closed ' + aSubscriptionId);
end;

procedure TForm1.Unsubscribe;
begin
  MCP.SubscriptionsCancel(FSubscriptionId);
end;