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
- Brak powierzchni sieciowej. Nie ma portu do otwarcia, nie ma nasłuchiwania HTTP ani TLS czy uwierzytelniania do skonfigurowania na potrzeby użytku lokalnego. Komunikacja to czyste stdin i stdout.
- Natywny wzorzec lokalny. Narzędzia kodujące AI, takie jak Claude Code i Cursor, uruchamiają serwery MCP przez stdio, więc Twój serwer integruje się bez adaptera.
- Czysty cykl życia i izolacja. Serwer żyje i kończy działanie wraz z procesem klienta. Jeden serwer na klienta, brak współdzielonego stanu i brak pozostawionych nasłuchów.
- To samo API MCP. Narzędzia, prompty i zasoby rejestruje się w ten sam sposób co w serwerze HTTP. Przełączenie transportu po stronie klienta to pojedyncza właściwość.
- Idealny do użytku na komputerach stacjonarnych i offline. Gdy udostępnianie punktu końcowego HTTP jest zbędne lub niepożądane, stdio utrzymuje wszystko wewnątrz maszyny lokalnej.
- Solidne ramkowanie. JSON-RPC rozdzielany znakiem nowej linii w UTF-8, z tolerancją wiodącego znacznika kolejności bajtów w komunikatach przychodzących dla szerokiej zgodności z klientami.
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.
