모델 컨텍스트 프로토콜(MCP) 및 Go로 MCP 서버를 구현하는 방법에 대한 노트
MCP 사양과 GO에서의 구현에 대한 장문의 글
여기에는 **Model Context Protocol (MCP)**에 대한 설명과 Go로 작성된 MCP 서버를 구현하는 방법에 대한 간단한 노트, 메시지 구조 및 프로토콜 명세가 포함되어 있습니다.
Model Context Protocol (MCP) 개요
**Model Context Protocol (MCP)**는 AI 언어 모델을 외부 데이터 소스, 도구 및 시스템에 연결하기 위한 개방형 표준화된 프레임워크입니다. 이 프로토콜은 Anthropic가 2024년 말에 도입한 것으로, 다양한 애플리케이션에서 파일 읽기, 함수 실행(도구), 맥락 프롬프트 사용 등과 같은 작업에 대한 보편적인 인터페이스를 제공하여 “N×M 통합” 문제를 해결하고자 합니다. MCP는 특허나 내부용 프로토콜이 아니며, 공식 명세와 오픈소스 참조 구현이 있는 개방형 표준입니다. 실제로, 주요 AI 제공업체(예: OpenAI 및 Google DeepMind)는 MCP 도입 후 MCP를 지원한다고 발표했으며, 이는 MCP가 특정 업체에 의존하는 솔루션이 아니라 널리 채택되는 표준이 되고 있음을 강조합니다.
MCP 목적 및 아키텍처
MCP는 애플리케이션이 LLMs에 맥락을 제공하는 방식을 표준화하는 것을 목표로 합니다. 자주 사용되는 비유는 “AI 애플리케이션용 USB-C 포트”입니다. 공통 프로토콜을 정의함으로써 MCP는 AI 어시스턴트와 도구가 데이터베이스, 파일 시스템, API 및 기타 자원과의 통합을 위해 맞춤형 통합이 필요 없이 원활하게 인터페이스할 수 있도록 합니다. 이는 언어 모델이 필요한 데이터에 보안 있는 접근을 통해 더 관련성 있고 최신 정보를 생성하도록 도와줍니다.
아키텍처: MCP는 클라이언트–서버 모델을 따르며 명확한 역할 분리를 합니다:
- MCP 호스트: 연결을 관리하는 부모 애플리케이션(예: 채팅 클라이언트 또는 IDE)이며, 하나 이상의 MCP 클라이언트(연결자)를 포함합니다.
- MCP 클라이언트: 호스트 내에서 MCP 서버와 1:1 세션을 설정하는 연결자 인스턴스입니다. 클라이언트는 세션의 수명 주기를 관리하고 메시지를 라우팅하며 사용자 권한 또는 보안 정책을 강제합니다.
- MCP 서버: MCP 프로토콜을 통해 특정 기능(특정 데이터 또는 함수에 대한 액세스)을 노출하는 가벼운 서비스입니다. 각 서버는 데이터 소스(파일, DB, API 등) 또는 도구를 감싸고 있을 수 있습니다. 여러 서버가 병렬적으로 실행될 수 있으며, 각 서버는 다른 통합을 제공합니다.
- 데이터 소스/서비스: 서버가 인터페이스하는 실제 자원으로, 로컬 파일 및 데이터베이스 또는 원격 서비스(웹 API, SaaS 앱 등)가 포함될 수 있습니다. MCP 서버는 이러한 자원에 대한 어댑터 역할을 하며, LLM이 표준화된 프로토콜을 통해만 데이터에 액세스하도록 보장합니다.
이 설계는 IDE 세계에서 사용되는 Language Server Protocol(LSP)에서 영감을 받았습니다. LSP가 모든 에디터가 공통 프로토콜을 통해 모든 프로그래밍 언어를 지원할 수 있도록 하듯, MCP는 MCP를 사용하는 모든 데이터/도구 통합에 연결할 수 있는 모든 AI 애플리케이션을 가능하게 합니다. 이 분리된 구조는 AI 도구 개발자가 MCP 서버를 한 번 작성하면 여러 AI 클라이언트와 작동할 수 있도록 하며, AI 애플리케이션 개발자는 MCP 서버를 플러그인하여 새로운 통합을 추가할 수 있도록 하여 맞춤형 통합 코드를 피할 수 있습니다.
프로토콜 및 메시지 구조
통신: MCP 통신은 JSON-RPC 2.0 메시지를 사용하여 지속적이고 상태 있는 세션을 기반으로 합니다. 모든 요청과 응답은 JSON-RPC의 형식에 맞춰야 하며, "jsonrpc": "2.0"
필드, 메서드 이름, 파라미터 및 연관된 ID를 포함해야 합니다. 클라이언트 또는 서버 중 어느 쪽이든 요청 또는 알림을 보낼 수 있어, 양방향 상호작용이 가능합니다. MCP 세션은 일반적으로 핸드셰이크로 시작됩니다:
- 클라이언트는
initialize
요청으로 시작하여 프로토콜 버전을 제안하고 지원하는 기능(예: 서버 주도의 “샘플링” 요청 처리 또는 파일 액세스에 대한 특정 루트 제공)을 광고합니다. 서버는 지원하는 프로토콜 버전과 기능을 응답하여, 이 세션에서 활성화된 기능을 결정합니다(이 기능은 LSP의 선택적 기능과 유사한 기능 협상 시스템을 사용합니다). 만약 중요한 기능 또는 버전이 호환되지 않으면 연결은 부드럽게 종료됩니다. - 합의가 이루어지면 클라이언트는
initialized
알림을 보내 준비가 완료되었음을 표시합니다. 이 후에는 일반적인 작업이 진행됩니다. 세션은 한쪽이 종료 요청을 보내기 전까지 지속적으로 JSON-RPC 메시지를 교환합니다.
전송: MCP는 단일 전송을 강제하지 않으며, JSON 텍스트를 전달할 수 있는 모든 채널에서 작동합니다. 일반적으로 MCP 서버는 서브프로세스로 실행되고, 로컬 통합을 위해 STDIO(stdin/stdout 파이프)를 통해 통신합니다. 이는 언어 서버가 작동하는 방식과 유사하며, 로컬 도구에 편리합니다(호스트는 서버 프로세스를 실행하고 메시지를 파이프할 수 있습니다). 대안적으로, MCP 서버는 HTTP를 통해 접근 가능한 독립 서비스로 실행될 수 있습니다. MCP 명세는 스트리밍 HTTP 전송을 정의하며, 서버는 JSON-RPC 호출을 위한 단일 HTTP 엔드포인트를 노출합니다(클라이언트는 POST 요청을 보내고, 서버는 Server-Sent Events를 통해 장기 실행 작업의 결과를 스트리밍할 수 있습니다). 어떤 경우에도 메시지는 UTF-8 JSON 라인이며, 프로토콜은 스트리밍 응답 및 서버 주도 메시지(예: HTTP+SSE 접근 방식은 서버가 비동기적으로 알림 또는 부분 결과를 푸시할 수 있음)를 지원합니다. 보안 가이드라인은 로컬 서버가 localhost에 바인딩하고 Origin
헤더를 검증하여 원치 않는 원격 액세스를 방지하도록 권장하며, 원격 서버는 적절한 인증(예: 토큰 또는 OAuth 흐름)을 사용해야 합니다.
메시지 형식: MCP는 JSON-RPC의 세 가지 메시지 유형을 활용합니다: 요청, 응답, 알림. 요청은 id
, method
문자열, (선택적으로) params
(일반적으로 인수의 JSON 객체)를 포함합니다. 수신자는 해당 응답(일치하는 id
를 포함)을 보내야 하며, result
또는 error
객체를 포함해야 합니다. 알림은 method
와 params
가 있지만 id
가 없기 때문에 응답을 받지 않습니다. MCP는 기초 JSON-RPC 위에 몇 가지 규칙을 적용합니다(예: id
는 null이 아니어야 하며 세션 중에 재사용되어서는 안 됨)로 명확성을 유지합니다.
세션 및 상태: 연결은 상태 있는 것으로 간주되며, 클라이언트와 서버는 상호 간의 기능 및 가능한 세션 상태(예: 변경 사항에 대한 구독, 진행 중 작업 등)에 대한 맥락을 유지합니다. 또한, 부드러운 종료를 위한 정의된 절차가 있습니다(예: 클라이언트가 종료 요청을 보내거나 단순히 전송을 닫을 수 있음; 서버는 정리 작업을 수행해야 하며, 양측은 헛된 작업에 대한 타임아웃을 구현해야 함). 오류 처리는 JSON-RPC 관례를 따르며(오류 응답에는 코드와 메시지가 있음), 명세는 특정 조건(예: 권한 거부, 도구 찾기 실패 등)에 대한 표준 오류 코드를 정의합니다. MCP는 또한 공통 문제를 위한 유틸리티를 제공합니다: 예를 들어, 진행 상황 업데이트, 장기 실행 요청 취소(CancelledNotification
), 로깅/디버그 메시지, 구성 변경에 대한 내장 알림이 있습니다. 이는 긴 또는 복잡한 상호작용을 관리하는 데 도움이 됩니다(예: 클라이언트는 진행 중인 도구 호출을 취소하거나, 서버는 클라이언트에 경고를 로깅할 수 있음 등).
MCP 기능 및 운영
초기화가 완료되면 MCP 세션은 맥락과 명령의 구조화된 교환을 가능하게 합니다. MCP의 핵심 서버 측 기능은 프롬프트, 리소스, 도구입니다(서버는 초기화 중에 지원 여부를 선언합니다):
-
프롬프트: 서버가 클라이언트에 제공할 수 있는 사전 정의된 프롬프트 템플릿 또는 지시문입니다. 이들은 일반적으로 사용자 주도 도움말(예: 사용자가 UI에서 슬래시 명령을 통해 명시적으로 프롬프트를 삽입)입니다. MCP는 사용 가능한 프롬프트 목록을 열거하고 프롬프트의 내용을 검색하는 방법을 제공합니다. 예를 들어, 클라이언트는
prompts/list
를 호출하여 프롬프트 템플릿 목록(각각 이름, 설명, 선택적 파라미터)을 얻을 수 있습니다. 특정 프롬프트를 가져오려면 클라이언트는prompts/get
을 사용하여 프롬프트의 이름과 파라미터 값을 전달하고, 서버는 프롬프트 내용(일반적으로 클라이언트가 LLM의 맥락에 삽입할 메시지 집합)을 반환합니다. 프롬프트는 복잡한 지시문 또는 워크플로우(예: “코드 리뷰 템플릿”)를 재사용할 수 있도록 합니다. 서버는prompts
기능(선택적으로listChanged
와 같은 하위 기능으로 프롬프트 세트가 동적으로 변경될 경우 클라이언트를 통지)을 표시합니다. -
리소스: 모델에 맥락을 제공하는 구조화된 데이터 또는 콘텐츠입니다. 리소스는 일반적으로 파일, 문서, 데이터베이스 항목과 같은 정보로, AI 어시스턴트가 읽거나 참조할 수 있는 것입니다. MCP는 리소스가 어떻게 식별되고 전송되는지 표준화합니다: 각 리소스는 URI 식별자(예:
file:///path/to/file.txt
또는 데이터베이스를 위한 커스텀 스키마)를 가집니다. 클라이언트는resources/list
를 통해 사용 가능한 리소스를 쿼리할 수 있습니다(서버는 디렉토리 트리, 최근 문서 목록 등 노출할 수 있습니다). 서버의 응답에는 각 리소스(URI, 이름, 유형, 설명 등)에 대한 메타데이터가 포함됩니다. 그런 다음 클라이언트는resources/read
를 사용하여 특정 리소스의 콘텐츠를 요청할 수 있으며, URI를 전달합니다. 서버는 리소스 콘텐츠를 응답으로 반환합니다(일반적으로 텍스트이지만, MCP는 텍스트, JSON, 이진 등 다양한 콘텐츠 유형을 지원하며 MIME 유형을 사용합니다). 또한, 리소스 템플릿(파라미터화된 리소스로, 클라이언트가 채울 수 있는 템플릿 URI, 예: 사용자가 파라미터를 제공하는 데이터베이스 쿼리)에 대한 지원도 있습니다. 활성화된 경우, 서버는 리소스가 변경될 때 알림을 보낼 수 있습니다(예:notifications/resources/updated
) 또는 클라이언트가 리소스 변경을 구독할 수 있도록 합니다(resources/subscribe
). MCP의 설계에서 리소스는 애플리케이션 제어 맥락입니다: 호스트 애플리케이션(클라이언트)이 일반적으로 모델의 프롬프트에 실제로 제공할 리소스 콘텐츠를 결정합니다(보통 사용자 확인 또는 UI 맥락에 따라). -
도구: 모델이 실행할 수 있는 실행 가능한 함수 또는 작업입니다. 도구는 AI가 수행할 수 있는 작업(예: 외부 API 호출, 데이터베이스 쿼리 실행, 이메일 전송, 파일 수정)을 나타냅니다. 각 도구는 이름과 입력(및 선택적 출력) 파라미터의 JSON 스키마를 가지므로, AI(또는 클라이언트)는 기대하는 인수를 알 수 있습니다. 도구는 일반적으로 모델 제어입니다: 아이디어는 언어 모델(에이전트)이 대화 중에 사용자 요청을 충족하기 위해 언제 사용할지 결정하는 것입니다. 그러나 안전을 위해, 인간 사용자 또는 호스트 앱이 도구 사용을 중재할 수 있습니다(예: 확인 클릭이 필요함). MCP에서 도구 사용은 두 가지 주요 작업을 포함합니다: 목록 및 호출. 클라이언트는
tools/list
를 호출하여 사용 가능한 도구와 스키마를 얻을 수 있습니다. 예를 들어, 서버는get_weather
라는 도구를 목록에 포함할 수 있으며, 설명과 “location” 문자열이 필요한 입력 스키마를 제공할 수 있습니다. 그런 다음 모델이 도구를 사용하기로 결정하거나 사용자가 호출할 경우, 클라이언트는 도구의 이름과 인수의 JSON 객체를 포함한tools/call
요청을 보냅니다. 서버는 함수를 실행하고 결과를 반환합니다(일반적으로result.content
필드로, 텍스트 또는 구조화된 데이터가 포함될 수 있음, MCP는 여러 콘텐츠 부분(예: 텍스트와 이미지 등)을 지원하지만 텍스트가 일반적입니다). 간단한 예:get_weather
도구를 호출하면 “뉴욕의 현재 날씨: 72°F, 부분적으로 흐림"과 같은 텍스트 페이로드가 어시스턴트가 제시할 내용으로 반환될 수 있습니다. 도구는 또한 오류를 표시할 수 있습니다(응답에는isError
플래그 또는 문제가 발생한 경우 오브젝트가 포함됨). 프롬프트와 리소스와 마찬가지로,tools
기능에는 사용 가능한 도구가 런타임에서 변경될 경우 통지할 수 있는 선택적listChanged
플래그가 포함될 수 있습니다(예: 동적 플러그인의 로드/언로드).
이상의 서버 제공 기능 외에도, MCP는 클라이언트 제공 기능(서버가 클라이언트가 지원하는 경우 활용할 수 있는 기능)도 정의합니다. 이는 샘플링, 루트, 유도를 포함합니다:
-
샘플링은 서버가 클라이언트(및 그 LLM)에게 세션 내에서 모델 추론을 수행하도록 요청할 수 있도록 합니다. 예를 들어, 서버는
sampling/request
와 같은 요청을 보내어 LLM 호출을 시작할 수 있습니다(예: 사고 체인을 계속하거나 요약하는 것), 클라이언트는 모델을 프롬프트하고 결과를 반환합니다. 이는 에이전트 행동을 가능하게 하며, 서버가 AI를 자신의 하위 작업에 도움을 줄 수 있도록 합니다. (모든 이러한 행동은 사용자 승인과 정책에 따라 이루어집니다 - 예: 사용자가 서버가 모델을 추가 쿼리에 대해 트리거하도록 허용해야 할 수 있습니다.) -
루트는 서버가 특정 허용된 파일 시스템 또는 URI 루트 내에서 조사하거나 운영하도록 허용합니다. 클라이언트는 서버가 액세스할 수 있는 “루트” 디렉토리/URI 목록을
roots/list
를 통해 제공할 수 있습니다. 이는 서버가 경계를 알고 있는 보안 기능입니다(예: 읽을 수 있는 폴더 트리). -
유도는 서버가 필요할 경우 클라이언트에게 사용자로부터 추가 정보를 얻도록 요청할 수 있도록 합니다. 예를 들어, 도구가 제공되지 않은 정보가 필요할 경우, 서버는 유도 요청을 보내고, 클라이언트(UX)는 사용자에게 프롬프트(“X 통합은 API 키가 필요합니다. 입력해 주세요”)로 변환합니다. 이로 인해 서버는 클라이언트를 통해 입력을 상호적으로 수집할 수 있습니다.
이러한 기능은 모두 선택적이며, 초기화 시점에 협상됩니다. MCP의 주요 설계 요소 중 하나는 기능 협상이 초기화 중에 이루어진다는 것입니다. 클라이언트와 서버는 위 기능 중 어떤 것을 지원하는지 광고하므로, 양측 모두 세션에서 사용 가능한 작업을 알고 있습니다. 예를 들어, 서버가 tools
기능을 선언하지 않으면, 클라이언트는 해당 서버와 tools/list
또는 tools/call
작업을 시도하지 않습니다. 이 확장성은 MCP가 시간이 지남에 따라 새로운 기능을 추가하면서도 후방 호환성을 유지할 수 있도록 합니다(지원되지 않은 메서드는 협상되지 않으면 사용되지 않습니다).
구현, SDK 및 MCP 서버 구축(특히 Go에서)
공식 명세 및 문서: 공식 MCP 명세는 공개되어 있으며, 모든 메시지 유형의 공식 스키마가 포함되어 있습니다. 이는 Model Context Protocol 웹사이트와 GitHub에서 유지됩니다. 명세는 TypeScript 스키마 파일(대응하는 JSON 스키마 포함)로 정의되어 있으며, 모든 요청, 응답 및 구조를 정확히 문서화합니다. 문서 사이트(modelcontextprotocol.io)는 가이드, FAQ, 각 기능 및 메시지 유형의 상세한 분석, 그리고 상호작용 디버깅을 위한 “MCP Inspector” 도구를 제공합니다. MCP는 아직 IETF 또는 ISO 표준이 아니지만, 커뮤니티의 입력을 받으며, 요구사항에 대해 익숙한 RFC 2119 용어를 사용하는 개방형 표준으로 개발되고 있습니다. 이는 진화하는 프로토콜이며, 버전은 날짜로 표시됩니다(예: 2025-06-18은 최근 수정입니다), 변경을 관리하는 버전 정책이 있습니다.
참조 구현: Anthropic은 MCP를 도입하면서 여러 MCP 서버 커넥터 및 SDK를 오픈소스로 제공했습니다. **modelcontextprotocol
**이라는 GitHub 조직은 명세 및 여러 저장소를 호스팅합니다. 특히, “servers” 저장소에는 일반 서비스 및 데이터 소스에 대한 사전 구축된 MCP 서버 구현이 포함되어 있습니다. 이들은 참조 통합으로 작동하며, 일반적으로 즉시 사용하거나 커스텀 서버를 위한 템플릿으로 사용할 수 있습니다. 예를 들어, 공식 저장소에는 Google Drive(Google Drive 파일 액세스 및 검색), Slack(워크스페이스 메시징 및 채널 콘텐츠), GitHub/Git(코드 저장소 맥락), PostgreSQL(읽기 전용 데이터베이스 쿼리 및 스키마 정보), Google Maps(위치 및 경로 API), Puppeteer(웹 브라우징 및 스크래핑), 등이 포함됩니다. 이러한 서버를 설치하거나 실행함으로써 Claude 또는 Cursor와 같은 AI 애플리케이션은 즉시 해당 통합을 얻을 수 있습니다. 또한, 커뮤니티 주도의 MCP 등록 서비스(Go로 작성된 오픈소스)가 제공되며, 많은 제3자 기여가 MCP를 다양한 분야(예: CRM에서 블록체인 데이터)로 확장하고 있습니다.
SDK 및 라이브러리: 자신의 MCP 서버/클라이언트를 구축하기 위해 여러 언어의 공식 SDK가 제공됩니다. 2025년 현재, 프로젝트는 TypeScript/Node, Python, Java(및 Kotlin), C#(Microsoft와 협력하여 개발됨), Ruby(Shopify와 협력하여 개발됨), Swift, 등에 대한 SDK를 제공합니다. 이러한 라이브러리는 프로토콜의 구현을 처리합니다 – 예를 들어, JSON-RPC 전송을 관리하거나, 명세 스키마를 구현하거나, 도구 등록 또는 리소스 제공을 위한 도움말 API를 제공합니다. 예를 들어, TypeScript SDK는 Node.js에서 서버를 빠르게 작성할 수 있도록 하며, Python SDK는 Python 애플리케이션에서 MCP를 통합할 수 있도록 합니다. SDK 접근 방식은 개발자가 JSON-RPC 메시지를 수동으로 구성하거나 전체 상태 머신을 구현할 필요 없이, 고수준 메서드를 호출하여 요청을 보내거나 기능을 게시할 수 있도록 합니다.
Go 구현: Go는 MCP 서버에 대한 인기 있는 선택이 되고 있으며, 그 성능과 동시성 강점을 고려할 때(다중 동시 요청 처리에 적합). 공식 Go SDK는 Google의 Go 팀과 협력하여 제공되고 있습니다. (이것은 2025년 4월경 발표되었으며, 첫 안정 버전은 2025년 8월에 예정되어 있습니다.) Go SDK는 클라이언트/서버를 구축하기 위한 mcp
패키지와 도구 스키마를 위한 jsonschema
도움말을 제공합니다. Go SDK를 사용하여 개발자는 몇 번의 호출만으로 MCP 서버를 생성할 수 있습니다. 예를 들어, 이름과 버전을 지정하여 새 서버를 인스턴스화하고, AddTool
을 통해 도구를 추가할 수 있습니다. 이는 도구 정의(이름, 설명, 입력 스키마)와 함께 Go 핸들러 함수를 제공하여 해당 도구가 호출될 때 실행되도록 합니다. SDK는 프로토콜에서 도구를 노출하도록 처리합니다(예: tools/list
에서 광고하고 tools/call
요청을 처리함). 마찬가지로, 리소스 또는 프롬프트를 노출할 수 있는 유사한 API를 사용할 수 있습니다. 마지막으로, 서버를 실행합니다 – 예를 들어, server.Run(ctx, mcp.NewStdioTransport())
은 클라이언트가 연결을 끊을 때까지 stdio를 통해 JSON-RPC 메시지를 처리하도록 시작합니다. 클라이언트 측에서는 Go SDK가 서브프로세스를 생성하고 mcp.NewCommandTransport(exec.Command("myserver"))
를 통해 연결할 수 있으며, 클라이언트는 session.CallTool(ctx, params)
를 호출하여 도구를 실행하고 Go 코드에서 결과를 쉽게 얻을 수 있습니다.
예시: 공식 Go SDK 문서는 간단한 “인사” 서버를 보여줍니다. 서버는 이름을 입력하고 인사문자열을 반환하는
"greet"
도구를 등록합니다. 클라이언트는 이 도구의 이름을 사용하여 호출하고 결과를 인쇄합니다. 이는 기본 패턴을 보여줍니다: 도구 정의 -> 클라이언트가 도구 호출 -> 결과 얻기. 내부적으로, 이는 MCP 명세에 따라 정의된 JSON-RPC 메시지("method": "tools/call", params: {"name": "greet", ...}
및 응답에result.content
에 텍스트가 포함됨)에 해당합니다.
공식 Go SDK가 발표되기 전에 커뮤니티는 자체 Go 라이브러리를 만들었습니다. 특히, Ed Zynda의 mcp-go
프로젝트(mark3labs/mcp-go)는 널리 사용되었으며 공식 SDK의 설계에 영향을 주었습니다. 또 다른 라이브러리인 **mcp-golang
**은 Metoro에서 제공하며 Go 구현 및 API를 제공합니다(Elton Minetto의 Dev 커뮤니티 블로그 게시물은 2025년 초반에 이 라이브러리를 사용하고 있습니다). 이러한 커뮤니티 SDK는 Go 개발자가 MCP를 조기에 실험할 수 있도록 했습니다 – 예를 들어, 한 튜토리얼은 Metoro의 mcp-golang
라이브러리를 사용하여 브라질 우편번호(CEP)를 조회하는 MCP 서버를 구축하는 방법을 보여줍니다. 그 예시에서 Go 서버는 외부 API를 호출하여 ZIP 코드로 주소를 찾는 함수를 등록하고, 결과를 텍스트로 반환하여 AI 어시스턴트가 MCP를 통해 즉시 주소 정보를 가져올 수 있도록 합니다. 또 다른 가이드는 mark3labs의 mcp-go
SDK를 사용하여 커스텀 인메모리 데이터베이스(DiceDB)를 MCP 서버로 래핑하는 방법을 보여줍니다: ping
도구를 정의하여 DB 연결성을 확인하고, 데이터 작업을 위한 다른 도구를 정의합니다. 이러한 예시들은 MCP 통합을 생성하는 것이 얼마나 간단할 수 있는지를 보여줍니다: 대부분의 코드는 비즈니스 로직(API 호출, DB 쿼리 등)이며, SDK는 JSON-RPC 연결을 처리합니다.
Go로 MCP 서버 구축 (튜토리얼 요약)
프로세스를 개요로 설명하자면, Go SDK나 유사한 라이브러리를 사용하여 일반적인 흐름은 다음과 같습니다:
-
서버 설정: 기본 정보(이름, 버전, 지원하는 기능)로 새로운 서버 인스턴스를 초기화합니다. 예를 들어, Go에서
server := mcp.NewServer("MyServer", "1.0.0", nil)
을 사용하면 (기본적으로) 핵심 프로토콜 기능을 지원하는 서버가 생성됩니다. 특정 기능(프롬프트/리소스/도구)을 활성화하려면 옵션을 통해 설정하거나 해당 기능을 등록(도구나 리소스를 추가하는 것은 해당 기능을 지원함을 의미함)할 수 있습니다. -
기능 등록: 노출하고자 하는 기능을 추가합니다:
- 도구를 노출하는 경우, 각 도구의 스키마와 핸들러를 정의해야 합니다. 예를 들어, Go SDK의
AddTool
을 사용하여mcp.Tool{Name: "...", Description: "..."}
와 요청을 받아 결과를 반환하는 핸들러 함수를 제공할 수 있습니다(결과에는 텍스트나 다른 콘텐츠가 포함될 수 있음). SDK는 핸들러의 파라미터 타입에 따라 입력에 대한 JSON 스키마를 자동으로 생성하거나 직접 지정할 수도 있습니다. - 리소스를 노출하는 경우, 리소스 목록을 등록하는 API나 콘텐츠를 읽는 콜백을 사용할 수 있습니다. 예를 들어, Python SDK에서는
ResourceProvider
를 상속받을 수 있지만, Go SDK는 아직 발전 중이므로 일반적으로 리소스를 나열하고 읽는 함수를 제공해야 합니다. 각 리소스는 안정적인 URI를 가져야 합니다. - 프롬프트를 노출하는 경우, 프롬프트 템플릿(정적 파일이나 문자열)을 정의하고 이름과 선택적 파라미터와 함께 등록해야 합니다. 서버는 이를 클라이언트가 사용자에게 표시할 수 있도록 노출합니다.
- 도구를 노출하는 경우, 각 도구의 스키마와 핸들러를 정의해야 합니다. 예를 들어, Go SDK의
-
전송 구현: 서버가 어떻게 실행될지를 결정합니다. 로컬 사용에 가장 간단한 방법은 stdio입니다. 예를 들어, Go에서
server.Run(ctx, mcp.NewStdioTransport())
을 사용하면 표준 입력에서 JSON-RPC를 읽기 시작합니다. 네트워크를 통해 실행하려면 HTTP 핸들러를 구현하여 Go SDK를 통해 HTTP를 통해 JSON-RPC를 수신하는 방식을 사용할 수 있습니다(공식 Go SDK는 HTTP/SSE 전송을 위한 도움말 기능도 곧 포함될 예정입니다). -
클라이언트 테스트: MCP 호환 클라이언트를 사용하여 서버를 테스트할 수 있습니다. 예를 들어, Anthropic의 Claude 2(Claude for Desktop)는 로컬 MCP 서버를 로딩하는 것을 지원합니다. Claude를 설정하여 서버 바이너리 실행 또는 연결하도록 구성할 수 있습니다. 또한,
mcp-cli
명령줄 도구와 MCP Inspector GUI는 전체 AI 클라이언트 없이도 서버를 테스트할 수 있는 도구로, 이 도구들은 서버에 MCP 요청을 보내고 결과를 표시하여 디버깅에 도움을 줍니다. -
보안 및 권한: 서버를 구축할 때 인증과 범위 설정을 고려해야 합니다. 로컬 서버의 경우 호스트가 특정 OS 권한으로 실행하거나 환경 변수를 통해 API 키를 제공할 수 있습니다. 원격 서버의 경우 인증 헤더나 OAuth 흐름을 사용해야 합니다. MCP는 HTTP 전송에 대한 인증 명세를 포함하고 있습니다(서버는 토큰을 요구할 수 있고, 클라이언트는 이를 전송할 수 있음). 항상 서버가 사용자가 허용한 데이터만 접근하도록 해야 합니다(예: 클라이언트가 제공한 루트 디렉토리만 존중하고, 다른 곳으로 데이터가 유출되지 않도록 함). MCP 가이드라인은 사용자 동의, 데이터 프라이버시, 도구 안전성을 기본 원칙으로 강조합니다.
요약하자면, MCP는 LLM과 외부 세계를 연결하는 공식적이면서 유연한 프로토콜입니다. 이는 어떤 회사에 종속된 내부 API가 아니라 개방 표준이며, 점점 더 많은 도입과 풍부한 통합 생태계를 갖추고 있습니다. 프로토콜은 명확한 메시지 구조(JSON-RPC 기반)와 명령어 집합(프롬프트, 도구, 리소스 등에 대한 메서드)을 정의하여, 모든 호환되는 클라이언트/서버가 이를 구현할 수 있도록 합니다. 공식 문서와 명세가 제공되고 있으며, 다양한 SDK, 라이브러리, 예제 서버(포함 Go)가 존재하여 구현을 더 쉽게 합니다. MCP를 사용함으로써 개발자는 기존 데이터와 서비스를 안전하게 활용하면서, 각 새로운 모델이나 데이터셋마다 통합 논리를 다시 구현할 필요 없이 AI 기반 애플리케이션을 구축할 수 있습니다.
유용한 링크
- https://www.anthropic.com/news/model-context-protocol
- https://modelcontextprotocol.io/introduction
- https://github.com/modelcontextprotocol/go-sdk - Model Context Protocol 서버 및 클라이언트를 위한 공식 Go SDK. Google과 협력하여 유지 관리됩니다.