MCP · OVERVIEW
MCP 개요 & 스펙
Model Context Protocol(MCP)의 설계 철학, 프로토콜 버전, 네 가지 핵심 프리미티브의 개념과 역할을 정확히 파악합니다.
왜 MCP가 필요한가
MCP 이전에는 각 LLM 프레임워크(LangChain, Claude, GPT 등)마다 외부 도구를 연결하는 방식이 달랐습니다. 같은 "GitHub 검색 도구"를 Claude용, GPT용, Gemini용으로 각각 별도 구현해야 했고, 버전이 바뀌면 모두 수정해야 했습니다.
💡 MCP의 핵심 철학
"어떤 AI 모델이든, 어떤 도구든 같은 방식으로 연결한다" — USB-C처럼 표준화된 AI-도구 인터페이스.
한 번 구현한 MCP Server는 Claude, GPT, Gemini, 오픈소스 LLM 등 모든 MCP 호환 클라이언트에서 동작합니다.
프로토콜 기본 정보
| 항목 | 내용 |
|---|---|
| 최초 공개 | 2024년 11월 25일 (Anthropic 오픈소스 공개) |
| 현행 스펙 버전 | 2024-11-05 (protocolVersion) |
| 메시지 포맷 | JSON-RPC 2.0 기반 |
| 전송 방식 | stdio, HTTP+SSE, WebSocket(2025 draft) |
| 공식 SDK | Python (mcp), TypeScript (@modelcontextprotocol/sdk) |
| 라이선스 | MIT |
| 공식 스펙 | github.com/modelcontextprotocol/specification |
4가지 핵심 프리미티브
MCP Server는 아래 4가지 프리미티브 중 필요한 것만 선택적으로 구현합니다. 클라이언트와 서버는 연결 시 Capability 협상을 통해 지원 여부를 확인합니다.
그림 1. MCP 전체 구조 — Host가 Server를 통해 외부 서비스에 접근
| 프리미티브 | 방향 | 용도 | 예시 |
|---|---|---|---|
| 🔧 Tools | Host → Server | Host가 Server에게 함수 실행을 요청. 사이드이펙트 허용 | 웹 검색, DB 쿼리, 파일 쓰기, API 호출 |
| 📄 Resources | Host → Server | URI 기반으로 데이터/파일 읽기. 읽기 전용 | 파일 내용, 설정값, DB 스키마, 로그 |
| 💬 Prompts | Host → Server | 재사용 가능한 프롬프트 템플릿. 변수 인수 지원 | 코드 리뷰 템플릿, 번역 프롬프트 |
| 🤖 Sampling | Server → Host | Server가 Host의 LLM을 역방향으로 호출 | 데이터 분석 요청, 중간 추론 위임 |
MCP vs 기존 방식 비교
| 항목 | MCP 이전 (ad-hoc) | MCP |
|---|---|---|
| 도구 정의 | 프레임워크마다 다른 형식 | 표준 JSON Schema + JSON-RPC |
| 재사용성 | 낮음 — 프레임워크 종속 | 높음 — 모든 MCP 호환 Host |
| Discovery | 없음 — 하드코딩 | tools/list, resources/list 동적 탐색 |
| 스트리밍 결과 | 프레임워크 의존 | notifications 표준 지원 |
| 인증 표준 | 없음 | OAuth 2.1 (2025 spec) |
| 로깅/디버깅 | 없음 | logging capability 표준 |
Python SDK 빠른 시작
공식 Python SDK를 설치하고 최소한의 Tool 하나를 노출하는 서버를 만드는 전체 과정입니다.
bash
설치
# Python SDK (서버 + 클라이언트 포함)
pip install mcp
# FastMCP — 고수준 데코레이터 API (권장)
pip install fastmcp
python
hello_mcp.py — 최소 서버
from mcp.server.fastmcp import FastMCP
# 서버 인스턴스 생성
mcp = FastMCP("hello-server")
@mcp.tool()
def add(a: int, b: int) -> int:
"""두 정수를 더합니다."""
return a + b
@mcp.resource("config://version")
def get_version() -> str:
"""서버 버전 정보."""
return "1.0.0"
if __name__ == "__main__":
mcp.run() # stdio transport (기본값)
⚠️ protocolVersion 주의
클라이언트가 initialize 요청 시 보내는 protocolVersion은 반드시 서버가 지원하는 버전과 일치하거나 하위 호환이어야 합니다.
현재 안정 버전은 "2024-11-05"입니다. 서버는 지원하지 않는 버전 요청에 오류를 반환해야 합니다.