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.
Call SubscriptionsListen with the notifications you want and, optionally, the list of resource URIs to watch. The method returns the subscription id.
Accept: application/json, text/event-stream.
list_changed notification arrived. aKind is aimcplckTools, aimcplckPrompts or aimcplckResources; call ListTools, ListPrompts or ListResources to refresh the catalogue.notifications/resources/updated); read aNotification.Uri and call RequestResource. This event is published, assign it in the Object Inspector or in code. See OnMCPResourcesUpdated.
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.
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.
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;