Skip to content

Split View: Model Context Protocol(MCP) 레퍼런스 — AI를 외부 세계에 연결하는 열린 표준

|

Model Context Protocol(MCP) 레퍼런스 — AI를 외부 세계에 연결하는 열린 표준

들어가며 — MCP는 무엇이고 무슨 문제를 푸는가

Model Context Protocol(MCP)은 공식 문서의 표현으로 "AI 애플리케이션을 외부 시스템에 연결하기 위한 오픈소스 표준"입니다. Claude나 ChatGPT 같은 애플리케이션이 로컬 파일·데이터베이스 같은 데이터 소스, 검색·계산기 같은 도구, 특화된 프롬프트 같은 워크플로에 붙도록 규격을 통일합니다. 문서는 이를 "AI 애플리케이션을 위한 USB-C 포트"에 비유합니다 — 케이블 규격이 하나로 통일되듯, 연결 방식을 하나로 통일한다는 뜻입니다.

왜 표준이 필요한가? 흔히 M×N 문제로 부릅니다. AI 애플리케이션이 M개, 붙이고 싶은 도구·데이터 소스가 N개면, 표준이 없을 때는 M×N개의 제각각인 통합을 손으로 만들어야 합니다. 공용 프로토콜이 하나 생기면 이 비용이 M+N으로 줄어듭니다 — 서버를 한 번 만들면 프로토콜을 지원하는 모든 클라이언트가 쓸 수 있고, 클라이언트도 프로토콜만 구현하면 모든 서버에 붙습니다. 문서의 표현으로 "한 번 만들어 어디에나 통합(build once, integrate everywhere)"입니다. MCP는 이 발상을 Language Server Protocol(LSP)에서 빌려왔다고 밝힙니다. LSP가 "에디터 × 언어" 조합을 표준 하나로 정리했듯, MCP는 "AI 앱 × 도구" 조합을 정리합니다.

MCP는 Anthropic이 2024년 11월에 공개·오픈소스화했고, 초기에 Python·TypeScript SDK와 Google Drive·Slack·GitHub·Git·Postgres·Puppeteer용 서버를 함께 냈습니다. 이후 OpenAI와 Google DeepMind도 채택하면서 사실상 업계 표준이 되었습니다.

아키텍처 — 호스트·클라이언트·서버, 그리고 전송

MCP는 클라이언트-서버 구조이고, 참여자는 셋으로 정의됩니다:

  • 호스트(Host). 하나 이상의 MCP 클라이언트를 조율·관리하는 AI 애플리케이션(예: Claude Code, VS Code).
  • 클라이언트(Client). 서버 하나와 연결을 유지하며 컨텍스트를 받아 오는 구성요소.
  • 서버(Server). 클라이언트에 컨텍스트를 제공하는 프로그램. 로컬에서 돌든 원격에서 돌든 "서버"입니다.

핵심 규칙은 서버 하나당 클라이언트 하나입니다. 호스트는 붙는 서버마다 전용 클라이언트를 만들어 각자 독립된 연결을 유지합니다. VS Code가 파일시스템 서버와 Sentry 서버에 붙으면 내부적으로 클라이언트 객체가 둘 생기는 식입니다.

프로토콜은 두 계층입니다. 데이터 계층(data layer)은 JSON-RPC 2.0 기반 교환 규격으로 생명주기 관리와 프리미티브(도구·리소스·프롬프트·알림)를 정의하고, 전송 계층(transport layer)은 실제 통신 채널과 인증을 다룹니다. 연결은 상태를 가지며(stateful), 클라이언트가 initialize 요청으로 protocolVersion과 서로의 능력(capabilities)을 협상한 뒤 notifications/initialized로 준비 완료를 알리며 시작합니다.

전송은 둘입니다:

  • stdio. 표준 입출력으로 같은 머신의 프로세스끼리 직접 통신 — 네트워크 오버헤드가 없어 로컬 서버에 적합하고 보통 클라이언트 하나를 상대합니다.
  • Streamable HTTP. 클라이언트→서버는 HTTP POST, 스트리밍이 필요하면 서버센트이벤트(SSE)를 얹습니다. 원격 서버용이며 베어러 토큰·API 키·커스텀 헤더를 지원하고, 문서는 토큰 획득에 OAuth를 권장합니다.

같은 JSON-RPC 메시지가 어느 전송에서도 그대로 통하도록, 전송 계층은 통신 세부를 프로토콜에서 분리합니다.

세 가지 프리미티브 — 도구, 리소스, 프롬프트

프리미티브는 MCP에서 가장 중요한 개념이고, 서버가 노출하는 세 가지가 핵심입니다. 각각 "누가 주도하는가"가 다릅니다:

  • 도구(Tools) — 모델 주도. AI가 실제로 호출해 행동하는 함수입니다(파일 쓰기, API 호출, DB 쿼리). 입력은 JSON Schema로 검증합니다. 발견은 tools/list, 실행은 tools/call. 모델이 스스로 언제 쓸지 정하므로, 실행 전 사용자 승인 같은 통제 장치가 강조됩니다.
  • 리소스(Resources) — 애플리케이션 주도. 읽기 전용 컨텍스트 데이터입니다(파일 내용, DB 스키마, 문서). 각 리소스는 고유 URI와 MIME 타입을 가집니다. 고정 URI인 직접 리소스와, 파라미터를 받는 리소스 템플릿이 있습니다. 메서드는 resources/list, resources/templates/list, resources/read, 변경 구독은 resources/subscribe.
  • 프롬프트(Prompts) — 사용자 주도. 재사용 가능한 템플릿으로, 도구·리소스를 어떻게 엮어 쓸지 안내합니다. 슬래시 커맨드처럼 사용자가 명시적으로 부릅니다. 메서드는 prompts/list, prompts/get.

리소스 URI는 고정형(직접 리소스)과 파라미터형(템플릿) 두 갈래입니다(설명용):

file:///Users/me/notes.md          # 직접 리소스 (고정 URI)
calendar://events/2026             # 직접 리소스
weather://forecast/{city}/{date}   # 리소스 템플릿 (파라미터)

발견은 */list, 조회는 */get, 실행은 tools/call이라는 규칙적 패턴을 따릅니다. 목록은 동적이라, 서버의 도구가 바뀌면 notifications/tools/list_changed 같은 알림으로 클라이언트에 알릴 수 있습니다.

반대로 클라이언트가 서버에 노출하는 프리미티브도 있습니다:

  • 샘플링. 서버가 클라이언트의 LLM에 완성을 요청하는 sampling/createMessage — 서버가 자체 모델 SDK 없이도 모델을 쓰게 합니다.
  • 일리시테이션. 서버가 사용자에게 추가 입력이나 확인을 요청하는 elicitation/create.
  • roots·로깅. 서버가 다룰 파일·URI 경계를 알리는 roots, 그리고 디버깅용 로그 전송.

서버를 어떻게 만들 것인가

서버 만들기의 본질은 "무엇을 도구로, 무엇을 리소스로, 무엇을 프롬프트로 노출할지"를 정하는 일입니다. 행동은 도구, 읽을 컨텍스트는 리소스, 정형 워크플로는 프롬프트로 나눕니다. 공식 SDK는 TypeScript·Python·C#·Go(Tier 1), Java·Rust(Tier 2), Swift·Ruby·PHP·Kotlin(Tier 3)이 있고, 모두 같은 기능을 언어 관용구에 맞춰 제공합니다. 세부 API는 SDK마다 다르니 언어별 문서를 봐야 합니다.

도구 정의는 이름·설명·입력 스키마로 이뤄집니다. 공식 문서의 예시 형태(설명용):

{
  "name": "searchFlights",
  "description": "Search for available flights",
  "inputSchema": {
    "type": "object",
    "properties": {
      "origin": { "type": "string", "description": "Departure city" },
      "destination": { "type": "string", "description": "Arrival city" }
    },
    "required": ["origin", "destination"]
  }
}

클라이언트는 먼저 tools/list로 이 정의를 받아 LLM에 등록하고, 모델이 도구를 고르면 tools/call로 실행합니다. 실제 오가는 JSON-RPC는 이런 모양입니다(설명용):

{ "jsonrpc": "2.0", "id": 3, "method": "tools/call",
  "params": { "name": "weather_current",
              "arguments": { "location": "San Francisco", "units": "imperial" } } }

응답은 content 배열로 돌아오며 텍스트·이미지·리소스 같은 여러 형식을 담을 수 있습니다. 개발·디버깅에는 공식 MCP Inspector레퍼런스 서버 모음이 출발점으로 좋습니다.

트레이드오프와 성숙도 — 솔직한 정리

MCP의 매력은 명확합니다. 통합을 한 번만 만들면 되고, LSP처럼 생태계 전체가 같은 규격을 공유합니다. 다만 냉정히 볼 지점도 있습니다.

  • 보안이 프로토콜에 내장되지 않습니다. 스펙 자신이 "도구는 임의의 코드 실행"이며 신뢰할 수 없는 서버의 도구 설명(annotation)은 믿지 말라고 못 박습니다. 사용자 동의·도구 실행 승인·샘플링 승인은 호스트 구현의 몫입니다 — 즉 안전은 프로토콜이 아니라 클라이언트가 지킵니다.
  • 원격 서버의 인증은 여전히 무겁습니다. Streamable HTTP와 OAuth 조합은 강력하지만, 로컬 stdio의 단순함과는 거리가 있습니다.
  • 스펙이 계속 움직입니다. 버전은 날짜 기반이며(현재 최신 2025-11-25), Tasks 같은 기능은 아직 실험(Experimental) 단계입니다. SDK도 티어가 나뉘어 성숙도가 제각각입니다.
  • 거버넌스가 이동 중입니다. 보도에 따르면 2025년 12월 MCP는 Linux Foundation 산하 Agentic AI Foundation으로 이관되었습니다 — 한 회사의 프로젝트에서 중립적 표준으로 넘어가는 신호입니다.

마치며

MCP의 핵심은 화려한 신기술이 아니라 "지루한 표준화"이고, 바로 그 점이 가치입니다. 도구·리소스·프롬프트라는 세 프리미티브와 JSON-RPC라는 얇은 규격만 이해하면, 어떤 클라이언트든 어떤 서버든 같은 방식으로 붙습니다. 에이전트를 실제 시스템에 연결하려는 엔지니어라면, 프레임워크를 고르기 전에 이 프로토콜 한 겹을 이해해 두는 편이 오래 남습니다.

참고 자료

The Model Context Protocol (MCP): An Engineer's Reference

Introduction — what MCP is, and the problem it solves

In the words of the official docs, the Model Context Protocol (MCP) is "an open-source standard for connecting AI applications to external systems." It gives applications like Claude or ChatGPT a standardized way to connect to data sources (local files, databases), tools (search, calculators), and workflows (specialized prompts). The docs offer a memorable analogy: think of MCP as "a USB-C port for AI applications" — one connector standard instead of a bespoke adapter per device.

Why standardize? The usual framing is the M×N problem. If you have M AI applications and N tools or data sources, then without a standard you write M×N bespoke integrations by hand. A shared protocol collapses that to M+N — build a server once and every protocol-speaking client can use it, and a client that implements the protocol can reach every server. The docs put it as "build once and integrate everywhere." MCP borrows this idea from the Language Server Protocol (LSP): where LSP standardized the "editor × language" matrix, MCP standardizes the "AI app × tool" matrix.

MCP was introduced and open-sourced by Anthropic in November 2024, shipping initially with Python and TypeScript SDKs and prebuilt servers for Google Drive, Slack, GitHub, Git, Postgres, and Puppeteer. It was subsequently adopted by OpenAI and Google DeepMind, making it a de facto industry standard.

Architecture — hosts, clients, servers, and transports

MCP follows a client-server architecture with three participants:

  • Host. The AI application that coordinates and manages one or more MCP clients (e.g., Claude Code, VS Code).
  • Client. A component that maintains a connection to a single server and obtains context from it.
  • Server. A program that provides context to clients. Whether it runs locally or remotely, it is still "the server."

The key rule is one client per server. The host instantiates a dedicated client for each server it connects to, and each client keeps its own independent connection. If VS Code connects to a filesystem server and a Sentry server, two client objects exist internally.

The protocol has two layers. The data layer is a JSON-RPC 2.0 exchange protocol that defines lifecycle management and the primitives (tools, resources, prompts, notifications); the transport layer handles the actual communication channels and authentication. Connections are stateful and begin with a handshake: the client sends an initialize request to negotiate the protocolVersion and each side's capabilities, then signals readiness with a notifications/initialized message.

There are two transports:

  • stdio. Standard input/output for direct process-to-process communication on the same machine — no network overhead, ideal for local servers, and typically serving a single client.
  • Streamable HTTP. HTTP POST for client-to-server messages, with optional Server-Sent Events (SSE) when streaming is needed. This is the remote transport; it supports bearer tokens, API keys, and custom headers, and the docs recommend OAuth for obtaining tokens.

The transport layer abstracts these details away so the same JSON-RPC message format works across any transport.

The three primitives — tools, resources, prompts

Primitives are the most important concept in MCP, and the three a server exposes are the core of it. They differ in who controls them:

  • Tools — model-controlled. Functions the AI actively invokes to perform actions (write files, call APIs, query databases). Inputs are validated with JSON Schema. Discover with tools/list, execute with tools/call. Because the model decides when to call them, human oversight — such as approval before execution — is emphasized.
  • Resources — application-controlled. Read-only context data (file contents, database schemas, documents). Each resource has a unique URI and a MIME type. There are direct resources with fixed URIs and resource templates that take parameters. Methods: resources/list, resources/templates/list, resources/read, and resources/subscribe for change monitoring.
  • Prompts — user-controlled. Reusable templates that show how to combine tools and resources. Like slash commands, they are invoked explicitly by the user. Methods: prompts/list, prompts/get.

Resource URIs come in two shapes — fixed (direct resources) and parameterized (templates), illustrated below:

file:///Users/me/notes.md          # direct resource (fixed URI)
calendar://events/2026             # direct resource
weather://forecast/{city}/{date}   # resource template (parameters)

The design follows a regular pattern — discovery via */list, retrieval via */get, and execution via tools/call. Listings are dynamic, so when a server's tools change it can notify clients with messages like notifications/tools/list_changed.

Conversely, clients can expose primitives to servers:

  • Sampling. sampling/createMessage lets a server request a completion from the client's LLM — so the server can use a model without bundling its own model SDK.
  • Elicitation. elicitation/create lets a server request additional input or confirmation from the user.
  • Roots and logging. Roots tell the server which file/URI boundaries it may operate in; logging carries debug messages back to the client.

Building a server — how to think about it

Building a server is really about deciding what to expose as a tool, a resource, or a prompt. Actions become tools, readable context becomes resources, and structured workflows become prompts. The official SDKs are TypeScript, Python, C#, and Go (Tier 1); Java and Rust (Tier 2); Swift, Ruby, PHP, and Kotlin (Tier 3). All provide the same functionality following each language's idioms, so exact APIs differ — check the per-language docs.

A tool definition is a name, a description, and an input schema. The shape from the docs (illustrative):

{
  "name": "searchFlights",
  "description": "Search for available flights",
  "inputSchema": {
    "type": "object",
    "properties": {
      "origin": { "type": "string", "description": "Departure city" },
      "destination": { "type": "string", "description": "Arrival city" }
    },
    "required": ["origin", "destination"]
  }
}

The client first fetches these definitions via tools/list and registers them with the LLM; when the model picks a tool, the client executes it via tools/call. The JSON-RPC on the wire looks like this (illustrative):

{ "jsonrpc": "2.0", "id": 3, "method": "tools/call",
  "params": { "name": "weather_current",
              "arguments": { "location": "San Francisco", "units": "imperial" } } }

The response comes back as a content array that can carry multiple formats — text, images, resources. For development and debugging, the official MCP Inspector and the reference server collection are good starting points.

Tradeoffs and maturity — an honest read

The appeal is clear: integrate once, and the whole ecosystem shares one format, LSP-style. But there are things to look at soberly.

  • Security is not baked into the protocol. The spec itself states that tools "represent arbitrary code execution" and that a tool's descriptions or annotations "should be considered untrusted" unless the server is trusted. User consent, tool-execution approval, and sampling approval are the host's job — so safety lives in the client, not the protocol.
  • Remote authentication is still heavy. Streamable HTTP plus OAuth is powerful, but a long way from the simplicity of local stdio.
  • The spec keeps moving. Versions are date-based (the latest is 2025-11-25), and features like Tasks are still Experimental. SDKs are split into tiers, so maturity varies by language.
  • Governance is in transition. Per reporting, in December 2025 MCP moved to the Agentic AI Foundation under the Linux Foundation — a signal of the shift from one company's project toward a neutral standard.

Closing

The core of MCP is not a flashy new technology but "boring standardization" — and that is precisely its value. Understand three primitives (tools, resources, prompts) and one thin format (JSON-RPC), and any client connects to any server the same way. If you are an engineer wiring agents into real systems, understanding this one protocol layer will outlast whichever framework you pick on top of it.

References