- Authors

- Name
- Youngju Kim
- @fjvbn20031
Season 4 Ep 5 — Ep 3에서 잠깐 지나갔던 MCP. 2025년 기준 거의 모든 에이전트 프레임워크가 MCP를 얘기한다. 왜 이게 표준이 되는지, 어떻게 작동하는지, 어떻게 만들고 어떻게 지킬지.
- Prologue — "M x N 문제"의 해결책
- 1장 · 핵심 개념
- 2장 · 전송 계층 (Transport)
- 3장 · Tools · Resources · Prompts · Sampling
- 4장 · 인증과 권한 (OAuth 2.1)
- 5장 · 대표 MCP 서버 — 2025 생태계
- 6장 · 직접 MCP 서버 만들기 (TypeScript)
- 7장 · Python MCP 서버
- 8장 · 보안 위협과 방어
- 9장 · MCP vs OpenAPI vs Function calling
- 10장 · 엔터프라이즈 도입
- 11장 · 개발자 UX — 실전 팁
- 12장 · 안티패턴 10선
- 13장 · 체크리스트 — MCP 서버 배포 전 12가지
- 14장 · 다음 글 예고 — Season 4 Ep 6: "LLM 평가 & 관측성"
Prologue — "M x N 문제"의 해결책
2024년 초까지, LLM 애플리케이션과 도구의 연결은 각자 독자 규격이었다.
- ChatGPT 플러그인: OpenAPI 기반 독자 사양
- LangChain Tool: Python/JS 클래스
- Claude Tool use: Anthropic 스키마
- Ollama, vLLM, …
M개 LLM × N개 도구 = M×N 통합 코드. M, N이 커질수록 팀들은 같은 GitHub 연동을 각각 새로 짰다.
2024년 11월, Anthropic이 **Model Context Protocol (MCP)**을 공개했다. 핵심은 단순하다.
LLM 애플리케이션 ↔ 외부 도구·데이터 소스 사이의 표준 프로토콜.
USB-C가 전원·데이터·영상·오디오의 커넥터를 통일한 것처럼, MCP는 "LLM이 외부 세계와 얘기하는 방법"을 통일했다. 2025년 현재 Anthropic·OpenAI·Google·Microsoft·주요 IDE·수백 개 오픈소스 서버가 MCP를 지원한다.
1장 · 핵심 개념
1.1 Client · Server · Host
[Host Application] 예: Claude Desktop, Claude Code, Cursor, VS Code
├── [MCP Client] ↔ [MCP Server A] 예: GitHub MCP
├── [MCP Client] ↔ [MCP Server B] 예: Filesystem MCP
└── [MCP Client] ↔ [MCP Server C] 예: Slack MCP
- Host: LLM이 실행되는 앱 (IDE, 데스크톱 앱, 커스텀 앱)
- Client: Host 안에서 서버 한 곳과 연결을 맡는 단위
- Server: 특정 도구·데이터 소스를 MCP로 노출하는 프로세스
Host는 여러 Client를 동시에 가질 수 있다(= 여러 서버 붙이기). 서버는 독립적으로 배포 가능.
1.2 JSON-RPC 2.0 기반
메시지 형식은 JSON-RPC 2.0. 요청/응답/알림 세 종류.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": { "name": "search_issues", "arguments": { "q": "bug" } }
}
1.3 기능 레이어
- Resources: 서버가 제공하는 읽기 가능 데이터 (파일, 쿼리 결과 등)
- Tools: 서버가 제공하는 실행 가능 기능 (함수 호출)
- Prompts: 서버가 제공하는 재사용 프롬프트 템플릿
- Sampling: 서버가 Host에게 LLM 호출을 요청하는 역방향 기능 (서버 내 에이전트)
1.4 Capability 협상
세션 시작 시 initialize로 양쪽 capability를 선언. 서버가 Resources를 지원하는지, Host가 Sampling을 수락할지 등.
2장 · 전송 계층 (Transport)
2.1 stdio
프로세스 표준 입출력으로 JSON-RPC 메시지 주고받기.
- 로컬 서버 실행에 최적 (Claude Desktop이 처음부터 채택)
- 빠르고 단순
- 단점: 원격 분리 어려움, 수명이 Host에 종속
2.2 HTTP + SSE (구 방식)
- HTTP POST로 서버에 요청
- Server-Sent Events(SSE)로 응답 스트리밍
- 2024년 초기 스펙, 이후 보안·멀티플렉싱 이슈로 지양
2.3 Streamable HTTP (2025 주류)
- 단일 HTTP 엔드포인트로 request/response + streaming
- POST 요청에
Accept: text/event-stream등으로 스트리밍 응답 - 프록시·로드밸런서 친화, 클라우드 배포에 적합
- 인증(OAuth 2.1, Bearer) 자연스럽게 결합
신규 MCP 서버는 Streamable HTTP를 우선 채택하는 게 2025년 관례.
2.4 선택 가이드
| 배포 형태 | 권장 전송 |
|---|---|
| 사용자 로컬 바이너리 | stdio |
| 사내 SaaS 연결 | Streamable HTTP |
| 퍼블릭 클라우드 서비스 | Streamable HTTP + OAuth |
| 단기 실험·데모 | stdio |
3장 · Tools · Resources · Prompts · Sampling
3.1 Tools
모델이 호출할 "함수"를 서버가 노출.
{
"name": "github.create_issue",
"description": "Create an issue in a GitHub repository.",
"inputSchema": {
"type": "object",
"required": ["owner", "repo", "title"],
"properties": {
"owner": { "type": "string" },
"repo": { "type": "string" },
"title": { "type": "string" },
"body": { "type": "string" }
}
}
}
- Client가
tools/list로 조회 → 모델이 선택 →tools/call로 실행 - 결과는 text / image / resource 형태
3.2 Resources
정적/동적 데이터를 URI로 노출.
resources/list
-> [{ uri: "notes://personal/2025-04-15", name: "오늘의 메모", ... }, ...]
resources/read
params: { uri: "notes://personal/2025-04-15" }
-> { contents: [{ uri, text | blob, mimeType }] }
Tools와의 차이:
- Tools = 실행 (동사)
- Resources = 조회 (명사)
- Host UI가 Resource를 "첨부할 수 있는 것"으로 노출하는 경우 많음
3.3 Prompts
서버가 제공하는 사용자용 프롬프트 템플릿.
prompts/list
-> [{ name: "weekly_review", description: "주간 회고 생성", arguments: [...] }]
prompts/get
params: { name: "weekly_review", arguments: { project: "Alpha" } }
-> { messages: [{ role, content: { type: "text", text: "..." } }] }
Host에서 슬래시 명령(/weekly_review)처럼 노출되는 경우가 많다.
3.4 Sampling
서버가 Host에게 "이 프롬프트로 LLM 한 번 돌려줘"라고 요청.
- 서버 내부에 에이전트 로직을 넣되, LLM 호출은 Host의 모델을 쓰게 함 → 비용·권한이 사용자 쪽
- Host는 반드시 사용자 허용을 구현 (자동 실행 금지 권장)
4장 · 인증과 권한 (OAuth 2.1)
4.1 왜 OAuth 2.1
MCP의 원격 서버(Streamable HTTP)는 민감한 사내·SaaS 데이터에 접근한다. 따라서 표준 인증이 필수.
2025년 MCP는 OAuth 2.1 (PKCE 필수, implicit flow 제거)을 권장 표준으로 정비.
4.2 기본 흐름
Host(Client) → 인증 시작
↓
브라우저 리다이렉트 → 사용자 로그인/동의
↓
Authorization code + PKCE
↓
Access Token (+ Refresh Token)
↓
이후 MCP 호출 Authorization: Bearer <token>
4.3 Dynamic Client Registration
사용자가 어떤 Host를 쓸지 모르는 공개 MCP 서버는 동적 클라이언트 등록(RFC 7591)을 지원하는 것이 편리. Host가 처음 연결 시 자동으로 client_id를 발급받음.
4.4 Scope 설계
- 최소 권한 원칙: 각 Tool/Resource가 어떤 scope을 요구하는지 명시
- 사용자가 동의 화면에서 scope별로 on/off 가능하도록
- 예:
github:repo:read,github:issue:write,github:workflow:admin등 세분화
4.5 토큰 수명·회전
- Access Token 짧게 (15–60분), Refresh Token 별도
- 사고 시 회전(rotation) 가능하도록 revoke 엔드포인트 제공
5장 · 대표 MCP 서버 — 2025 생태계
5.1 Anthropic 및 커뮤니티 공식
- filesystem: 로컬 파일 읽기/쓰기
- git: 로컬 Git 작업
- github: 이슈, PR, 코드 검색
- slack: 메시지 읽기/보내기
- google-drive / gmail / calendar: 구글 워크스페이스
- postgres / sqlite: SQL 질의
- puppeteer / playwright: 브라우저 자동화
- memory: 대화 간 기억 저장
- time: 시간/타임존 유틸
5.2 제품 SaaS 공식 서버
- Linear, Notion, Figma, Jira, Confluence, GitLab, Asana, Monday, Intercom, Stripe, Vercel, Supabase, AWS — 2025년에 대부분 공식/준공식 MCP 서버 제공
- 인증은 OAuth 2.1 또는 개인 토큰
5.3 브라우저 MCP
- Claude for Chrome extension: Chrome 탭을 MCP로 노출
- Playwright MCP: 테스트·자동화용 브라우저 제어
- Chrome DevTools MCP: 퍼포먼스·네트워크·콘솔 조사
브라우저 MCP의 공통 리스크: 링크 수상함 검증, 데이터 유출(export), 자동 클릭 제한 등 안전 정책 필수.
5.4 Computer-use MCP
- claude computer-use: macOS 데스크톱 제어 (스크린샷, 키보드, 마우스)
- 네이티브 앱 자동화·크로스 앱 워크플로우
- 리스크: 화면 내 민감정보, 금전/거래 실행 등 — 가드레일 필요
5.5 한국 생태계
- 카카오(카카오워크), 네이버(웍스), 토스 등 공식 MCP는 아직 제한적 (2025년 중반)
- 대안: 각사 OpenAPI를 감싼 사내 MCP 서버 직접 구축
6장 · 직접 MCP 서버 만들기 (TypeScript)
6.1 프로젝트 스캐폴드
mkdir my-mcp-server && cd my-mcp-server
npm init -y
npm i @modelcontextprotocol/sdk zod
6.2 최소 예제
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new Server(
{ name: "demo-mcp", version: "0.1.0" },
{ capabilities: { tools: {} } }
);
server.tool(
"add",
"두 수를 더한다.",
{ a: z.number(), b: z.number() },
async ({ a, b }) => ({
content: [{ type: "text", text: String(a + b) }]
})
);
const transport = new StdioServerTransport();
await server.connect(transport);
실행: node dist/index.js. Claude Desktop이나 Claude Code의 MCP 설정에 등록하면 add 툴이 보인다.
6.3 Resources 예
server.resource(
"notes",
"notes://list",
async () => ({
contents: [{
uri: "notes://list",
mimeType: "application/json",
text: JSON.stringify(await listNotes())
}]
})
);
6.4 Streamable HTTP 전환
import { StreamableHttpServerTransport } from "@modelcontextprotocol/sdk/server/streamable-http.js";
const transport = new StreamableHttpServerTransport({
// Express/Fastify 어댑터
});
6.5 운영 팁
- 오류는 구조화(
{ error: { code, message, data } }) - 모든 툴에 자체 rate limit (악성 호출 방지)
- 로그: 요청 수, 사용자, 성공/실패, 지연 — 일반 서버처럼
7장 · Python MCP 서버
7.1 기본 예
from mcp.server import Server
from mcp.server.stdio import stdio_server
app = Server("demo-mcp")
@app.list_tools()
async def list_tools():
return [{
"name": "echo",
"description": "문자열을 그대로 돌려준다",
"inputSchema": {
"type": "object",
"properties": { "text": {"type": "string"} },
"required": ["text"],
},
}]
@app.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "echo":
return [{"type": "text", "text": arguments["text"]}]
async def main():
async with stdio_server() as (r, w):
await app.run(r, w, app.create_initialization_options())
7.2 FastMCP
더 간결한 파이썬 DSL.
from fastmcp import FastMCP
app = FastMCP("demo")
@app.tool()
def add(a: int, b: int) -> int:
"""두 수를 더한다"""
return a + b
app.run()
FastMCP는 Streamable HTTP·인증 미들웨어를 기본 제공.
8장 · 보안 위협과 방어
8.1 주요 위협
- Malicious MCP server: 사용자가 잘못된 서버를 붙여서 내 데이터가 새는 경우
- Prompt injection via tool output: 서버가 돌려주는 텍스트에 "다음 툴을 실행해" 같은 지시가 섞이면 에이전트가 속아 실행
- Tool confusion: 비슷한 이름의 두 서버(공식 vs 사칭)가 붙어 선택을 헷갈림
- Credential theft: 서버가 OAuth 토큰을 로그에 남기거나 외부에 전송
- Exfiltration via URL: 결과에
같은 이미지 링크로 데이터 탈취 - Supply chain: NPM/PyPI의 MCP 서버 패키지 변조
8.2 방어 레이어
(a) 서버 신뢰
- 공식 publisher/서명 여부 확인
- 허용 목록(allowlist)만 설치 가능하도록
- 설치 시 권한 스코프 사용자에게 명시적 동의
(b) 툴 출력의 취급
- Host는 서버 응답의 지시성 내용을 "데이터"로 취급. 시스템 프롬프트에 명시.
- 민감 작업(커밋, 삭제, 외부 전송)은 인간 승인 게이트
(c) 네트워크 경계
- MCP 서버가 외부와 통신 시 egress allowlist (사내 방화벽)
- URL에 임의의 쿼리스트링 포함 금지 정책
(d) 비밀 관리
- 토큰은 환경변수나 비밀 저장소(Keychain, Vault), 파일 직접 저장 금지
- 로그 마스킹(정규식으로 token-like 값 치환)
(e) 샌드박싱
- filesystem MCP는 특정 경로만 노출
- computer-use MCP는 앱 그룹별 tier 제한 (claude computer-use의 read/click/full 모델처럼)
8.3 엔터프라이즈 정책 예
- 공식 MCP 서버 + 사내 자체 서버만 허용
- 외부 서드파티 서버 설치는 보안팀 리뷰 필수
- OAuth 토큰은 사내 IdP 발급, scope별 승인
- 모든 tools/call 호출 로그 중앙 집계, 30–90일 보관
- 금지 동작(결제, 외부 메일 발송 등)은 별도 approval API 경유
9장 · MCP vs OpenAPI vs Function calling
9.1 비교
| 관점 | OpenAPI | Function calling | MCP |
|---|---|---|---|
| 목적 | HTTP API 명세 | 모델이 함수 호출 | 모델 ↔ 툴·데이터 연결 |
| 범위 | API 단위 | 단일 호출 | 세션·Capability |
| Resources | 없음 | 없음 | 있음 |
| Prompts | 없음 | 없음 | 있음 |
| Sampling | 없음 | 없음 | 있음 |
| 재사용 | 어플당 구현 | 모델·SDK별 | 범용 표준 |
9.2 관계
- Function calling은 LLM API 레벨의 프리미티브
- MCP는 Host ↔ Server 레벨의 프로토콜 (Function calling의 상위 계층)
- OpenAPI 서버는 보통 MCP 서버로 래핑해서 제공 가능
즉 MCP가 Function calling을 대체하는 게 아니라, Function calling을 호출할 수 있는 툴 소스를 표준화하는 것.
10장 · 엔터프라이즈 도입
10.1 단계
- Pilot: 1–2개 서버(공식 GitHub, 사내 Jira MCP) + 엔지니어링팀 일부
- Expand: 사내 필수 도구 MCP화 (CRM, BI, DMS)
- Govern: 허용 목록, 로깅, 보안 리뷰 프로세스
- Platform: 내부 MCP 마켓플레이스(사내 포털)로 공유
10.2 거버넌스
- 카탈로그: 사내 모든 MCP 서버 목록 + 오너 + 데이터 범위
- 접근 제어: 부서/역할별로 접근 가능한 서버 세트
- 감사: 누가 언제 어떤 서버에서 무엇을 했는지 로그 집계
- 회귀/업그레이드: 서버 버전 관리, 주요 변경 시 팀별 공지
10.3 비용 모델
- MCP 서버 자체는 가벼움 (Python/Node 프로세스)
- 진짜 비용은 그 뒤의 LLM 호출과 SaaS API 사용료
- Sampling 기능을 서버가 쓰면 사용자 Host의 LLM 크레딧 소비에 주의
10.4 한국 기업 사례
- 대기업: 사내 OpenAPI를 MCP 서버로 감싸 Claude/Cursor에서 바로 사용
- 스타트업: GitHub/Linear/Slack 공식 MCP + 자체 제품 MCP로 고객 지원 자동화
- 공공: 망분리 환경에서 사내 MCP만 허용, 외부 인터넷 접근 차단
11장 · 개발자 UX — 실전 팁
11.1 Claude Desktop/Code에 등록
~/Library/Application Support/Claude/claude_desktop_config.json 같은 설정 파일에 서버 목록:
{
"mcpServers": {
"filesystem": {
"command": "node",
"args": ["/path/to/fs-mcp.js", "/Users/me/docs"]
}
}
}
11.2 Cursor / VS Code / JetBrains
- Cursor는 GUI로 MCP 추가 가능 (2025년 정식 지원)
- VS Code + Continue / Cline / Aider 등 확장도 MCP 소비자
- JetBrains는 AI Assistant 플러그인이 MCP 흡수 진행 중
11.3 여러 서버 충돌 해결
같은 툴 이름이 겹치면 혼란. 관례:
- 서버 이름을 prefix로 자동 부여 (
github.create_issue,slack.send_message) - 설치 시 서버별 prefix 사용자 설정 가능
11.4 디버깅
mcp inspector공식 툴: 브라우저 UI로 서버 붙여 요청·응답 관찰- JSON-RPC 로그를 파일로 덤프 → 이슈 재현
- Host 측 trace와 결합해 "에이전트 → MCP → 외부 API"를 한 화면에
12장 · 안티패턴 10선
12.1 아무 MCP 서버나 설치
신뢰·서명 확인 없이는 설치 금지.
12.2 토큰을 코드에 하드코딩
누출 즉시 전파. 환경변수/Secrets Manager 사용.
12.3 한 서버에 툴 50개 몰기
모델의 선택 정확도 떨어짐 + UI 혼잡. 카테고리로 분리.
12.4 Sampling 자동 승인
비용·데이터 유출 위험. 반드시 사용자 확인.
12.5 stdio만 지원, 원격 배포 불가
팀 공유·클라우드 배포 막힘. Streamable HTTP 병행.
12.6 권한 scope 없음
"전권" 토큰. 최소 권한 원칙 위배.
12.7 툴 반환에 민감정보 원문
LLM 컨텍스트에 API key, PII가 노출.
12.8 OpenAPI 감싸기만 하고 도메인화 없음
"GET /v1/...?.." 그대로 노출하면 모델이 호출 못 함. 도메인 언어로 툴 네이밍.
12.9 감사 로그 없음
사고 시 "누가 뭘 했는지" 알 수 없음.
12.10 서버 업그레이드 시 마이그레이션 가이드 없음
Host 사용자들이 침묵의 고장.
13장 · 체크리스트 — MCP 서버 배포 전 12가지
- 서버 이름·버전·설명 명확
- 전송 계층 명시(Streamable HTTP 우선)
- 모든 Tool에
inputSchema+ description - 리턴 포맷 표준화 + 오류 포맷 정의
- OAuth 2.1 + scope 설계 (원격 서버 시)
- Rate limit·백오프 정책
- 로그에 비밀값 마스킹
- 감사 로그(사용자·시간·툴·인자 해시)
- 민감 작업에 인간 승인 훅
- 테스트: mcp inspector로 주요 시나리오 확인
- 버저닝 정책(semver)과 변경 로그
- 문서: Install 가이드, Troubleshooting, FAQ
14장 · 다음 글 예고 — Season 4 Ep 6: "LLM 평가 & 관측성"
MCP로 도구를 붙이고, RAG로 지식을 붙이고, Fine-tune으로 스타일을 고정해도 — **"정말 잘 작동하는지"**를 못 재면 모든 게 무용지물이다.
- Eval harness: 오프라인/온라인, 자동/수동
- LLM-as-judge: 장점과 치명적 단점
- 회귀 방지 CI 설계
- 관측성 3층: Trace, Span, Metric
- 비용·지연 대시보드
- 프로덕션 피드백 루프 (좋아요/싫어요 → 평가셋 복귀)
- 에이전트·RAG·Fine-tune 각각의 평가 특수성
- Arize Phoenix, LangSmith, LangFuse, Helicone, W&B 비교
- 사고(incident) 대응 플레이북
- 한국어·규제 환경에서의 관측성
"측정할 수 없으면 개선할 수 없다." 너무 자주 듣는 말이지만, LLM 제품에선 더 그렇다.
다음 글에서 만나자.
요약: MCP는 M×N 통합 비용을 M+N으로 줄이는 표준이다. Tools/Resources/Prompts/Sampling 네 축으로 LLM ↔ 외부를 연결하고, Streamable HTTP + OAuth 2.1로 안전하게 원격 배포하며, 서버·툴·권한을 최소 단위로 쪼개서 운영한다. 2025년엔 "MCP 지원 없는 에이전트 프레임워크는 시대에 뒤처짐"이라는 인식이 굳어졌다. 직접 서버를 만드는 건 하루면 되지만, 엔터프라이즈에 안전하게 배포하려면 카탈로그·감사·거버넌스가 그 다음의 진짜 과제.