Model Context Protocol이란?
Model Context Protocol(MCP)은 AI 모델에 도구, 데이터 및 프롬프트 템플릿을 노출하기 위한 Anthropic의 개방형 표준이에요. AI용 USB로 생각하세요: 모든 MCP 서버는 모든 MCP 클라이언트(Claude Desktop, Cursor, Continue, 자체 Delphi 앱, OpenAI의 클라이언트)에 연결될 수 있으며 모델은 즉시 사용 가능한 도구와 호출 방법을 발견해요.
MCP 이전에는 모든 AI 통합이 각 개별 앱에 도구 정의, JSON 스키마 및 호출 디스패처를 연결하는 것을 의미했어요. MCP는 그것을 단일 프로토콜로 축소해요: 서버를 한 번 작성하면 모든 모델이 사용할 수 있어요. 이미 비즈니스 API 스택(ERP 쿼리, CRM 조회, 파일 생성기, 청구 함수)이 있는 Delphi 회사의 경우 MCP는 해당 API를 AI 액세스 가능하게 만드는 가장 저렴한 경로예요.
이 튜토리얼은 TsgcAI_MCP_Server 컴포넌트를 사용하여 Delphi에서 MCP 서버를 구축하고, 작동하는 get_weather 도구를 노출하고, stdio 및 HTTP 전송 모두를 통해 Claude Desktop에 연결하는 과정을 살펴봐요.
역사가 MCP를 맥락에 놓아요. Anthropic은 호환되지 않는 도구 호출 형식의 확산 — OpenAI의 함수 호출 JSON, Google의 Gemini 그라운딩 도구, 모든 공급업체의 맞춤형 스키마 — 에 대한 답변으로 2024년 말에 사양을 게시했어요. 이것을 읽을 때쯤이면 MCP 지원이 Claude Desktop, Cursor, Continue, Zed 및 대부분의 최신 AI IDE에 출시되고 있어요; OpenAI는 2026년 초에 호환성을 발표했어요. 다시 말해: 오늘 MCP 서버를 구축하는 것은 오늘과 내일 모두 고객이 사용할 수 있는 모든 클라이언트에 걸쳐 보상하는 일회성 투자예요.
MCP 빌딩 블록
MCP 서버는 세 가지 종류의 기능을 노출할 수 있어요:
| 도구 타입이 지정된 입력이 있는 호출 가능한 함수. 모델이 호출 시점을 결정해요. 예: get_weather(city), create_invoice(customer, lines). |
리소스 모델이 가져올 수 있는 읽기 전용 데이터. 각 리소스에는 URI가 있어요. 예: file:///docs/handbook.md, db://customers/12345. |
프롬프트 사용자(모델이 아님)가 선택하는 재사용 가능한 프롬프트 템플릿. 예: "공식 스페인어로 번역" 또는 "회의 노트 요약" 템플릿. |
프로토콜은 두 가지 전송 중 하나를 통해 JSON-RPC 2.0을 사용해요: stdio(서버가 자식 프로세스; 메시지가 stdin/stdout을 통해 흐름) 또는 서버-투-클라이언트 스트림용 Server-Sent Events가 있는 HTTP. Stdio는 Claude Desktop과 같은 데스크톱 통합의 기본값이에요; HTTP는 서버가 다른 머신에서 실행되거나 여러 클라이언트를 제공할 때 올바른 선택이에요.
컴포넌트는 단일 API 뒤에 두 전송을 숨겨요. 도구 핸들러를 한 번 작성한 다음 시작 시 전송을 선택해요. 동일한 코드가 Claude Desktop 헬퍼, 네트워크 도달 가능한 HTTP 서비스 또는 한 프로세스 내에서 동시에 둘 다로 실행돼요. 단일 박스에서 30+ MCP 서버를 실행하는 회사를 보았어요. 다른 포트에 걸쳐 다중화되고 하나 또는 두 개의 stdio 바이너리, 모두 동일한 Delphi 코드베이스를 제공해요.
프로젝트 설정
uses 절에 sgcAI_MCP_Server를 추가하고, 폼에 TsgcAI_MCP_Server를 드롭하고(또는 콘솔 앱의 경우 코드에서 생성), 이벤트를 연결하고, 시작하세요. 컴포넌트가 JSON-RPC 프레이밍, 메시지 라우팅 및 기능 광고를 처리해요.
uses sgcAI_MCP_Server, sgcAI_MCP_Classes; procedure TForm1.FormCreate(Sender: TObject); begin oMCP := TsgcAI_MCP_Server.Create(Self); oMCP.ServerInfo.Name := 'weather-mcp'; oMCP.ServerInfo.Version := '1.0.0'; // Wire handlers oMCP.OnListTools := DoListTools; oMCP.OnCallTool := DoCallTool; // Stdio transport for Claude Desktop integration oMCP.Transport := mtStdio; oMCP.Active := True; end;
도구 구현: get_weather
도구에는 두 개의 핸들러가 필요해요. OnListTools는 어떤 도구가 존재하고 어떤 인수를 수락하는지 클라이언트에 알려줘요. OnCallTool은 실제로 호출을 실행해요. 두 핸들러 모두 일반 Delphi 이벤트예요 — 수동 JSON 구성 없음.
procedure TForm1.DoListTools(Sender: TObject;
const aTools: TsgcAI_MCP_Tools);
var
oTool: TsgcAI_MCP_Tool;
begin
oTool := aTools.Add;
oTool.Name := 'get_weather';
oTool.Description := 'Return the current weather for a city.';
oTool.InputSchema :=
'{"type":"object",' +
'"properties":{' +
'"city":{"type":"string","description":"City name, e.g. Madrid"},' +
'"units":{"type":"string","enum":["metric","imperial"],"default":"metric"}' +
'},' +
'"required":["city"]}';
end;
procedure TForm1.DoCallTool(Sender: TObject;
const aRequest : TsgcAI_MCP_ToolCall;
const aResult : TsgcAI_MCP_ToolResult);
var
vCity, vUnits, vReport: string;
begin
if aRequest.Name = 'get_weather' then
begin
vCity := aRequest.Arguments.S['city'];
vUnits := aRequest.Arguments.S['units'];
if vUnits = '' then vUnits := 'metric';
// Call your own weather backend
vReport := MyWeatherService.Fetch(vCity, vUnits);
aResult.AddText(vReport);
end
else
aResult.Error('Unknown tool: ' + aRequest.Name);
end;
그것이 전체 구현이에요. 컴포넌트는 스키마에 대한 입력 검증, 오류 형식 지정 및 기본 JSON-RPC 엔벨로프를 처리해요. 비즈니스 로직에 집중하세요.
좋은 도구 설계를 위한 몇 가지 원칙, 힘들게 배운 것:
- 도구당 하나의 동사. "get_weather"가 하위 액션 매개변수가 있는 "weather_operations"보다 나아요. 각 이름이 정확히 하나의 결과를 설명할 때 모델이 더 빠르게 올바른 도구를 선택해요.
- 설명에 무자비하게. 스키마 설명은 도구가 무엇을 하고 무엇을 하지 않는지 모델에게 가르치는 유일한 기회예요. 엣지 케이스, 단위, 형식 및 전제 조건을 명시하세요.
- 가능한 모든 것을 기본값으로. 합리적인 기본값이 있는 선택적 매개변수를 사용하면 모델이 컨텍스트의 절반만 알고 있어도 도구를 성공적으로 호출할 수 있어요.
- 작고 집중된 페이로드 반환. 50줄 텍스트 응답은 괜찮아요; 5,000줄 덤프는 컨텍스트 윈도우와 청구서를 부풀려요. 서버 측에서 요약하세요.
- 명시적으로 실패. 자동으로 빈 결과를 반환하는 대신 구조화된 오류 메시지("도시가 인식되지 않음. Madrid 또는 Madras를 의미했나요?")를 반환하세요.
리소스 노출
도구는 작업용이고; 리소스는 모델이 읽을 수 있는 데이터용이에요. 리소스 핸들러는 주어진 URI에 대한 콘텐츠를 반환해요. 문서 서버는 docs/ 아래의 모든 Markdown 파일을 리소스로 노출할 수 있어요.
oMCP.OnListResources := DoListResources;
oMCP.OnReadResource := DoReadResource;
procedure TForm1.DoListResources(Sender: TObject;
const aResources: TsgcAI_MCP_Resources);
var
vFiles: TStringDynArray;
i : Integer;
oRes : TsgcAI_MCP_Resource;
begin
vFiles := TDirectory.GetFiles('C:\docs', '*.md');
for i := 0 to High(vFiles) do
begin
oRes := aResources.Add;
oRes.URI := 'file:///' + StringReplace(vFiles[i], '\', '/', [rfReplaceAll]);
oRes.Name := ExtractFileName(vFiles[i]);
oRes.MimeType := 'text/markdown';
oRes.Description := 'Documentation page';
end;
end;
procedure TForm1.DoReadResource(Sender: TObject;
const aURI: string; const aResult: TsgcAI_MCP_ResourceResult);
var
vPath: string;
begin
vPath := StringReplace(Copy(aURI, 9, MaxInt), '/', '\', [rfReplaceAll]);
if FileExists(vPath) then
aResult.AddText(TFile.ReadAllText(vPath))
else
aResult.Error('Resource not found');
end;
Stdio vs HTTP 전송
서버가 실행되는 위치와 사용자에 따라 전송을 선택하세요.
| 전송 | 사용 사례 | 장점 | 단점 |
| Stdio | 로컬 데스크톱 도구 (Claude Desktop, Cursor) | 구성 없음, 포트 없음, OS가 프로세스 라이프사이클 처리 | 프로세스당 하나의 클라이언트, 원격 액세스 없음 |
| HTTP / SSE | 공유 기업 서버, 웹 클라이언트, 다중 테넌트 | 많은 클라이언트, 네트워크 도달 가능, TLS, 인증 | 호스팅, 포트 관리, 인증 디자인 필요 |
전송 전환은 한 줄짜리예요:
// Stdio (default for desktop) oMCP.Transport := mtStdio; // HTTP listener on port 8080 oMCP.Transport := mtHTTP; oMCP.HTTPOptions.Host := '0.0.0.0'; oMCP.HTTPOptions.Port := 8080; oMCP.HTTPOptions.TLS.Enabled := True; oMCP.HTTPOptions.TLS.CertFile := 'cert.pem'; oMCP.HTTPOptions.TLS.KeyFile := 'key.pem'; oMCP.Active := True;
Claude Desktop에서 연결
stdio의 경우 claude_desktop_config.json을 편집하고 컴파일된 .exe를 가리키는 항목을 추가하세요. Claude Desktop이 요청에 따라 프로세스를 생성해요.
{
"mcpServers": {
"weather": {
"command": "C:\\Tools\\weather-mcp.exe",
"args": []
}
}
}
Claude Desktop을 다시 시작하면 프롬프트 영역에 작은 도구 아이콘이 표시돼요. "도쿄의 날씨는 어떤가요?"라고 물으면 Claude가 Delphi 도구를 호출해요.
HTTP의 경우 MCP 가능 클라이언트를 https://your-host:8080/mcp로 가리키세요. 동일한 Delphi 서버가 Claude Desktop 인스턴스, Cursor 세션 및 사용자 정의 Delphi MCP 클라이언트를 동시에 행복하게 처리해요.
프롬프트: 잘 사용되지 않는 세 번째 기능
도구와 리소스가 모든 관심을 받아요; 프롬프트는 조용한 일꾼이에요. MCP 프롬프트는 사용자가 MCP 클라이언트의 UI 메뉴에서 호출하는 재사용 가능한 템플릿 — "이 회의 요약", "액션 항목 추출", "공식 스페인어로 번역" — 이에요. 그런 다음 모델은 사용자가 제공한 모든 컨텍스트에 대해 해당 프롬프트를 실행해요.
내부 도구의 경우 이것은 금이에요. 지원 팀은 Claude Desktop 내에서 회사 승인 프롬프트의 큐레이션된 목록을 받아요. 영업 팀은 톤을 이미 알고 있는 "후속 이메일 초안" 프롬프트를 받아요. 그들 중 누구도 프롬프트 엔지니어링을 배울 필요가 없어요 — 그저 템플릿을 선택해요.
oMCP.OnListPrompts := DoListPrompts;
oMCP.OnGetPrompt := DoGetPrompt;
procedure TForm1.DoListPrompts(Sender: TObject;
const aPrompts: TsgcAI_MCP_Prompts);
var
oPrompt: TsgcAI_MCP_Prompt;
begin
oPrompt := aPrompts.Add;
oPrompt.Name := 'summarise_meeting';
oPrompt.Description := 'Turn a meeting transcript into bullet decisions and actions.';
oPrompt.AddArgument('transcript', 'Plain-text transcript', True);
end;
procedure TForm1.DoGetPrompt(Sender: TObject;
const aRequest: TsgcAI_MCP_PromptRequest;
const aResult : TsgcAI_MCP_PromptResult);
begin
if aRequest.Name = 'summarise_meeting' then
aResult.AddMessage('user',
'You are a meeting note taker. Read the transcript and produce: ' +
'(1) a 3-sentence summary, (2) decisions taken, (3) action items ' +
'with owners and due dates.' + sLineBreak + sLineBreak +
aRequest.Arguments.S['transcript']);
end;
프로덕션 고려 사항
MCP 서버를 프로덕션에 배포하기 전에 예산을 잡아야 할 몇 가지 사항:
- 인증: stdio는 OS 수준 신뢰를 상속하지만 HTTP는 베어러 토큰 또는 mTLS가 필요해요. 검증하려면
OnHTTPAuthenticate를 사용하세요. - 속도 제한: 수다스러운 모델은 타이트한 루프에서 도구 호출을 발사할 수 있어요. MCP 서버를
TsgcWebSocketHTTPServer_RateLimiter또는 자체 할당량 로직과 페어링하세요. - 로깅: 모든 도구 호출을 캡처하려면
OnLog를 연결하세요. 사용자가 "Claude가 이상한 일을 했어요"라고 보고할 때 이것이 필요할 거예요. - 스키마 규율: JSON 스키마(설명, 열거형, 예제)가 더 정확할수록 모델이 올바른 인수로 올바른 도구를 더 잘 선택해요.
- 멱등성: 모델이 재시도하면 도구가 두 번 호출될 수 있어요. 쓰기 작업을 멱등으로 표시하거나 트랜잭션 ID 매개변수를 추가하세요.
디버깅 팁
MCP는 AI 클라이언트 내부에서 보이지 않게 실행되므로 처음 무언가 잘못되면 디버깅이 까다로워요. 세 가지 습관이 시간을 절약해 줄 거예요:
- Stderr이 콘솔이에요. stdio 모드에서 stdout은 JSON-RPC에 속해요. 그것에 쓰는 모든 것은 프로토콜을 깨요. stderr(Claude Desktop이 로그 파일에 캡처)에 로깅하거나 프로세스 ID 접미사가 있는 사이드 로그 파일에 로깅하세요.
- MCP Inspector를 사용하세요. Anthropic은 UI를 서버에 가리키고, 각 도구를 클릭하고, 원시 요청/응답을 보고, AI 클라이언트를 전혀 관여시키지 않고 스키마를 검증할 수 있는 무료 도구(
npx @modelcontextprotocol/inspector)를 제공해요. - "진단" 도구 추가. 빌드 날짜, 호스트 및 버전을 반환하는 간단한
server_info도구는 AI 클라이언트에서 올바른 서버와 통신하고 있는지 확인하는 것을 사소하게 만들어요. 우리는 모든 프로덕션 MCP 서버에 이것을 추가해요.
마무리
MCP는 클라이언트별 연결 없이 모든 최신 AI 클라이언트가 사용할 수 있는 것으로 내부 Delphi API를 변환해요. TsgcAI_MCP_Server 컴포넌트는 JSON-RPC 프레이밍, 전송 및 기능 광고를 처리하여 실제 도구 본문을 작성하도록 남겨요. 하나의 읽기 전용 도구로 시작하여 모델이 어떻게 사용하는지 보고 쓰기, 리소스 및 프롬프트로 확장하세요.
내부적으로 MCP를 출시하면서 얻은 가장 큰 교훈: 가치는 "Claude가 이제 우리 API를 사용할 수 있다"가 아니에요. 가치는 "회사의 누구나 API를 배우지 않고도 자연어를 통해 API를 사용할 수 있다"예요. 그것은 누가 무엇을 할 수 있는지 바꾸고, 그것이 실제 생산성 향상이 오는 곳이에요.
매칭 클라이언트를 원하나요? 모든 MCP 서버를 소비하는 Delphi 앱을 빌드하는 TsgcAI_MCP_Client를 참조하세요. 그리고 AI 컴포넌트가 처음이라면 시작하기 허브가 5분 안에 설치를 안내해 줄 거예요.