M C P 服务器可以让助手调用你的代码。但它从来都不能让你展示任何东西:助手提问,你的工具用文字回答,用户读到的是一段文字。sgcWebSockets 2026.10 为 sgcHTML 添加了MCP Apps,这样工具就可以改用一个页面来回答。助手渲染这个页面,用户在页面里点击,点击会返回到你的 Delphi 应用。
这个页面由与其他任何页面相同的 sgcHTML 组件构建而成。没有 JavaScript 框架,没有独立的前端,没有第二套代码库。
一个用页面回答的工具
一个 MCP App 由三部分组成:一个模型可以调用的工具、一个承载页面的资源,以及决定这两者含义的事件。TsgcHTMLComponent_MCPApp 在你已有的 MCP 服务器上声明了这一切。
uses
sgcAI, sgcHTML_MCPApp;
FMCP := TsgcWSAPIServer_MCP.Create(nil);
FMCP.Server := FHTTPServer;
FMCP.EndpointOptions.Endpoint := '/mcp';
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"}}}';
end;
FApps.RegisterApps;
这就是全部的注册工作。该组件用元数据声明工具,告诉宿主它带有用户界面;声明宿主用来读取页面的资源;并声明页面自身使用的配套工具。
模型读到什么,用户看到什么
一个工具结果分为两部分,而它们面向的不是同一个受众。OnToolCall 同时写入两者:一句供模型推理的话,以及页面所读取的结构化内容。
procedure TMyLogic.DoToolCall(Sender: TObject; aApp: TsgcHTMLMCPApp;
const aArguments: string; var aText, aStructured: string);
begin
aText := Format('%d open orders, %s in total.', [vCount, vTotal]);
aStructured := '{"orders":' + IntToStr(vCount) + '}';
end;
OnRender 负责回答页面本身。这就是普通的 sgcHTML:一张卡片、一个表格、几个按钮。其中没有任何针对助手的特殊内容。
在没有服务器的地方也能工作的按钮
这通常是最容易出问题的部分。页面运行在一个没有自身网络的沙盒 iframe 中,所以 hx-get 无处可去。sgcHTML 用一个注册 htmx 扩展的桥接来解决这个问题:页面上的每个 hx-get 和 hx-post 都会变成对配套工具的一次调用,返回的标记会像 htmx 替换 HTTP 响应一样被精确替换。
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;
同一份通过 HTTP 提供的标记,就是一个普通的 htmx 请求。你只需编写一次页面,它就能在两种场景下都正常工作。
单一文档,没有外部链接
由于框架没有网络,文档承载了一切:页面、样式表、脚本和桥接代码,全部放在一个文件里。页面模板新增的 InlineAssets 选项就是做这件事的,并且在 MCP Apps 中默认开启。一个典型的应用文档大约 360 KB,渲染时不需要其他任何东西。
宿主还会通过 PreferredWidth 和 PreferredHeight 得知应该以什么尺寸打开这个框架,而页面也会在内容变化时报告自己的高度。
无需安装助手也能看到它
新的 19.MCPApp 演示是一个运行在 5725 端口、发布两个应用的控制台服务器,并且自带一个参考宿主。打开 http://localhost:5725/,左侧面板扮演模型的角色:它调用工具、读取资源、在沙盒框架中渲染页面、响应握手、在页面请求时调整框架大小,并转发页面所调用的内容。下方的日志显示了双向的每一条消息。
当你想要接入真实环境时,把 Claude、ChatGPT 或 VS Code 指向 http://localhost:5725/mcp。工具和资源已经在那里声明好了。
它不是什么
该组件不保存任何状态。谁可以调用工具、一条记录意味着什么、以及一个片段请求可以返回什么,都是你的应用自己的决定,就像 Web 应用中的一条路由一样。而且页面无法夹带任何东西:模型能够触发的,只是你注册的工具,用你构建的标记来回答。
升级
MCP Apps 是 sgcHTML 的一部分,需要 SGC_AI_MCP,也就是 Enterprise 和 All-Access 版本以及 sgcAI 包。对于已有的 MCP 服务器,一切都不会改变:该组件会挂接到你已有的服务器上,并且不会影响你已经发布的工具。
延伸阅读
观看视频
关于此功能的简短视频发布在eSeGeCe 频道上。
有问题、反馈,或需要迁移方面的帮助?欢迎联系我们 — 你会收到编写这些代码的人的回复。
