MCPApp
TsgcHTMLComponent_MCPApp: metin yerine bir sayfayla yanıt veren bir MCP aracı; böylece herhangi bir web sayfasını işleyen aynı Delphi bileşenleri ChatGPT, Claude ve VS Code (MCP Apps) içinde de işlenir.
TsgcHTMLComponent_MCPApp: metin yerine bir sayfayla yanıt veren bir MCP aracı; böylece herhangi bir web sayfasını işleyen aynı Delphi bileşenleri ChatGPT, Claude ve VS Code (MCP Apps) içinde de işlenir.
Bir MCP App, sonucunu host'un yalnızca okumak yerine işlediği bir araçtır. Bileşen; aracı, sayfayı taşıyan kaynağı ve sayfanın kendisinin çağırdığı bir yardımcı aracı, zaten sahip olduğunuz MCP sunucusunda yayımlar ve sayfa, diğer tüm sayfalar gibi aynı sgcHTML bileşenleriyle oluşturulur. MCP sunucusu üzerinde çalıştığı için sgcWebSockets'in Enterprise veya All-Access sürümünü ya da sgcAI paketini gerektirir.
TsgcHTMLComponent_MCPApp, TsgcHTMLMCPApps koleksiyonu ve onun TsgcHTMLMCPApp öğeleriyle birlikte
Host'un sandbox içindeki bir çerçevede gösterdiği, varlıkları içine gömülü tek bir HTML belgesi
Delphi, C++ Builder, .NET
Bileşenin MCPServer özelliğine bir TsgcWSAPIServer_MCP atayın, bir araç adı ve bir açıklamayla bir uygulama ekleyin, OnRender, OnToolCall ve OnFragment olaylarını yanıtlayın, ardından RegisterApps çağırın.
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();
En sık başvurduğunuz üyeler.
Apps, TsgcHTMLMCPApps koleksiyonudur ve TsgcHTMLMCPApp öğelerini tutar. ToolName zorunludur: onsuz bir uygulama hiçbir şey kaydetmez. Description, modelin aracı çağırıp çağırmayacağına karar vermek için okuduğu metindir; InputSchema ise bağımsız değişkenlerinin JSON şemasıdır. Title, ResourceURI, PageBuilder, Enabled, PreferredWidth ve PreferredHeight bir uygulamayı tamamlar; son ikisi, host'tan çerçeveyi açması istenen boyuttur.
Sunucuda uygulama başına üç şey: adı ToolName ile verilen ve _meta.ui.resourceUri değeri host'a sayfayı hangi kaynağın taşıdığını söyleyen araç; sayfanın çağırdığı ve modelin hiçbir zaman çağırmadığı <ToolName>.fragment yardımcı aracı; ve ui://sgchtml/<toolname> kaynağı, text/html;profile=mcp-app olarak sunulur. Delphi'de RegisterApps, Loaded içinden çalışır ve bir uygulama ekleyen kod onu yeniden çağırır; .NET'te onu kendiniz çağırın. UnregisterApps bunları kaldırır.
Bir araç sonucunun iki okuyucusu vardır. OnToolCall içinde aText modelin okuduğu cümledir, aStructured ise sayfanın okuduğu JSON'dır. İkisi de isteğe bağlıdır ve metin boş olduğunda uygulamanın Title değeri kullanılır. İkisi farklı olduğunda ikisini de yanıtlayın, ki çoğu zaman farklıdırlar: model bir cümle ister, sayfa ise sayılar.
OnRender sayfayı sıradan sgcHTML işaretlemesi olarak yanıtlar. aHTML, uygulamanın PageBuilder bileşeni atanmışsa onun oluşturduğu sayfayı içerecek biçimde gelir; böylece bir işleyici onu değiştirebilir ya da olduğu gibi bırakabilir. GetAppHTML bir uygulamanın belgesinin tamamını döndürür; kaynağın yanıtladığı ve bir testin okuduğu da budur.
Sandbox içindeki bir çerçevenin bir hx-get isteğini yanıtlayacak HTTP sunucusu yoktur. Her belge window.sgcMCPApp taşır: sayfa hazır olduğunda ui/initialize gönderir, host'un yanıtladığı temayı uygular, host çerçeveyi boyutlandırabilsin diye sayfanın yüksekliğini bildirir ve her hx-get ve hx-post isteğini parça aracının bir tools/call çağrısına dönüştüren bir htmx uzantısı kaydeder. OnFragment bunu yanıtlar: aTarget öğenin istediği şeydir, aArguments formun ya da sorgunun JSON'ıdır, aHTML ise yerine konan işaretlemedir. HTTP üzerinden sunulan aynı işaretleme sıradan bir htmx isteğidir.
Çerçeve sandbox içindedir ve genellikle kendi ağı yoktur, bu yüzden hiçbir şey bağlanamaz. InlineAssets varsayılan olarak açıktır ve stil sayfasının, betiklerin ve sayfanın tek bir dosyada taşınmasını sağlar. Yalnızca varlıkları sunabilen, aynı makinedeki bir host için kapatın.
MCPServer, uygulamaların üzerinde bildirildiği TsgcAI_MCP_Server nesnesidir. TsgcWSAPIServer_MCP onu herkese açık bir özellik olarak sunar, bu yüzden FApps.MCPServer := FMCP.MCPServer uygulamaları bir web sunucusunun uç noktasına yerleştirir. Bileşen araç ve kaynak olaylarına abone olur ve orada bulunan işleyicileri zincirler, böylece zaten yayımladığınız araçlar çalışmaya devam eder. Bu olayları kendisi işleyen bir host ProcessToolsCall ve ProcessResourcesRead yöntemlerini çağırır; istek bir uygulamaya ait değilse bunlar False döndürür. .NET'te ona elinizdeki TsgcAI_MCP_Server nesnesini verin, örneğin TsgcAI_MCP_Server_Stdio tarafından sahiplenilen nesneyi.
Bileşen kendi başına hiçbir durum tutmaz. Bir araç çağrısının ne anlama geldiği, onu kimin çağırabileceği ve bir parça isteğinin ne döndürebileceği, bir web uygulamasındaki bir rotada olduğu gibi, uygulamanızın kararlarıdır. Modelin tetikleyebildiği şey, sizin kaydettiğiniz bir araçtır ve sizin oluşturduğunuz işaretlemeyle yanıt verir.
Demos\60.HTML\01.RunTime\19.MCPApp, 5725 numaralı bağlantı noktasında çalışan bir konsol sunucusudur; orders.board ve sales.summary adlı iki uygulamayı tek bir uç noktada yayımlar ve bir referans host ile gelir. http://localhost:5725/ adresini açın; sol panel gerçek bir host'un yaptığını yapar: aracı çağırır, kaynağı okur, sandbox içindeki bir çerçevede işler ve sayfanın çağrılarını iletir. Gerçek deneyim için Claude, ChatGPT veya VS Code'u http://localhost:5725/mcp adresine yönlendirin.
Birim, hem SGC_HTML hem de SGC_AI_MCP tanımlı olduğu yerde derlenir. SGC_AI_MCP, Enterprise ve All-Access sürümleriyle ve sgcAI paketiyle gelir. SGC_HTML, Android ve iOS dışındaki tüm platformlarda sgcWebSockets'ten bağımsız olarak satılan sgcHTML ile gelir.
| Çevrimiçi yardımMCP Apps için kullanım kılavuzu: araç, kaynak, parça aracı ve köprü. | Aç | |
| Tüm sgcHTML Bileşenleri80'den fazla bileşenin tam özellik matrisine göz atın. | Aç | |
| Ücretsiz Deneme Sürümünü İndirin30 günlük deneme, 60.HTML demo projeleriyle birlikte gelir. | Aç | |
| FiyatlandırmaTam kaynak kodlu Single, Team ve Site lisansları. | Aç |