Transporte stdio do MCP para sgcWebSockets

· Componentes

Os componentes Model Context Protocol (MCP) do sgcWebSockets já permitem que você construa servidores e clientes MCP em Delphi sobre HTTP e Streamable HTTP. Esta versão adiciona um terceiro transporte a ambos os lados: stdio. O seu servidor MCP agora pode rodar sobre entrada e saída padrão, e o seu cliente MCP pode iniciar um executável de servidor e conversar com ele através dessa fronteira de processo. Sem listener HTTP, sem porta, sem configuração de TLS para uso local.

Isso importa porque o stdio é a forma nativa pela qual os agentes modernos de codificação com IA se conectam a servidores MCP. Ferramentas como o Claude Code, o Cursor e outros clientes MCP iniciam um servidor como processo filho e trocam JSON-RPC pelo seu stdin e stdout. Com este transporte, um servidor MCP em Delphi se encaixa diretamente nesse ecossistema.

O que é o transporte stdio

No transporte stdio, o processo do servidor lê mensagens JSON-RPC delimitadas por nova linha de stdin e escreve respostas JSON-RPC em stdout, um objeto JSON compacto por linha, codificado como UTF-8. O cliente é dono da relação: ele inicia o executável do servidor, escreve requisições no pipe de entrada do filho e lê as respostas do seu pipe de saída, casando cada resposta com a sua requisição pelo id do JSON-RPC. As notificações iniciadas pelo servidor trafegam pelo mesmo canal.

Comparado ao HTTP, não há socket nem qualquer superfície de rede. Tudo acontece através de pipes herdados entre um processo pai e um processo filho na mesma máquina.

Rodando um servidor MCP sobre stdio

O novo host TsgcAI_MCP_Server_Stdio encapsula o mesmo núcleo MCP usado pelo servidor HTTP, então você registra ferramentas, prompts e recursos exatamente como antes. Construa-o como uma aplicação de console, registre as suas ferramentas e então chame Run para começar a bombear mensagens.

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.

Uma regra ao construir um servidor stdio: stdout é o canal do protocolo, então nunca escreva banners ou logs nele. Envie qualquer diagnóstico para stderr ou para um arquivo, em vez disso.

Conectando um cliente MCP sobre stdio

No cliente, você mantém a mesma API pública. Selecione o transporte stdio e diga ao cliente qual executável iniciar por meio das novas StdioOptions. O cliente inicia o processo, executa o handshake de inicialização e então expõe ferramentas, prompts e recursos exatamente como o cliente 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;

A resposta é entregue através do evento OnMCPResponseTool habitual, e as notificações do servidor chegam através de OnMCPLoggingMessage, OnMCPProgress e dos demais eventos de notificação, idênticos ao transporte HTTP. StdioOptions também aceita entradas de Environment quando o processo filho precisa de variáveis de ambiente específicas.

Use-o com o Claude Code e outros agentes de IA

Como o transporte segue a convenção stdio do MCP, qualquer cliente MCP compatível pode iniciar o seu servidor em Delphi. Para registrá-lo no Claude Code, adicione uma entrada à configuração do MCP que aponte para o seu executável.

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

O agente inicia o servidor sob demanda, lista as ferramentas que você registrou e as chama enquanto trabalha. O seu código Delphi se torna um provedor de ferramentas de primeira classe para assistentes de IA, sem servidor web para implantar ou proteger.

Vantagens

Atualizando

O transporte stdio é um acréscimo plug-and-play. Os servidores e clientes HTTP e Streamable HTTP existentes permanecem inalterados, e o novo transporte reaproveita o mesmo modelo de ferramentas, prompts e recursos, então não há nada a migrar. Para adotá-lo, construa o seu servidor como uma aplicação de console em torno de TsgcAI_MCP_Server_Stdio, ou defina Transport como aimcptrStdio no cliente. Você pode baixar a versão mais recente na página de download do sgcWebSockets.

Dúvidas, comentários ou ajuda com a migração? Entre em contato, você receberá uma resposta das pessoas que escreveram o código.