Trasporto MCP stdio per sgcWebSockets

· Componenti

I componenti Model Context Protocol (MCP) di sgcWebSockets ti permettono già di creare server e client MCP in Delphi su HTTP e Streamable HTTP. Questa release aggiunge un terzo trasporto a entrambi i lati: stdio. Il tuo server MCP ora può girare su input e output standard, e il tuo client MCP può avviare un eseguibile server e comunicare con esso attraverso quel confine di processo. Nessun listener HTTP, nessuna porta, nessuna configurazione TLS per l'uso locale.

Questo è importante perché stdio è il modo nativo con cui i moderni agenti AI di coding si connettono ai server MCP. Strumenti come Claude Code, Cursor e altri client MCP avviano un server come processo figlio e si scambiano JSON-RPC tramite il suo stdin e stdout. Con questo trasporto, un server MCP Delphi si inserisce direttamente in quell'ecosistema.

Che cos'è il trasporto stdio

Nel trasporto stdio, il processo server legge messaggi JSON-RPC delimitati da newline da stdin e scrive risposte JSON-RPC su stdout, un oggetto JSON compatto per riga, codificato come UTF-8. Il client possiede la relazione: avvia l'eseguibile server, scrive le richieste nella pipe di input del figlio e legge le risposte dalla sua pipe di output, abbinando ciascuna risposta alla sua richiesta tramite l'id JSON-RPC. Le notifiche avviate dal server viaggiano sullo stesso canale.

Rispetto a HTTP, non c'è alcun socket e nessuna superficie di rete. Tutto avviene attraverso pipe ereditate tra un processo padre e un processo figlio sulla stessa macchina.

Eseguire un server MCP su stdio

Il nuovo host TsgcAI_MCP_Server_Stdio incapsula lo stesso core MCP usato dal server HTTP, quindi registri tool, prompt e risorse esattamente come prima. Costruiscilo come applicazione console, registra i tuoi tool, poi chiama Run per iniziare a pompare i messaggi.

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.

Una regola quando costruisci un server stdio: stdout è il canale del protocollo, quindi non scrivere mai banner o log su di esso. Invia invece eventuali diagnostiche a stderr o a un file.

Connettere un client MCP su stdio

Sul client, mantieni la stessa API pubblica. Seleziona il trasporto stdio e indica al client quale eseguibile avviare tramite le nuove StdioOptions. Il client avvia il processo, esegue l'handshake di inizializzazione e poi espone tool, prompt e risorse esattamente come il client 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;

La risposta viene consegnata tramite il consueto evento OnMCPResponseTool, e le notifiche del server arrivano tramite OnMCPLoggingMessage, OnMCPProgress e gli altri eventi di notifica, identici al trasporto HTTP. StdioOptions accetta anche voci Environment quando il processo figlio necessita di variabili d'ambiente specifiche.

Usalo con Claude Code e altri agenti AI

Poiché il trasporto segue la convenzione MCP stdio, qualsiasi client MCP conforme può avviare il tuo server Delphi. Per registrarlo con Claude Code, aggiungi una voce alla configurazione MCP che punti al tuo eseguibile.

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

L'agente avvia il server su richiesta, elenca i tool che hai registrato e li chiama mentre lavora. Il tuo codice Delphi diventa un fornitore di tool di prima classe per gli assistenti AI, senza alcun web server da distribuire o proteggere.

Vantaggi

Aggiornamento

Il trasporto stdio è un'aggiunta drop-in. I server e i client HTTP e Streamable HTTP esistenti rimangono invariati, e il nuovo trasporto riutilizza lo stesso modello di tool, prompt e risorse, quindi non c'è nulla da migrare. Per adottarlo, costruisci il tuo server come applicazione console attorno a TsgcAI_MCP_Server_Stdio, oppure imposta Transport su aimcptrStdio sul client. Puoi scaricare l'ultima versione dalla pagina di download di sgcWebSockets.

Domande, feedback o aiuto per la migrazione? Contattaci, riceverai una risposta dalle persone che hanno scritto il codice.