Model Context Protocol (MCP)란 무엇인가?
요약
Model Context Protocol(MCP)은 LLM을 다양한 데이터 소스 및 도구와 연결하기 위한 개방형 표준 프로토콜입니다. 기존의 복잡한 맞춤형 통합 방식(N x M)을 단순한 서버-클라이언트 구조(N + M)로 혁신하여 모델과 데이터 간의 상호운용성을 극대화합니다.
핵심 포인트
- LLM과 데이터 소스 간의 일관된 인터페이스 제공
- N x M의 통합 비용을 N + M으로 획기적으로 감소
- 호스트, 클라이언트, 서버로 구분된 명확한 아키텍처
- stdio 및 SSE(HTTP)를 통한 유연한 전송 방식 지원
Model Context Protocol (MCP)는 언어 모델(Language Models)을 하나의 일관된 인터페이스를 통해 도구 및 데이터와 연결하기 위한 개방형 표준입니다. 이를 통해 한 번 작성한 통합 코드가 서로 다른 모델과 호스트 애플리케이션(Host Applications) 전반에서 계속 작동할 수 있습니다.
LLM을 실제 시스템에 연결할 때마다 여러분은 똑같은 벽에 부딪힙니다. 모델은 여러분의 데이터에 대해 추론할 수는 있지만, 그 데이터에 직접 접근할 수는 없습니다. 여러분의 Postgres 행(Rows), 티켓팅 시스템, 혹은 정답이 실제로 의존하고 있는 디스크 상의 파일 같은 것들 말입니다. 그래서 여러분은 '글루(Glue, 접착제)' 코드를 작성합니다. 여기에는 함수를 하나 만들고, 저기에는 JSON 스키마(JSON Schema)를 만들고, 각 모델 벤더(Model Vendor)를 위한 맞춤형 어댑터(Bespoke Adapter)를 만듭니다. 그러다 새로운 모델이 출시되거나 새로운 데이터 소스(Data Source)가 나타나면, 여러분은 그 글루 코드를 다시 작성해야 합니다.
MCP는 바로 그 반복되는 루프를 멈추기 위해 존재합니다.
MCP는 실제로 어떤 문제를 해결하나요?
MCP 이전에는 "모델에게 X에 대한 접근 권한을 부여하라"는 작업이 N x M만큼의 작업량을 요구했습니다. N개의 모델과 M개의 데이터 소스가 있다면, 모든 쌍에 대해 커스텀 브리지(Custom Bridge)를 만들어야 했습니다. 각 브리지는 자신만의 인증(Auth) 방식, 도구가 무엇을 하는지 설명하는 방식, 그리고 자신만의 에러 핸들링(Error Handling) 방식을 가지고 있었습니다.
MCP는 이를 N + M으로 축소합니다. 여러분은 데이터 소스를 노출하는 단 하나의 MCP 서버(MCP Server)를 작성하면 됩니다. MCP 기능이 있는 클라이언트(Client)라면 무엇이든 이 서버와 통신할 수 있습니다. 모델을 교체하더라도 서버는 그대로 유지됩니다. 두 번째 앱을 추가하더라도 동일한 서버를 가리키기만 하면 됩니다. 프로토콜(Protocol)은 중간에서의 계약(Contract) 역할을 하며, 양측은 오직 그 계약의 언어만 사용하면 됩니다.
만약 Language Server Protocol (LSP)을 사용해 본 적이 있다면, 그 형태가 익숙할 것입니다. LSP는 모든 에디터(Editor)가 모든 언어에 대한 지원을 매번 새로 구현하는 대신, 하나의 언어 서버(Language Server)가 여러 에디터에 서비스를 제공할 수 있게 했습니다. MCP는 모델 컨텍스트(Model Context)에 대해 동일한 방식을 적용합니다.
MCP의 클라이언트/서버 모델 작동 방식
MCP에는 명확히 구분해야 할 세 가지 역할이 있습니다.
호스트(Host)는 사용자가 상호작용하는 애플리케이션입니다. 데스크톱 어시스턴트, IDE 플러그인, 채팅 UI, 또는 여러분이 직접 만든 에이전트(Agent)가 될 수 있습니다.
클라이언트(Client)는 호스트 내부에 존재하며, 하나의 서버에 대한 하나의 연결을 관리합니다. 만약 호스트가 네 개의 서버와 통신한다면, 네 개의 클라이언트를 실행하게 됩니다.
서버는 기능을 노출하기 위해 당신이 작성하는 작은 프로그램입니다. GitHub 서버, 파일 시스템 (filesystem) 서버, 기업 데이터베이스 (company-database) 서버 등이 이에 해당합니다. 서버는 반대편에 어떤 모델이 있는지 추적하지 않습니다. 서버는 프로토콜 메시지에 응답할 뿐이며, 호스트가 어떤 LLM (Large Language Model)을 구동하든 동일한 서버가 작동합니다.
전송 (Transport) 방식은 로컬 도구에 적합한 stdio (호스트가 서버를 서브프로세스로 실행하고 stdin/stdout을 통해 통신하는 방식) 또는 원격 서버를 위한 서버 전송 이벤트 (Server-Sent Events, SSE)를 사용하는 HTTP 방식 중 하나입니다. 두 경우 모두 메시지는 JSON-RPC 2.0 형식을 사용합니다.
중요한 속성: 서버는 자신이 무엇을 할 수 있는지 선언하며, 호스트는 연결 시점에 이러한 기능들을 발견 (discovery)합니다. 모델 측에는 아무것도 하드코딩되어 있지 않습니다.
MCP vs Raw Function Calling (원시 함수 호출)
함수 호출 (Function calling)은 모델의 기능입니다. 모델은 당신이 전달한 스키마 (schema)에 따라 구조화된 호출을 생성할 수 있습니다. MCP는 이 기능을 중심으로 구축된 전송, 발견 및 재사용 레이어이므로, 재연결(rewiring) 없이도 동일한 기능이 여러 호스트에서 작동합니다.
| 고려 사항 | Raw Function Calling | MCP |
|---|---|---|
| 도구 정의 위치 | 앱 코드 내, 모델 벤더별로 정의 | 독립된 서버에 한 번만 정의 |
| 앱 간 재사용 | 각 앱에 코드를 복사 | 각 앱을 동일한 서버로 지정 |
| 발견 (Discovery) | 도구 목록을 하드코딩 | 호스트가 연결 시점에 도구 목록을 나열 |
| 격리 (Isolation) | 앱 프로세스 내에서 실행 | 서버가 자체 권한을 가진 별도 프로세스로 실행 |
| 전송 (Transport) | 벤더 SDK 특정 방식 | stdio 또는 HTTP/SSE를 통한 JSON-RPC |
| 동작 그 이상 | 도구만 지원 | 도구 (Tools), 리소스 (Resources), 프롬프트 (Prompts) 지원 |
MCP 서버는 세 가지 종류의 요소를 노출하며, 서버를 설계할 때 각 요소는 고유한 역할을 수행합니다.
도구 (Tools): 모델이 호출할 수 있는 동작
도구는 모델이 호출할 수 있는 동작입니다. create_issue, run_query, send_email 등이 있습니다. 이들은 부수 효과 (side effects)를 가질 수 있습니다. 각 도구는 이름, 설명, 그리고 입력값에 대한 JSON Schema를 함께 제공합니다. 모델은 해당 스키마를 읽고 언제 어떻게 호출할지를 결정합니다.
도구 정의는 대략 다음과 같은 형태를 가집니다:
{
"name": "search_orders",
"description": "고객 이메일 또는 주문 ID로 주문을 찾습니다.",
"inputSchema": {
"type": "object",
"properties": {
"email": { "type": "string" },
"order_id": { "type": "string" }
}
}
}
모델은 귀하의 데이터베이스에 직접 접근하지 않습니다. 모델은 구조화된 호출 (structured call)을 생성하고, 호스트 (host)가 이를 귀하의 서버로 전달하면, 귀하의 서버가 실제 쿼리 (query)를 실행하고 결과를 반환합니다.
Resources: 모델이 읽을 수 있는 데이터
Resources는 모델이 읽을 수 있는 데이터입니다. URI로 주소가 지정된 파일, 데이터베이스 레코드, API 응답 등이 이에 해당합니다. file:///logs/today.txt 또는 db://customers/4821과 같은 형태를 생각하면 됩니다. Resources는 읽기 전용 컨텍스트 (read-only context)를 목적으로 하며, POST보다는 GET에 더 가깝습니다. 호스트는 이를 인라인 (inline)으로 포함할지 또는 사용자가 선택하게 할지 등 어떻게 노출할지를 결정합니다.
Prompts: 재사용 가능한 상호작용 템플릿
Prompts는 서버가 제공하는 재사용 가능한 템플릿으로, 종종 호스트에서 슬래시 명령어 (slash commands)나 메뉴 항목으로 나타납니다. "이 사건을 요약해줘", "이 diff를 검토해줘"와 같은 예가 있습니다. Prompts를 통해 서버는 모든 사용자가 문구를 새로 만들 필요 없이, 이미 검증된 상호작용 패턴을 제공할 수 있습니다.
이러한 구분은 실용적입니다. Tools는 부수 효과 (side effects)를 동반하는 동작을 수행하고, Resources는 읽기 전용 컨텍스트를 제공하며, Prompts는 정해진 상호작용을 제공합니다. 서버를 설계할 때 각 기능을 적절한 범주에 분류하면, 호스트는 각 기능이 의도된 방식대로 렌더링할 수 있습니다.
직접 실행해 볼 수 있는 최소 기능의 MCP 서버
복사하여 실행하고 연결할 수 있는 전체 서버 코드가 여기 있습니다. 이 코드는 공식 Python SDK를 사용하며, SDK가 JSON-RPC 파이프라인 (plumbing)을 처리하므로 귀하는 도구의 본문 (tool body)만 작성하면 됩니다.
먼저 SDK를 설치하세요:
pip install "mcp[cli]"
그 다음, 이 내용을 server.py로 저장하세요:
from mcp.server.fastmcp import FastMCP
server = FastMCP("notes")
# 실제 데이터 소스를 대신하는 예시 데이터
NOTES = [
"현재로서는 캐싱 레이어를 Redis에 유지하기로 결정했습니다.",
"Postgres 업그레이드는 런칭 프리즈 (launch freeze) 이후로 예정되어 있습니다.",
"속도 제한 (rate limiting)은 게이트웨이가 아닌 인증 서비스 (Auth service)가 담당합니다.",
]
@server.tool()
def search_notes(query: str) -> list[str]:
"""쿼리에 일치하는 노트 스니펫 (snippets)을 반환합니다."""
q = query.lower()
return [n for n in NOTES if q in n.lower()][:5]
if name == "main":
# stdio를 통해 실행됩니다; 호스트(host)가 이 파일을 서브프로세스 (subprocess)로 실행합니다.
server.run()
정상적으로 시작되는지 로컬에서 실행하여 확인하세요:
bash
python server.py
이것이 통합 인터페이스 (integration surface)의 전부입니다. 연결 시점에 호스트는 서버에 도구 (tools) 목록을 요청하고, search_notes와 그 스키마 (schema)를 확인한 뒤, 해당 설명을 모델 (model)에게 전달합니다. 사용자가 "캐싱 레이어 (caching layer)에 대해 무엇을 결정했지?"라고 물으면, 모델은 search_notes("caching layer")를 호출하고, 귀하의 함수가 실행되어 스니펫이 반환되면, 모델은 실제 노트를 근거로 답변합니다.
귀하는 모델 벤더의 SDK를 건드리지 않았습니다. 모델의 출력 형식 (output format)을 위한 파서 (parser)를 작성하지도 않았습니다. 귀하는 기능 (capability)을 기술했고, 프로토콜 (protocol)이 이를 전달하게 했을 뿐입니다.
이것이 귀하의 통합 (integrations)에 중요한 이유
세 가지 실질적인 이점이 있습니다.
재사용성 (Reuse). IDE 어시스턴트를 위해 작성한 서버는 변경 없이 CI 봇과 고객 지원 에이전트에서도 그대로 작동합니다.
격리성 (Isolation). 서버는 자체 권한을 가진 별도의 프로세스 (processes)로 실행됩니다. 파일 시스템 (filesystem) 서버에 정확히 하나의 디렉토리에 대한 접근 권한만 부여하고 다른 것은 허용하지 않을 수 있습니다. 모델의 도달 범위는 각 서버가 노출하기로 선택한 범위로 제한됩니다.
조립성 (Composability). 호스트는 여러 서버에 동시에 연결할 수 있으며, 모델은 병합된 도구 세트 (toolset)를 보게 됩니다. 파일 시스템, GitHub, 그리고 귀하의 데이터베이스가 모두 동적으로 발견되며, 유지 관리해야 할 중앙 레지스트리 (central registry)는 없습니다.
비용이 발생하는 부분은 이제 프로토콜 경계 (protocol boundary) 관점에서 생각해야 한다는 점입니다. 모델이 도구 설명을 문서처럼 읽기 때문에, 도구 설명은 제품의 표면 (product surface)의 일부가 됩니다. 모호한 설명은 모호한 도구 사용을 초래하므로, 명확한 도구 계약 (tool contracts)을 작성하고 모델이 실제로 이를 어떻게 호출하는지 테스트하는 것이 진정한 기술입니다. 가이드가 있는 실습을 통해 이 기술을 쌓고 싶다면, AGINE Academy는 각 레슨이 귀하가 소유할 수 있는 작동하는 결과물로 끝나도록 구조화되어 있습니다.
미니 FAQ (Mini-FAQ)
MCP를 한 문장으로 정의하면 무엇인가요?
하나의 표준 인터페이스를 통해 언어 모델 (Language Models)이 도구 (Tools)를 호출하고 데이터를 읽을 수 있게 해주는 개방형 프로토콜로, 단 한 번의 통합만으로 여러 모델과 호스트 (Hosts)에서 작동할 수 있습니다.
MCP는 함수 호출 (Function Calling)과 어떻게 다른가요?
함수 호출 (Function Calling)은 구조화된 호출을 생성하는 모델 측의 능력입니다. MCP는 이를 전송 계층 (Transport), 탐색 (Discovery) 단계, 그리고 재사용 경계 (Reuse boundary)로 감싸서, 도구가 독립적인 서버에 존재하게 하며 특정 벤더 전용의 접착 코드 (Glue code) 없이도 규격을 준수하는 모든 호스트가 이를 사용할 수 있게 합니다. 만약 단 하나의 스크립트에서 단 하나의 API만 호출한다면 일반적인 함수 호출 (Function Calling)만으로 충분합니다. 하지만 동일한 도구를 여러 호스트 간에 공유하거나 프로세스 격리 (Process isolation)를 원하는 경우 MCP가 그 가치를 증명합니다.
MCP의 도구 (Tools), 리소스 (Resources), 프롬프트 (Prompts)의 차이는 무엇인가요?
도구 (Tools)는 부수 효과 (Side effects)를 가질 수 있는 동작과 입력 스키마 (Input schema)를 가집니다. 리소스 (Resources)는 URI로 주소가 지정되는 읽기 전용 데이터로, GET 요청에 더 가깝습니다. 프롬프트 (Prompts)는 서버가 호스트에게 제공하는 재사용 가능한 상호작용 템플릿입니다. 도구 (Tools)는 실행하고, 리소스 (Resources)는 정보를 제공하며, 프롬프트 (Prompts)는 가이드를 제공합니다.
MCP는 어떤 전송 방식 (Transports)을 지원하나요 (stdio vs HTTP/SSE)?
두 가지를 지원합니다. stdio를 사용하면 호스트가 서버를 서브프로세스 (Subprocess)로 실행하고 stdin/stdout을 통해 통신하며, 이는 로컬 도구에 적합합니다. HTTP와 서버 전송 이벤트 (Server-sent events, SSE)를 사용하면 서버가 원격에서 실행됩니다. 두 방식 모두 JSON-RPC 2.0 메시지를 전달하므로, 전송 방식이 바뀌어도 도구 코드를 변경할 필요가 없습니다.
MCP는 특정 모델 벤더에 종속되어 있나요?
아니요. 이는 개방형 프로토콜입니다. 이를 구현하는 모든 호스트와 모든 모델이 참여할 수 있습니다.
서버를 작성하기 어렵나요?
위에서 보여준 것처럼 최소한의 서버는 수십 줄 정도로 작성할 수 있습니다. Python 및 TypeScript용 공식 SDK가 JSON-RPC의 복잡한 구현 (Plumbing)을 처리하므로, 사용자는 도구의 본체에만 집중할 수 있습니다.
하나의 서버와 하나의 도구로 시작하세요
안정적인 프로토콜 뒤에서 데이터와 동작을 한 번만 정의하면, 모델이나 호스트가 바뀔 때마다 접착 코드 (Glue code)를 다시 작성하는 일을 멈출 수 있습니다. 이미 보유하고 있는 무언가에 대해 하나의 도구를 노출하는 하나의 서버부터 시작해 보세요. 모델이 도구를 올바르게 호출하는 것을 확인했다면, 그다음 도구를 추가하면 됩니다.
AGINE Academy는 AGINE AI의 독립적인 제품이며, Claude의 제작사인 Anthropic과 관련이 없습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기