MCP v2: 무엇이 변경되고, 무엇이 지원 중단되며, 그 이유는 무엇인가
요약
Model Context Protocol(MCP) v2의 주요 변경 사항과 마이그레이션 가이드를 다룹니다. 프로토콜이 상태 비저장(stateless) 방식으로 전환되며, 샘플링, 루트, 로깅 기능이 지원 중단되는 내용을 설명합니다.
핵심 포인트
- 프로토콜이 상태 비저장(stateless) 방식으로 전환되어 수평적 확장이 용이해짐
- sampling, roots, logging 하위 시스템의 지원 중단(deprecation) 안내
- 확장(extensions) 기능이 일급 구성 요소로 공식화됨
- 현재 v2 SDK는 베타 단계이므로 안정적인 릴리스를 기다릴 것을 권장
MCP v2의 중대한 변경 사항(breaking changes) 설명: 프로토콜이 상태 비저장(stateless) 방식으로 전환되며 샘플링(sampling), 루트(roots), 로깅(logging) 기능이 지원 중단(deprecated)됩니다. 모든 MCP SDK에서 무엇이 변경되는지, 그 이유는 무엇인지, 그리고 지금 바로 마이그레이션해야 하는지에 대해 알아봅니다.
서론 (Introduction)
Model Context Protocol (MCP)을 기반으로 무언가를 구축했다면, 향후 몇 주가 매우 중요합니다. MCP v2 (프로토콜 개정 버전 2026-07-28)는 2026년 7월 28일에 최종 확정됩니다. 출시 후보(release candidate) 버전은 2026년 5월 21일에 확정되었으며, SDK 유지 관리자들은 사양이 발표되기 전 10주간의 기간 동안 실제 워크로드(workloads)를 대상으로 이를 검증하고 있습니다.
이번 업데이트는 단순한 포인트 릴리스(point release)가 아닙니다. v2는 프로토콜을 상태 비저장(stateless) 방식으로 만들고, **확장(extensions)**을 일급 구성 요소(first-class components)로 공식화하며, 기존의 많은 서버가 의존하고 있는 세 가지 하위 시스템인 샘플링(sampling), 루트(roots), **로깅(logging)**을 지원 중단(deprecates)합니다.
이 기사는 각 SDK별 가이드를 보완하는 언어 중립적인(language-agnostic) 동반 가이드입니다. TypeScript, Python, Go 또는 C# 중 무엇을 사용하든, 안정적인 SDK가 출시되었을 때 마이그레이션의 형태를 이해할 수 있도록 무엇이 변경되는지 그리고 왜 변경되는지를 다룹니다. 현재의 v1 TypeScript 가이드는 The MCP TypeScript SDK: A Complete Guide를 참조하십시오. SDK가 안정화되면 해당 가이드의 v2 업데이트 버전이 제공될 예정입니다.
중요: 이 글을 쓰는 시점에서 v2 SDK는 베타(beta) 단계에 있습니다. MCP 팀은 다음과 같이 명시하고 있습니다: "모든 중요한 워크로드에 대해서는 안정적인(stable) SDK 릴리스를 권장 버전으로 유지합니다." 그리고 "공개 API(public APIs)는 베타와 안정적 릴리스 사이에 여전히 변경될 수 있습니다." 아래의 코드 형태는 최종안이 아닌 방향성을 제시하는 것으로 간주하십시오.
학습 내용:
- 주요 변경 사항: 왜 MCP가 상태 비저장(stateless) 방식으로 전환되는가
- 어떤 하위 시스템이 지원 중단되는가 (sampling, roots, logging) 및 각각을 무엇이 대체하는가
- 상태 비저장(stateless)으로의 전환이 여러분이 구축하는 SDK에 의미하는 바는 무엇인가
- 확장(extensions)이란 무엇이며, v2와 함께 출시되는 두 가지 공식 확장은 무엇인가
- 지금 마이그레이션해야 하는가, 아니면 안정화(stable)를 기다려야 하는가
핵심적인 변화: MCP의 무상태(Stateless) 전환
v2에서 가장 큰 단일 변화는 프로토콜이 **무상태(stateless)**가 된다는 점입니다.
v1에서는 모든 세션이 initialize / initialized 핸드셰이크(handshake)로 시작되었으며, 서버는 Mcp-Session-Id를 발행하고 클라이언트는 이후의 모든 요청에서 이를 다시 전송했습니다. 해당 세션 ID는 클라이언트를 특정 서버 인스턴스에 고정(pin)시켰습니다. 만약 서버를 수평적으로 확장(scale horizontally)한다면, 후속 요청이 핸드셰이크를 수행했던 동일한 프로세스에 도달할 수 있도록 스티키 세션(sticky sessions)이 필요했습니다.
v2는 이 모든 것을 제거합니다:
initialize/initialized핸드셰이크가 없습니다.Mcp-Session-Id헤더가 없습니다.- 클라이언트 정보는 이제 각 요청의
_meta필드를 통해 전달되므로, 모든 요청이 자기 완결적(self-contained)입니다. - 두 가지 새로운 운영 헤더인 **
Mcp-Method**와 **Mcp-Name**을 통해 인프라가 본문(body)을 파싱하지 않고도 요청을 라우팅하고 관찰할 수 있습니다. - 캐싱 메타데이터(
ttlMs및cacheScope)가 이제 프로토콜의 일부가 되었습니다.
실질적인 이점은 다음과 같습니다: 요청이 어떠한 서버 인스턴스에 의해서도 처리될 수 있습니다. 스티키 세션, 세션 어피니티(session affinity), 공유 세션 저장소가 필요하지 않습니다. 이는 다음 요청이 동일한 장비에 도달한다고 가정할 수 없는 서버리스(serverless) 및 오토스케일링(autoscaled) 배포 환경에 훨씬 더 적합합니다.
이 한 가지 변화가 아래에 언급될 대부분의 지원 중단(deprecation) 사항들의 이유이기도 합니다. 여러 v1 기능들은 하나의 클라이언트와 하나의 서버 프로세스 간의 장기적인 상태 유지(stateful) 연결을 암묵적으로 가정했습니다. 일단 그 가정이 사라지면, 해당 기능들은 더 이상 적합하지 않게 됩니다.
무엇이 지원 중단되며, 그 이유는 무엇인가
v2의 새로운 라이프사이클 정책에 따라 세 가지 서브시스템(subsystems)이 지원 중단됩니다. 지원 중단(Deprecated)이 제거(removed)를 의미하지는 않습니다. 각 기능은 1년의 유예 기간(grace period) 동안 기능이 유지되므로, 기존 v1 서버는 계속 작동합니다. 하지만 새로운 코드는 대체 기능을 채택해야 합니다.
샘플링 (Sampling)
기존 기능: 샘플링 (Sampling)은 _서버 (server)_가 실행 도중 _클라이언트 (client)_의 LLM에 텍스트 생성을 요청할 수 있게 했습니다 (TypeScript SDK의 createMessage를 통해). 이는 클라이언트의 모델을 빌려와 내부적으로 추론하고 의사결정을 내릴 수 있는 "에이전트형 서버 (agentic servers)"를 구현하는 기반이 되었습니다.
제거되는 이유: 샘플링은 서버가 클라이언트의 요청을 처리하고 있지 않은 동안에도 클라이언트에게 다시 접근해야 하므로, 지속적이고 상태를 유지하는 연결 (stateful connection) 환경에서만 작동합니다. 이것이 바로 v2에서 제거하는 가정이기도 합니다. 상태가 없는 (stateless) 환경에서는 귀하의 요청을 처리하는 서버가 클라이언트와의 연결을 유지하고 있는 서버와 전혀 다를 수 있습니다.
대체 기능:
- LLM 제공자 API와의 직접 통합 (Direct integration with LLM provider APIs). 서버에 모델이 필요한 경우, 서버에서 제공자 (Anthropic, OpenAI 등)를 직접 호출하십시오. 모델, 키, 그리고 비용을 직접 제어할 수 있습니다.
InputRequiredResult패턴: 작업 도중 클라이언트로부터 실제로 무언가가 필요한 경우를 위한 방식입니다. 실시간 콜백 (callback) 대신, 서버는 "이 입력이 필요합니다"라고 명시하는 결과를 반환하고, 클라이언트는 해당 답변과 함께 요청을 재시도합니다. 각 왕복 (round-trip)은 새롭고 독립적인 요청이므로, 어떠한 서버 인스턴스에 대해서도 재시도가 가능하며 상호작용을 상태가 없는 (stateless) 상태로 유지할 수 있습니다.
현재 샘플링을 사용 중이라면, 이는 실제 재작업이 가장 많이 필요할 가능성이 높은 지원 중단 사항입니다. 왜냐하면 대체 방식이 모델 호출이 일어나는 _위치_를 바꾸기 때문입니다 (클라이언트 측이 아닌 서버 측).
루트 (Roots)
기존 기능: 루트 (Roots)는 클라이언트가 서버가 작동할 범위를 지정하기 위해 제공하는 URI였습니다. 예를 들어, 코드 분석 서버에 어떤 디렉토리를 스캔해야 하는지 알려주기 위해 file:///home/user/my-project와 같은 값을 제공하는 식입니다. 서버는 listRoots()를 통해 이를 읽어 들였습니다.
제거되는 이유: 루트는 클라이언트에서 서버로 전달되어 연결이 유지되는 동안 보관되는, 세션 범위의 상태 (session-scoped state)의 또 다른 형태였습니다.
대체 기능: 동일한 정보를 요청마다 명시적으로 전달하십시오:
- 도구 파라미터 (Tool parameters) — 작업 디렉터리(working directory)나 범위(scope)를 도구 입력값으로 받습니다.
- 리소스 URI (Resource URIs) — 요청되는 리소스 내에 범위를 직접 인코딩합니다.
- 서버 설정 (Server configuration) — 범위가 정적인 경우 배포 시점에 경계를 설정합니다.
로깅 (Logging)
기존 방식: MCP 프로토콜을 통해 서버에서 클라이언트로 전송되며, 클라이언트가 설정한 레벨(logging/setLevel)에 따라 필터링되는 구조화된 로그 메시지였습니다.
삭제되는 이유: 프로토콜 수준의 로깅은 관찰성(observability)을 활성화된 클라이언트 연결에 종속시켰습니다. 이는 상태가 없는(stateless) 멀티 인스턴스 배포 환경에서는 까다로우며, 이미 존재하는 도구들과 기능이 중복됩니다.
대체 기능:
- stderr — stdio 전송 방식의 경우 표준 에러(standard error)를 사용합니다. 로그를 표준 에러로 작성하면 호스트가 이를 캡처합니다. (이는 stdout이 프로토콜용으로 예약되어 있기 때문에, v1에서도 stdio 서버에 권장되었던 방식입니다.)
- OpenTelemetry — 구조화된 프로덕션급 관찰성을 위해 사용합니다. MCP를 통하는 대신 기존의 OTel 파이프라인으로 트레이스(traces)와 메트릭(metrics)을 방출하십시오.
상태가 없는(Stateless) 전환이 SDK에 의미하는 것
지원 중단(deprecation) 사항 외에도, 상태가 없는 방식(statelessness)은 모든 SDK의 인터페이스 전반에 영향을 미칩니다. 세부 사항은 언어마다 다르며, v2 SDK는 아직 안정화 단계에 있으므로, 이는 정확한 심볼(symbol) 목록이라기보다 _어떤 종류_의 변화를 예상해야 하는지에 대한 지도입니다. 어떤 SDK를 사용하든 세 가지 패턴이 나타납니다:
- 트랜스포트(Transports)의 재구성. 세션(session)을 제거하는 것은 트랜스포트 레벨의 변경 사항입니다. 따라서 HTTP 트랜스포트의 이름이 변경되거나 런타임(runtime)별로 분리될 것을 예상해야 하며, 기존의 SSE 트랜스포트(지속적인 스트림을 중심으로 구축된 두 개의 엔드포인트 설계)는 사라질 것으로 예상됩니다. 단일화된 통합 요청/응답(request/response) 트랜스포트는 상태가 없는(stateless) 모델에 적합하지만, 수명이 긴 스트림은 그렇지 않습니다.
- 에러가 프로토콜 에러(protocol errors)와 로컬 SDK 에러(local SDK errors)로 분리됩니다. v2는 "요청 자체가 잘못됨"("the request itself was malformed", 상대방이 인지해야 하는 와이어 프로토콜(wire-protocol) 에러)과 "HTTP 연결이 끊어지는 것과 같이 로컬에서 무언가 실패함" 사이의 경계를 더 명확하게 긋습니다. 만약 귀하의 코드가 에러 타입을 검사한다면, API에서 이러한 구분이 나타날 것을 예상해야 합니다.
- 요청 컨텍스트(Request context)가 트랜스포트를 인식하게 됩니다. stdio 서버는 뒤에 HTTP 요청이 없기 때문에, 요청당 컨텍스트(per-request context) 객체는 프로토콜 레벨의 필드와 트랜스포트 특정 필드(HTTP를 통해서만 존재하는 인증 정보 등)를 분리합니다. 핸들러(Handlers)는 이러한 선택적 필드들을 방어적으로 읽습니다.
이 중 어떤 것도 당장 조치를 취할 필요는 없습니다. 이는 귀하가 어떤 언어로 개발하든, 향후 마이그레이션(migration)이 귀하의 코드베이스에 미칠 영향을 가늠할 수 있도록 하는 지도입니다. SDK가 안정화(stable) 단계에 도달하면, 각 언어별 가이드를 통해 구체적인 이름 변경 사항을 안내해 드릴 예정입니다.
지금 마이그레이션해야 할까요?
짧은 답변: 프로덕션(production) 환경이라면, 아직은 아닙. 2026년 7월 초 기준 상황은 다음과 같습니다:
- v2 SDK는 전반적으로 아직 pre-stable(안정화 전) 단계입니다. TypeScript 및 Python SDK는 베타(beta) 상태이며, Go 및 C#은 프리릴리스(pre-release)/프리뷰(preview) 빌드 단계에 있습니다. 정확한 버전은 빠르게 변동되므로, 여기에 인용된 숫자를 신뢰하기보다는 각 SDK의 릴리스를 확인하십시오.
- 안정화(Stable)가 머지않았습니다. 스펙(spec)은 2026년 7월 28일에 확정되며, 안정화된 SDK 릴리스도 비슷한 시기에 이루어질 것으로 예상됩니다.
- 베타 버전은 선택 사항(opt-in)입니다. SDK를 업그레이드한다고 해서 서버가 자동으로 새로운 프로토콜 개정(protocol revision)으로 전환되지는 않습니다. v2 동작을 채택할 시점은 직접 선택할 수 있습니다.
- 실험 중이라면 정확한 버전을 고정(Pin)하십시오. pre-stable 빌드와 안정화 버전 사이에서 퍼블릭 API(Public APIs)가 변경될 수 있으므로, 유동적인 버전 범위(floating version range)를 사용하면 시스템이 중단될 수 있습니다.
대부분의 팀을 위한 합리적인 계획:
- 현재: 스펙 변경 사항(본 문서)을 읽으십시오. 샘플링(sampling), 루트(roots), 로깅(logging) 사용 사례에 대해 서버를 감사(audit)하십시오. 세션 상태(session state)에 의존하는 부분을 기록해 두십시오.
- 안정화 시점(7월 28일 이후): 먼저 중요도가 낮은 서버를 업그레이드하십시오. 이름이 변경된 임포트(imports)와 지원 중단된 서브시스템(deprecated subsystems)을 처리하십시오.
- 유예 기간 내에: 지원 중단된 서브시스템이 제거되기 전에 나머지를 마이그레이션(migrate)하십시오.
새로운 기능: 확장(Extensions)
v2는 단순히 기능을 빼기만 하는 것이 아닙니다. 또한 **역도메인 네임 식별자(reverse-DNS identifiers)**와 **독립적인 버전 관리(independent versioning)**를 갖춘 **확장(extensions)**을 일급 프로토콜 구성 요소(first-class protocol components)로 공식화합니다. 이제 기능을 핵심 스펙에 덧붙이는 대신, 버전이 지정된 확장 기능으로서 진화할 수 있습니다.
v2와 함께 두 가지 공식 확장이 출시됩니다:
- MCP Apps — 서버 렌더링 UI(server-rendered UIs)로, 서버가 텍스트와 구조화된 데이터만 반환하는 대신 사용자에게 풍부한 인터페이스를 제공할 수 있습니다.
- Tasks — 장기 실행 작업(long-running operations)을 위한 표준 패턴으로, 서버가 단일 요청보다 오래 지속되는 작업을 시작하고 이에 대해 보고할 수 있습니다. 이는 상태가 없는(stateless) 핵심 기능과 자연스럽게 결합됩니다. 즉, 작업(task)은 하나의 연결에 묶이지 않고 인스턴스 전반에서 주소 지정이 가능합니다.
확장 모델(extension model)이 MCP의 향후 기능 성장의 상당 부분을 담당할 것으로 예상됩니다. 이는 확장이 전체 사양 개정(spec revision)을 기다리지 않고도 배포 및 버전 관리가 가능하기 때문입니다.
기존 v1 서버에 미치는 영향
현재 운영 중인 MCP 서버가 있다면, 7월 28일에 아무것도 깨지지 않습니다. 요약하자면 다음과 같습니다:
- v1 서버는 계속 작동합니다. 지원 중단(Deprecations)에는 1년의 유예 기간이 주어집니다.
- 마감 기한에 맞춰 강제로 마이그레이션(migration)해야 하는 것은 아닙니다. 유예 기간이 끝나기 전까지 마이그레이션을 완료해야 할 뿐입니다.
- 가장 큰 실질적인 변화는 샘플링(sampling)입니다. Roots와 로깅(logging)은 이미 절반쯤 진행했을 수도 있는 명확한 대체 수단이 있습니다. 샘플링은 모델 호출(model call)을 클라이언트에서 서버로 이동시키는데, 이는 단순한 이름 변경이 아닌 아키텍처의 변화(architectural shift)입니다.
- 무상태성(Statelessness)은 대규모로 운영할 경우 축복입니다. 인프라에서 스티키 세션(sticky-session)의 복잡성을 제거해 줍니다.
지금 계획을 세우고, 안정적인 버전에서 마이그레이션하십시오. 그러면 1년이라는 충분한 준비 기간을 가질 수 있습니다.
리소스
- MCP 2026-07-28 Release Candidate — 소스에서 직접 전달하는 프로토콜 변경 사항
- MCP SDK v2 Betas — 언어별 베타 상태 및 버전
- TypeScript SDK v2 Migration Guide — 구체적인 TS 업그레이드 경로
- MCP Specification — 전체 프로토콜 사양
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기