03. 다른 접근과의 비교, 그리고 생태계
- MCP를 함수 호출·플러그인·일반 REST API와 비교해 위치를 잡는다
- "왜 또 새 표준인가"에 대한 합리적 답을 갖는다
- 현재 MCP 생태계(SDK·도구·레지스트리)의 큰 지도를 그린다
비슷해 보이는 것들과의 구분
MCP를 처음 보면 이미 아는 여러 개념과 겹쳐 보입니다. 하나씩 떼어 놓아 봅시다.
1) LLM 함수 호출(function calling / tool use)
모델 API가 제공하는, "이런 도구가 있으니 필요하면 호출해"라고 모델에 알려주는 기능입니다. 강력하지만 모델 API 수준에 머뭅니다. 도구를 어떻게 정의·발견·실행·인증할지는 앱마다 직접 짜야 했습니다.
MCP는 이 위에 프로토콜 계층을 얹습니다. 도구뿐 아니라 리소스·프롬프트까지 표준 메서드(tools/list, tools/call, resources/read 등)로 노출·발견하게 만들어, 한 번 만든 서버를 여러 호스트가 재사용하게 합니다. 비유하자면 함수 호출은 "이 식당에서 쓰는 주문 방식"이고, MCP는 "모든 식당이 따르는 표준 주문서 양식"입니다.
2) 챗봇 플러그인 / 앱 스토어식 통합
특정 플랫폼 전용 플러그인은 그 플랫폼에서만 돕니다. 플랫폼이 바뀌면 다시 만들어야 하죠. MCP 서버는 표준을 따르므로, MCP를 지원하는 어떤 호스트에서도 동작합니다. "한 번 만들어 여러 곳에서"가 핵심 차이입니다.
3) 그냥 REST API를 호출하면 안 되나?
됩니다. 다만 그때마다 인증·스키마·발견·에러 규약을 앱이 직접 풀어야 합니다. MCP는 그 공통 부분을 표준화합니다. 표준화된 발견(tools/list로 자동 발견), 재사용 가능한 서버, 정의된 보안 모델(OAuth 2.0·TLS·동의 흐름), 그리고 도구·리소스·프롬프트라는 풍부한 컨텍스트 타입을 한 프로토콜 안에 담는 것이 REST를 직접 부르는 것과의 차이입니다.
flowchart TD
Q{"외부 도구를 LLM에 붙이려면?"}
Q -->|"한 앱에서만, 빠르게"| FC["모델 함수 호출\n직접 구현"]
Q -->|"한 플랫폼 전용"| PL["플랫폼 플러그인"]
Q -->|"여러 호스트에서 재사용\n표준 발견·인증 필요"| MCP["MCP 서버로 구현"]
classDef q fill:#bfdbfe,stroke:#1d4ed8,color:#000;
classDef opt fill:#5eead4,stroke:#0f766e,color:#000;
class Q q;
class FC,PL,MCP opt;
MCP가 표준으로 정해 둔 것들 (미리보기)
MCP가 "표준화했다"고 할 때, 구체적으로 무엇을 정해 두었는지 미리 훑어봅니다. 각 항목은 뒤 장에서 자세히 다룹니다.
| 표준화 영역 | 내용 | 다루는 장 |
|---|---|---|
| 메시지 형식 | JSON-RPC 2.0, UTF-8 | 04장 |
| 연결 시작 | initialize 핸드셰이크, capability 협상 | 05장 |
| 버전 | 날짜 기반 리비전, 버전 협상 | 06장 |
| 전송 | stdio, Streamable HTTP | 3부 |
| 능력(primitive) | Tools, Resources, Prompts | 4부 |
| 부가 | 알림, 구독, 로깅, sampling, elicitation | 13장 |
| 인증 | OAuth 2.1 기반 (원격) | 7부 |
여기서 primitive(원시 요소) 라는 말이 자주 나옵니다. MCP에서 일급(first-class) 컨텍스트 타입은 세 가지 — Tool(실행 가능한 행동), Resource(읽기 전용 데이터), Prompt(재사용 템플릿) — 이며 각각 표준화된 목록(list)과 가져오기/호출(get/call) 메서드를 가집니다. 또한 capability(능력)는 핸드셰이크 때 클라이언트나 서버가 광고하는 기능으로, 서버는 자신이 어떤 primitive를 지원하는지, 목록 변경 알림을 지원하는지를 선언합니다.
생태계 지도
MCP는 2024년 11월 공개 후 빠르게 커졌습니다. 제작자로서 알아둘 큰 줄기는 다음과 같습니다.
flowchart LR
SPEC["스펙\nmodelcontextprotocol.io\n(날짜 리비전)"] --> SDK
subgraph SDK["공식 SDK"]
PY["Python\n(mcp 패키지)"]
TS["TypeScript"]
ETC["기타 언어"]
end
SDK --> TOOLS
subgraph TOOLS["도구·인프라"]
INSP["MCP Inspector\n(디버깅)"]
REG["MCP Registry\n(서버 발견)"]
FAST["FastMCP\n(Python 고수준 프레임워크)"]
end
classDef spec fill:#bfdbfe,stroke:#1d4ed8,color:#000;
classDef sdk fill:#5eead4,stroke:#0f766e,color:#000;
classDef tool fill:#fde68a,stroke:#b45309,color:#000;
class SPEC spec;
class PY,TS,ETC sdk;
class INSP,REG,FAST tool;
- 스펙: 권위 있는 출처는
modelcontextprotocol.io의 스펙 문서입니다. 스펙은 TypeScript 스키마(schema.ts)를 기준으로 정의되며, JSON으로도 내보내집니다. - 공식 SDK: 여러 언어로 제공되며, 이 안내서는 Python(
mcp패키지) 을 씁니다. 공식 Python SDK는 전체 MCP 스펙을 구현해, 어떤 서버에도 붙는 클라이언트와, 리소스·프롬프트·도구를 노출하는 서버를 쉽게 만들 수 있게 해주며, stdio·SSE·Streamable HTTP 같은 표준 전송을 지원합니다. - FastMCP: Python으로 서버를 만들 때 널리 쓰이는 고수준 프레임워크입니다. 데코레이터와 타입 힌트로 함수에
@tool만 붙이면 JSON 스키마·검증·문서를 자동 생성해 줍니다. 여기서 데코레이터는 함수 위에@something을 붙여 그 함수에 기능을 더하는 파이썬 문법이고, 타입 힌트는 인자·반환의 타입을 표기하는 문법(a: int)입니다. FastMCP가 이 둘을 읽어 도구의 입력 양식과 설명을 자동으로 만들어 줍니다. (5부에서 직접 사용합니다.)
mcp 패키지 안에 mcp.server.fastmcp.FastMCP가 있습니다. 한편 standalone fastmcp 프로젝트(Prefect 유지, 현재 3.x)는 별도로 활발히 발전 중이며 from fastmcp import FastMCP로 임포트합니다. 둘은 이름이 같고 철학도 비슷하지만 버전·API가 갈라져 있습니다. 이 안내서의 기본 코드는 공식 mcp SDK 내장 FastMCP를 쓰고, standalone이 유리한 지점에서는 명시적으로 구분합니다. 실제 코드를 작성할 때는 어느 쪽을 설치했는지부터 확인하세요.- MCP Inspector: 서버를 띄워 도구·리소스·프롬프트를 눈으로 확인하고 호출해 보는 공식 디버깅 도구입니다. (16장에서 사용.)
- MCP Registry: 서버를 발견·공유하기 위한 레지스트리 흐름이 생태계에 도입되었습니다.
생태계는 "살아있다"
🔒 공급망 관점 미리보기: 레지스트리에서 남이 만든 서버를 가져다 쓰는 건 편하지만, 그 서버가 무슨 일을 하는지는 코드와 권한을 확인해야 합니다. 신뢰할 수 없는 서버는 도구 설명에 악성 지시를 숨기는 "도구 중독" 같은 공격을 할 수 있습니다. (21장)
이 장에서 배운 것
- MCP는 함수 호출 위의 프로토콜 계층으로, 발견·인증·재사용까지 표준화한다.
- 단일 앱·일회성이면 함수 호출 직접 구현이 더 가볍다. MCP는 재사용·표준 발견·여러 호스트에서 값어치가 난다.
- 일급 primitive는 Tool·Resource·Prompt 세 가지이며, capability는 핸드셰이크에서 광고된다.
- 생태계는 스펙 → 공식 SDK(Python 포함) → 도구(Inspector·Registry·FastMCP)로 이어진다. "FastMCP"는 공식 SDK 내장본과 standalone 두 갈래가 있으니 구분해야 한다.
✍️ 확인 문제
- "한 사내 도구를 사내 챗봇 한 곳에서만, 한 번 붙여 쓴다." MCP와 함수 호출 직접 구현 중 무엇이 더 적절할까? 이유는?
- MCP의 일급 primitive 세 가지를 들고, 각각 한 단어로 성격(행동/데이터/템플릿)을 매겨 보자.
- Python에서
from fastmcp import FastMCP와from mcp.server.fastmcp import FastMCP는 왜 같지 않을 수 있나?
1부 끝. 다음은 2부 · 프로토콜 기초 (04장 JSON-RPC 메시지 구조)로 이어집니다.