MCPApp

TsgcHTMLComponent_MCPApp: ein MCP-Tool, das statt mit Text mit einer Seite antwortet, sodass dieselben Delphi-Komponenten, die jede beliebige Webseite erzeugen, auch in ChatGPT, Claude und VS Code (MCP Apps) dargestellt werden.

TsgcHTMLComponent_MCPApp

Eine MCP App ist ein Tool, dessen Ergebnis der Host darstellt, statt es nur zu lesen. Die Komponente veröffentlicht das Tool, die Ressource, die die Seite trägt, und ein Begleit-Tool, das die Seite selbst aufruft, auf dem MCP-Server, den Sie bereits haben, und die Seite wird aus denselben sgcHTML-Komponenten aufgebaut wie jede andere. Erfordert die Enterprise- oder All-Access-Edition von sgcWebSockets oder das sgcAI-Paket, weil sie auf dem MCP-Server läuft.

Komponentenklasse

TsgcHTMLComponent_MCPApp, mit der Sammlung TsgcHTMLMCPApps aus TsgcHTMLMCPApp-Elementen

Rendert

Ein HTML-Dokument, das der Host in einem Sandbox-Frame anzeigt, mit inline eingebetteten Assets

Familie

Chat & KI

Sprachen

Delphi, C++ Builder, .NET

Eine App deklarieren, drei Ereignisse beantworten

Weisen Sie der Komponente den MCPServer eines TsgcWSAPIServer_MCP zu, fügen Sie eine App mit einem Tool-Namen und einer Beschreibung hinzu, behandeln Sie OnRender, OnToolCall und OnFragment und rufen Sie dann RegisterApps auf.

uses
  Classes, SysUtils, StrUtils,
  // sgc
  sgcWebSocket_Server, sgcAI, sgcHTML_Nodes, sgcHTML_Nodes_Bootstrap,
  sgcHTML_MCPApp;

// The MCP endpoint a host connects to
FMCP := TsgcWSAPIServer_MCP.Create(nil);
FMCP.Server := FHTTPServer;
FMCP.EndpointOptions.Endpoint := '/mcp';

// The apps, declared on the MCP server the endpoint owns
FApps := TsgcHTMLComponent_MCPApp.Create(nil);
FApps.MCPServer := FMCP.MCPServer;
FApps.OnRender := DoRender;
FApps.OnToolCall := DoToolCall;
FApps.OnFragment := DoFragment;

with FApps.Apps.Add do
begin
  ToolName := 'orders.board';
  Title := 'Orders board';
  Description := 'Shows the orders of the company as a board that ' +
    'can be filtered by status.';
  InputSchema.Text := '{"type":"object","properties":{"status":' +
    '{"type":"string","description":"open, shipped or closed"}}}';
  PreferredWidth := 720;
  PreferredHeight := 460;
end;
FApps.RegisterApps;   // the tool, the fragment tool and the resource

// What the model reads, and what the page reads
procedure TMyLogic.DoToolCall(Sender: TObject; aApp: TsgcHTMLMCPApp;
  const aArguments: string; var aText, aStructured: string);
begin
  aText := '3 open orders, 1420.50 in total.';
  aStructured := '{"orders":3,"total":1420.5}';
end;

// The page: ordinary sgcHTML components
procedure TMyLogic.DoRender(Sender: TObject; aApp: TsgcHTMLMCPApp;
  const aArguments: string; var aHTML: string);
var
  oCard: TsgcHTMLCard;
  oButton: TsgcHTMLContainer;
begin
  oCard := TsgcHTMLCard.Create;
  try
    oCard.Body.Add(TsgcHTMLHeading.Create('Orders', 5));

    oButton := TsgcHTMLContainer.Create('button');
    oButton.CSSClass := 'btn btn-outline-secondary';
    // inside a host, the bridge turns this hx-get into a call of the fragment tool
    oButton.Attributes := 'type="button" hx-get="orders?status=open" ' +
      'hx-target="#orders" hx-swap="outerHTML"';
    oButton.AddText('Open');
    oCard.Body.Add(oButton);

    oCard.Body.AddRaw(BuildOrdersTable(''));   // your markup: the element whose id is orders
    aHTML := oCard.HTML;
  finally
    oCard.Free;
  end;
end;

// The markup a control of the page asked for
procedure TMyLogic.DoFragment(Sender: TObject; aApp: TsgcHTMLMCPApp;
  const aTarget, aArguments: string; var aHTML: string);
begin
  // aTarget is what the element asked for, for instance orders?status=open
  if StartsText('orders', aTarget) then
    aHTML := BuildOrdersTable(StatusOf(aTarget));
end;
// includes: sgcAI.hpp, sgcHTML_MCPApp.hpp

// The MCP endpoint a host connects to
FMCP = new TsgcWSAPIServer_MCP(NULL);
FMCP->Server = FHTTP;
FMCP->EndpointOptions->Endpoint = "/mcp";

// The apps, declared on the MCP server the endpoint owns
FApps = new TsgcHTMLComponent_MCPApp(NULL);
FApps->MCPServer = FMCP->MCPServer;
FApps->OnRender = DoRender;
FApps->OnToolCall = DoToolCall;
FApps->OnFragment = DoFragment;

TsgcHTMLMCPApp *app = FApps->Apps->Add();
app->ToolName = "orders.board";
app->Title = "Orders board";
app->Description = "Shows the orders of the company as a board that can be filtered by status.";
app->InputSchema->Text = "{\"type\":\"object\",\"properties\":{\"status\":{\"type\":\"string\"}}}";
app->PreferredWidth = 720;
app->PreferredHeight = 460;
FApps->RegisterApps();   // the tool, the fragment tool and the resource

// What the model reads, and what the page reads
void __fastcall TMyLogic::DoToolCall(TObject *Sender, TsgcHTMLMCPApp *aApp,
  const String aArguments, String &aText, String &aStructured)
{
  aText = "3 open orders, 1420.50 in total.";
  aStructured = "{\"orders\":3,\"total\":1420.5}";
}

// The markup a control of the page asked for
void __fastcall TMyLogic::DoFragment(TObject *Sender, TsgcHTMLMCPApp *aApp,
  const String aTarget, const String aArguments, String &aHTML)
{
  // aTarget is what the element asked for, for instance orders?status=open
  if (aTarget.Pos("orders") == 1)
    aHTML = BuildOrdersTable(StatusOf(aTarget));
}

// DoRender answers the page with sgcHTML components, as in the Delphi tab.
using esegece.sgcWebSockets;

// An MCP server over stdio, for a host that starts your program as a process
var host = new TsgcAI_MCP_Server_Stdio();

var apps = new TsgcHTMLComponent_MCPApp();
apps.MCPServer = host.MCPServer;

var app = apps.Apps.Add();
app.ToolName = "orders.board";
app.Title = "Orders board";
app.Description = "Shows the orders of the company as a board that can be filtered by status.";
app.InputSchema.Add("{\"type\":\"object\",\"properties\":{\"status\":{\"type\":\"string\"}}}");
app.PreferredWidth = 720;
app.PreferredHeight = 460;

// What the model reads, and what the page reads
apps.OnToolCall += (object sender, TsgcHTMLMCPApp a, string args,
    ref string text, ref string structured) =>
{
    text = "3 open orders, 1420.50 in total.";
    structured = "{\"orders\":3,\"total\":1420.5}";
};

// The page: ordinary sgcHTML components
apps.OnRender += (object sender, TsgcHTMLMCPApp a, string args, ref string html) =>
{
    var card = new TsgcHTMLCard();
    card.Body.Add(new TsgcHTMLHeading("Orders", 5));

    var button = new TsgcHTMLContainer("button");
    button.CSSClass = "btn btn-outline-secondary";
    // inside a host, the bridge turns this hx-get into a call of the fragment tool
    button.Attributes = "type=\"button\" hx-get=\"orders?status=open\" "
        + "hx-target=\"#orders\" hx-swap=\"outerHTML\"";
    button.AddText("Open");
    card.Body.Add(button);

    card.Body.AddRaw(BuildOrdersTable(""));   // your markup: the element whose id is orders
    html = card.HTML;
};

// The markup a control of the page asked for
apps.OnFragment += (object sender, TsgcHTMLMCPApp a, string target,
    string args, ref string html) =>
{
    // target is what the element asked for, for instance orders?status=open
    if (target.StartsWith("orders"))
        html = BuildOrdersTable(StatusOf(target));
};

apps.RegisterApps();   // the tool, the fragment tool and the resource
host.Run();

Wichtige Eigenschaften & Methoden

Die Member, die Sie am häufigsten verwenden.

Apps

Apps ist eine Sammlung TsgcHTMLMCPApps aus TsgcHTMLMCPApp-Elementen. ToolName ist erforderlich: Eine App ohne Tool-Namen registriert nichts. Description ist das, was das Modell liest, um zu entscheiden, ob es das Tool aufruft, und InputSchema ist das JSON-Schema seiner Argumente. Title, ResourceURI, PageBuilder, Enabled, PreferredWidth und PreferredHeight vervollständigen eine App, wobei die beiden letzten die Größe sind, in der der Host gebeten wird, den Frame zu öffnen.

Was RegisterApps deklariert

Drei Dinge pro App auf dem Server: das Tool, benannt durch ToolName, dessen _meta.ui.resourceUri dem Host mitteilt, welche Ressource die Seite trägt; das Begleit-Tool <ToolName>.fragment, das die Seite aufruft, das Modell aber nie; und die Ressource ui://sgchtml/<toolname>, ausgeliefert als text/html;profile=mcp-app. In Delphi läuft RegisterApps aus Loaded heraus, und Code, der eine App hinzufügt, ruft die Methode erneut auf; in .NET rufen Sie sie selbst auf. UnregisterApps entfernt sie.

Zwei Hälften eines Ergebnisses

Ein Tool-Ergebnis hat zwei Adressaten. In OnToolCall ist aText der Satz, den das Modell liest, und aStructured das JSON, das die Seite liest. Beide sind optional, und wenn der Text leer ist, wird der Title der App verwendet. Beantworten Sie beide, wenn sie sich unterscheiden, was meistens der Fall ist: Das Modell will einen Satz, die Seite will Zahlen.

Die Seite

OnRender liefert die Seite als gewöhnliches sgcHTML-Markup. aHTML kommt mit der Seite an, die der PageBuilder der App erzeugt, sofern einer zugewiesen ist, sodass ein Handler sie ersetzen oder unverändert lassen kann. GetAppHTML liefert das gesamte Dokument einer App, also das, was die Ressource beantwortet und was ein Test liest.

Fragmente und die Bridge

Ein Sandbox-Frame hat keinen HTTP-Server, der einen hx-get beantworten könnte. Jedes Dokument enthält window.sgcMCPApp: Es sendet ui/initialize, sobald die Seite bereit ist, wendet das Theme an, mit dem der Host antwortet, meldet die Höhe der Seite, damit der Host die Größe des Frames anpassen kann, und registriert eine htmx-Erweiterung, die jeden hx-get und hx-post in einen tools/call des Fragment-Tools umwandelt. OnFragment beantwortet diesen Aufruf: aTarget ist das, was das Element angefordert hat, aArguments das JSON des Formulars oder der Abfrage und aHTML das eingesetzte Markup. Dasselbe über HTTP ausgelieferte Markup ist eine gewöhnliche htmx-Anfrage.

Ein Dokument

Der Frame läuft in einer Sandbox und hat in der Regel kein eigenes Netzwerk, daher kann nichts verlinkt werden. InlineAssets ist standardmäßig aktiv und sorgt dafür, dass Stylesheet, Skripte und Seite in einer einzigen Datei transportiert werden. Schalten Sie es nur für einen Host auf demselben Rechner aus, der die Assets ausliefern kann.

Der MCP-Server

MCPServer ist der TsgcAI_MCP_Server, auf dem die Apps deklariert werden. TsgcWSAPIServer_MCP stellt ihn als öffentliche Eigenschaft bereit, sodass FApps.MCPServer := FMCP.MCPServer die Apps auf den Endpunkt eines Webservers legt. Die Komponente abonniert die Tool- und Ressourcen-Ereignisse und verkettet die bereits vorhandenen Handler, sodass die Tools, die Sie schon veröffentlichen, weiter funktionieren. Ein Host, der diese Ereignisse selbst behandelt, ruft ProcessToolsCall und ProcessResourcesRead auf, die False zurückgeben, wenn die Anfrage nicht zu einer App gehörte. In .NET übergeben Sie ihr den vorhandenen TsgcAI_MCP_Server, zum Beispiel den, der zu TsgcAI_MCP_Server_Stdio gehört.

Kein Zustand

Die Komponente hält keinen eigenen Zustand. Was ein Tool-Aufruf bedeutet, wer ihn ausführen darf und was eine Fragment-Anfrage zurückgeben darf, sind Entscheidungen Ihrer Anwendung, genau wie bei einer Route in einer Webanwendung. Was das Modell auslösen kann, ist ein Tool, das Sie registriert haben und das mit Markup antwortet, das Sie erzeugt haben.

Ohne Assistenten ansehen

Demos\60.HTML\01.RunTime\19.MCPApp ist ein Konsolenserver auf Port 5725, der zwei Apps, orders.board und sales.summary, an einem Endpunkt veröffentlicht und einen Referenz-Host mitliefert. Öffnen Sie http://localhost:5725/, und das linke Panel tut, was ein echter Host tut: Es ruft das Tool auf, liest die Ressource, stellt sie in einem Sandbox-Frame dar und leitet die Aufrufe der Seite weiter. Für den echten Einsatz richten Sie Claude, ChatGPT oder VS Code auf http://localhost:5725/mcp aus.

Verfügbarkeit

Die Unit kompiliert überall dort, wo sowohl SGC_HTML als auch SGC_AI_MCP definiert sind. SGC_AI_MCP gehört zu den Editionen Enterprise und All-Access sowie zum sgcAI-Paket. SGC_HTML gehört zu sgcHTML, das unabhängig von sgcWebSockets verkauft wird, auf jeder Plattform außer Android und iOS.

Weiter entdecken

Online-HilfeAnleitung zu MCP Apps: das Tool, die Ressource, das Fragment-Tool und die Bridge.
Alle sgcHTML-KomponentenDurchsuchen Sie die vollständige Funktionsmatrix von über 80 Komponenten.
Kostenlose Testversion herunterladenDie 30-Tage-Testversion enthält die 60.HTML-Demoprojekte.
PreiseSingle-, Team- und Site-Lizenzen mit vollständigem Quellcode.
Bestes Preis-Leistungs-Verhältnis: All-AccessAlle eSeGeCe-Produkte, inklusive Premium-Support, ab €1,059 pro Jahr.
All-Access-Preise ansehen

Bereit loszulegen?

Laden Sie die kostenlose Testversion herunter und beginnen Sie, Web-UIs in Delphi, C++ Builder und .NET zu erstellen.