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 트랜스포트에서 서버 프로세스는 stdin에서 줄바꿈으로 구분된 JSON-RPC 메시지를 읽고, stdout에 JSON-RPC 응답을 한 줄에 압축된 JSON 객체 하나씩 UTF-8로 인코딩하여 씁니다. 클라이언트가 관계를 소유합니다. 클라이언트는 서버 실행 파일을 시작하고, 자식의 입력 파이프에 요청을 쓰며, 출력 파이프에서 응답을 읽고, 각 응답을 JSON-RPC id로 해당 요청에 매칭합니다. 서버가 시작하는 알림도 같은 채널을 통해 전달됩니다.
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 이벤트를 통해 전달되며, 서버 알림은 HTTP 트랜스포트와 동일하게 OnMCPLoggingMessage, OnMCPProgress 및 그 밖의 알림 이벤트를 통해 도착합니다. StdioOptions는 자식 프로세스가 특정 환경 변수를 필요로 할 때 Environment 항목도 받습니다.
Claude Code 및 다른 AI 에이전트와 함께 사용하기
이 트랜스포트는 MCP stdio 규약을 따르므로, 규약을 준수하는 어떤 MCP 클라이언트도 여러분의 Delphi 서버를 시작할 수 있습니다. Claude Code에 등록하려면 실행 파일을 가리키는 항목을 MCP 구성에 추가하세요.
{
"mcpServers": {
"my-delphi-server": {
"command": "C:\\MyServer\\MyDelphiServer.exe",
"args": ["--stdio"]
}
}
}
에이전트는 필요할 때 서버를 생성하고, 여러분이 등록한 도구를 나열하며, 작업하는 동안 그 도구를 호출합니다. 여러분의 Delphi 코드는 배포하거나 보호해야 할 웹 서버 없이 AI 어시스턴트를 위한 일급 도구 제공자가 됩니다.
장점
- 네트워크 표면 없음. 열어야 할 포트도, HTTP 리스너도 없고, 로컬 사용을 위해 구성할 TLS나 인증도 없습니다. 통신은 순수한 stdin과 stdout입니다.
- 기본 로컬 패턴. Claude Code와 Cursor 같은 AI 코딩 도구는 stdio를 통해 MCP 서버를 생성하므로, 여러분의 서버는 어댑터 없이 통합됩니다.
- 깔끔한 수명 주기와 격리. 서버는 클라이언트 프로세스와 함께 살고 죽습니다. 클라이언트당 서버 하나, 공유 상태 없음, 남아 있는 리스너 없음.
- 동일한 MCP API. 도구, 프롬프트, 리소스는 HTTP 서버와 같은 방식으로 등록됩니다. 클라이언트에서 트랜스포트를 전환하는 것은 단일 속성입니다.
- 데스크톱 및 오프라인 사용에 이상적. HTTP 엔드포인트 노출이 불필요하거나 바람직하지 않을 때, stdio는 모든 것을 로컬 머신 안에 유지합니다.
- 견고한 프레이밍. UTF-8을 통한 줄바꿈으로 구분된 JSON-RPC이며, 폭넓은 클라이언트 호환성을 위해 인바운드 메시지의 선행 바이트 순서 표시를 허용합니다.
업그레이드
stdio 트랜스포트는 손쉽게 추가되는 기능입니다. 기존의 HTTP 및 Streamable HTTP 서버와 클라이언트는 변경되지 않으며, 새 트랜스포트는 동일한 도구, 프롬프트, 리소스 모델을 재사용하므로 마이그레이션할 것이 없습니다. 이를 채택하려면 TsgcAI_MCP_Server_Stdio를 중심으로 서버를 콘솔 애플리케이션으로 빌드하거나, 클라이언트에서 Transport를 aimcptrStdio로 설정하세요. 최신 버전은 sgcWebSockets 다운로드 페이지에서 받을 수 있습니다.
질문, 피드백 또는 마이그레이션 도움이 필요하신가요? 문의하기, 코드를 작성한 사람들에게서 답변을 받게 됩니다.
