Transport MCP stdio dla sgcWebSockets

· Komponenty

Komponenty Model Context Protocol (MCP) w sgcWebSockets już teraz pozwalają budować serwery i klientów MCP w Delphi przez HTTP oraz Streamable HTTP. To wydanie dodaje trzeci transport po obu stronach: stdio. Twój serwer MCP może teraz działać przez standardowe wejście i wyjście, a Twój klient MCP może uruchomić plik wykonywalny serwera i komunikować się z nim ponad granicą procesu. Bez nasłuchiwania HTTP, bez portu, bez konfiguracji TLS do użytku lokalnego.

Ma to znaczenie, ponieważ stdio jest natywnym sposobem, w jaki nowoczesni agenci kodujący AI łączą się z serwerami MCP. Narzędzia takie jak Claude Code, Cursor i inni klienci MCP uruchamiają serwer jako proces potomny i wymieniają JSON-RPC przez jego stdin i stdout. Dzięki temu transportowi serwer MCP w Delphi wpasowuje się wprost w ten ekosystem.

Czym jest transport stdio

W transporcie stdio proces serwera odczytuje rozdzielone znakiem nowej linii komunikaty JSON-RPC ze stdin i zapisuje odpowiedzi JSON-RPC do stdout, jeden kompaktowy obiekt JSON na linię, zakodowany w UTF-8. To klient jest właścicielem relacji: uruchamia plik wykonywalny serwera, zapisuje żądania do potoku wejściowego procesu potomnego i odczytuje odpowiedzi z jego potoku wyjściowego, dopasowując każdą odpowiedź do jej żądania po identyfikatorze JSON-RPC. Powiadomienia inicjowane przez serwer podróżują tym samym kanałem.

W porównaniu z HTTP nie ma tu w ogóle żadnego gniazda ani powierzchni sieciowej. Wszystko odbywa się przez dziedziczone potoki między procesem nadrzędnym a procesem potomnym na tej samej maszynie.

Uruchamianie serwera MCP przez stdio

Nowy host TsgcAI_MCP_Server_Stdio opakowuje ten sam rdzeń MCP, którego używa serwer HTTP, więc rejestrujesz narzędzia, prompty i zasoby dokładnie tak jak wcześniej. Zbuduj go jako aplikację konsolową, zarejestruj swoje narzędzia, a następnie wywołaj Run, aby rozpocząć przetwarzanie komunikatów.

uses
  SysUtils, sgcAI_MCP_Server, sgcAI_MCP_Classes, sgcAI_MCP_Types;

type
  TServerHandler = class
    procedure OnRequestTool(Sender: TObject; const aSession: TsgcAI_MCP_Session;
      const aRequest: TsgcAI_MCP_Request_ToolsCall;
      const aResponse: TsgcAI_MCP_Response_ToolsCall);
  end;

procedure TServerHandler.OnRequestTool(Sender: TObject;
  const aSession: TsgcAI_MCP_Session;
  const aRequest: TsgcAI_MCP_Request_ToolsCall;
  const aResponse: TsgcAI_MCP_Response_ToolsCall);
var
  vA, vB: Double;
begin
  if aRequest.Params.Name = 'add' then
  begin
    vA := aRequest.Params.Arguments.Node['a'].Value;
    vB := aRequest.Params.Arguments.Node['b'].Value;
    aResponse.Result.Content.AddText(FloatToStr(vA + vB));
  end;
end;

var
  oServer: TsgcAI_MCP_Server_Stdio;
  oTool: TsgcAI_MCP_Tool;
  oHandler: TServerHandler;
begin
  oHandler := TServerHandler.Create;
  oServer := TsgcAI_MCP_Server_Stdio.Create(nil);
  try
    oServer.ServerInfo.Name := 'MyDelphiServer';
    oServer.ServerInfo.Version := '1.0';

    // register a tool, exactly like the HTTP server
    oTool := oServer.MCPServer.Tools.AddTool('add', 'Adds two numbers');
    oTool.InputSchema.Properties.AddProperty('a', True, aimcpjtNumber);
    oTool.InputSchema.Properties.AddProperty('b', True, aimcpjtNumber);

    oServer.MCPServer.OnMCPRequestTool := oHandler.OnRequestTool;

    // read JSON-RPC from stdin, write responses to stdout, blocks until EOF
    oServer.Run;
  finally
    oServer.Free;
    oHandler.Free;
  end;
end.

Jedna zasada przy budowaniu serwera stdio: stdout jest kanałem protokołu, więc nigdy nie zapisuj do niego bannerów ani logów. Wszelkie informacje diagnostyczne kieruj zamiast tego do stderr lub do pliku.

Łączenie klienta MCP przez stdio

Po stronie klienta zachowujesz to samo publiczne API. Wybierz transport stdio i wskaż klientowi, który plik wykonywalny ma uruchomić, za pomocą nowego StdioOptions. Klient uruchamia proces, wykonuje uzgadnianie inicjalizacji, a następnie udostępnia narzędzia, prompty i zasoby zupełnie jak klient HTTP.

uses
  sgcAI_MCP_Client, sgcAI_MCP_Types;

var
  oClient: TsgcWSAPI_Client_MCP;
begin
  oClient := TsgcWSAPI_Client_MCP.Create(nil);
  try
    // select the stdio transport and point it at the server executable
    oClient.MCPOptions.Transport := aimcptrStdio;
    oClient.MCPOptions.StdioOptions.Command := 'C:\MyServer\MyDelphiServer.exe';
    oClient.MCPOptions.StdioOptions.Arguments := '--stdio';
    oClient.MCPOptions.StdioOptions.WorkingDir := 'C:\MyServer';
    oClient.MCPOptions.StdioOptions.Timeout := 20000;

    // the client launches the server and runs the MCP handshake
    oClient.Initialize;

    // discover tools and call one, the result arrives in OnMCPResponseTool
    oClient.ListTools;
    oClient.RequestTool('add', BuildArguments(2, 3));
  finally
    oClient.Free;
  end;
end;

Odpowiedź jest dostarczana przez zwykłe zdarzenie OnMCPResponseTool, a powiadomienia serwera docierają przez OnMCPLoggingMessage, OnMCPProgress oraz pozostałe zdarzenia powiadomień, identycznie jak w transporcie HTTP. StdioOptions akceptuje również wpisy Environment, gdy proces potomny potrzebuje określonych zmiennych środowiskowych.

Użyj go z Claude Code i innymi agentami AI

Ponieważ transport stosuje się do konwencji MCP stdio, dowolny zgodny klient MCP może uruchomić Twój serwer w Delphi. Aby zarejestrować go w Claude Code, dodaj do konfiguracji MCP wpis wskazujący na Twój plik wykonywalny.

{
  "mcpServers": {
    "my-delphi-server": {
      "command": "C:\\MyServer\\MyDelphiServer.exe",
      "args": ["--stdio"]
    }
  }
}

Agent uruchamia serwer na żądanie, wyświetla listę zarejestrowanych przez Ciebie narzędzi i wywołuje je podczas pracy. Twój kod w Delphi staje się pełnoprawnym dostawcą narzędzi dla asystentów AI, bez serwera webowego do wdrożenia lub zabezpieczenia.

Zalety

Aktualizacja

Transport stdio to dodatek typu drop-in. Istniejące serwery i klienci HTTP oraz Streamable HTTP pozostają niezmienieni, a nowy transport ponownie wykorzystuje ten sam model narzędzi, promptów i zasobów, więc nie ma niczego do migracji. Aby go zastosować, zbuduj swój serwer jako aplikację konsolową wokół TsgcAI_MCP_Server_Stdio lub ustaw Transport na aimcptrStdio po stronie klienta. Najnowszą wersję możesz pobrać ze strony pobierania sgcWebSockets.

Pytania, opinie lub pomoc przy migracji? Skontaktuj się z nami, otrzymasz odpowiedź od osób, które napisały ten kod.