ChatGPT와 Claude 안에서 Delphi 앱 실행하기

· 컴포넌트
ChatGPT와 Claude 안에서 Delphi 앱 실행하기

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-gethx-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에서는 기본적으로 켜져 있습니다. 일반적인 앱 문서는 약 360KB이며, 렌더링을 위해 그 밖에 아무것도 필요하지 않습니다.

호스트는 또한 PreferredWidthPreferredHeight를 통해 프레임을 어떤 크기로 열어야 하는지 전달받으며, 페이지는 콘텐츠가 바뀔 때마다 자신의 높이를 보고합니다.

어시스턴트를 설치하지 않고도 확인할 수 있습니다

새로운 데모 19.MCPApp은 포트 5725에서 두 개의 앱을 게시하는 콘솔 서버이며, 자체 참조 호스트도 함께 제공합니다. http://localhost:5725/ 를 열면 왼쪽 패널이 모델 역할을 대신합니다. 도구를 호출하고, 리소스를 읽고, 샌드박스 처리된 프레임 안에서 렌더링하며, 핸드셰이크에 응답하고, 페이지가 요청하면 프레임 크기를 조정하며, 페이지가 호출하는 내용을 전달합니다. 그 아래 로그는 양방향의 모든 메시지를 보여줍니다.

실제 환경을 원할 때는 Claude, ChatGPT 또는 VS Code를 http://localhost:5725/mcp 로 지정하세요. 도구와 리소스는 이미 그곳에 선언되어 있습니다.

이것이 아닌 것

이 컴포넌트는 어떠한 상태도 저장하지 않습니다. 누가 도구를 호출할 수 있는지, 레코드가 무엇을 의미하는지, 조각 요청이 무엇을 반환할 수 있는지는 웹 애플리케이션의 라우트와 마찬가지로 여러분의 애플리케이션이 결정할 사항입니다. 그리고 페이지는 아무것도 몰래 반입할 수 없습니다. 모델이 실행할 수 있는 것은 여러분이 등록한 도구뿐이며, 그 도구는 여러분이 만든 마크업으로 응답합니다.

업그레이드

MCP Apps는 sgcHTML의 일부이며, Enterprise 및 All-Access 에디션과 sgcAI 팩을 의미하는 SGC_AI_MCP가 필요합니다. 기존 MCP 서버에는 아무것도 바뀌지 않습니다. 이 컴포넌트는 이미 가지고 있는 서버에 연결되며, 이미 게시한 도구는 그대로 둡니다.

다음 읽을거리

영상으로 보기

이에 관한 짧은 영상eSeGeCe 채널에 있습니다.

질문, 피드백, 마이그레이션 도움이 필요하신가요? 문의하기 — 코드를 작성한 사람들에게서 직접 답변을 받으실 수 있습니다.