sgcWebSockets 向け MCP stdio トランスポート

· コンポーネント

sgcWebSockets の Model Context Protocol (MCP) コンポーネントは、すでに HTTP および Streamable HTTP 上で Delphi 製の MCP サーバーとクライアントを構築できるようにしています。今回のリリースでは、両方の側に三つ目のトランスポートとして stdio を追加しました。MCP サーバーは標準入出力上で動作できるようになり、MCP クライアントはサーバーの実行ファイルを起動して、そのプロセス境界を越えて通信できるようになります。HTTP リスナーも、ポートも、ローカル利用のための TLS 設定も不要です。

これが重要なのは、stdio が現代の AI コーディングエージェントが MCP サーバーに接続するネイティブな方法だからです。Claude Code、Cursor、その他の MCP クライアントといったツールは、サーバーを子プロセスとして起動し、その stdin と stdout 上で JSON-RPC をやり取りします。このトランスポートにより、Delphi 製の MCP サーバーはそのエコシステムへそのまま入り込めます。

stdio トランスポートとは

stdio トランスポートでは、サーバープロセスは改行区切りの JSON-RPC メッセージを stdin から読み取り、JSON-RPC レスポンスを stdout へ書き込みます。1 行につき 1 つのコンパクトな JSON オブジェクトを、UTF-8 でエンコードして出力します。この関係を所有するのはクライアントです。クライアントはサーバーの実行ファイルを起動し、子プロセスの入力パイプにリクエストを書き込み、その出力パイプからレスポンスを読み取り、各レスポンスを JSON-RPC の id によってリクエストと対応付けます。サーバー発のnotification も同じチャネルを通ります。

HTTP と比べると、ソケットもネットワーク上の露出面もまったくありません。すべては同一マシン上の親プロセスと子プロセスの間で、継承されたパイプを通じて行われます。

stdio 上で MCP サーバーを動作させる

新しい TsgcAI_MCP_Server_Stdio ホストは、HTTP サーバーが使うのと同じ MCP コアをラップしています。そのため、ツール、プロンプト、リソースは以前とまったく同じように登録できます。これをコンソールアプリケーションとしてビルドし、ツールを登録してから Run を呼び出してメッセージのポンプ処理を開始します。

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.

stdio サーバーを構築するときの一つのルール: stdout はプロトコルのチャネルなので、そこへバナーやログを決して書き込まないでください。診断情報はすべて stderr またはファイルへ送ってください。

stdio 上で MCP クライアントを接続する

クライアント側では、同じパブリック API をそのまま使い続けます。stdio トランスポートを選択し、新しい StdioOptions を通じて、どの実行ファイルを起動するかをクライアントに伝えます。クライアントはプロセスを起動し、initialize ハンドシェイクを実行してから、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;

レスポンスはいつもの OnMCPResponseTool イベントを通じて配信され、サーバーのnotification は OnMCPLoggingMessageOnMCPProgress、そしてその他のnotification イベントを通じて届きます。これは HTTP トランスポートと同一です。子プロセスが特定の環境変数を必要とする場合、StdioOptionsEnvironment エントリも受け付けます。

Claude Code やその他の AI エージェントで使う

このトランスポートは MCP の stdio 規約に従っているため、準拠したあらゆる MCP クライアントが Delphi 製サーバーを起動できます。Claude Code に登録するには、実行ファイルを指すエントリを MCP 設定に追加します。

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

エージェントは必要に応じてサーバーを起動し、登録したツールを一覧し、作業しながらそれらを呼び出します。Delphi のコードは、デプロイやセキュリティ保護が必要な Web サーバーを一切持たずに、AI アシスタント向けの第一級のツールプロバイダーになります。

利点

アップグレード

stdio トランスポートはドロップインで追加できます。既存の HTTP および Streamable HTTP のサーバーとクライアントは変更されず、新しいトランスポートは同じツール、プロンプト、リソースのモデルを再利用するため、移行すべきものは何もありません。導入するには、TsgcAI_MCP_Server_Stdio を中心にサーバーをコンソールアプリケーションとしてビルドするか、クライアントで TransportaimcptrStdio に設定します。最新バージョンは sgcWebSockets ダウンロードページからダウンロードできます。

ご質問、フィードバック、または移行のサポートが必要ですか? お問い合わせください。コードを書いた本人たちから返信が届きます。