MCP가 무상태(Stateless)로 전환되다: 2026-07-28 사양의 실제 변화
요약
Model Context Protocol(MCP)이 2026-07-28 사양을 통해 핸드셰이크와 세션 ID를 제거하고 무상태(Stateless) 프로토콜로 전환되었습니다. 이로 인해 별도의 세션 저장소 없이도 로드 밸런싱이 가능해졌으며, 서버리스 및 에지 인프라에서의 효율적인 운영이 가능해졌습니다.
핵심 포인트
- 핸드셰이크 및 세션 ID 제거로 인한 무상태(Stateless) 전환
- 공유 세션 저장소 없이 일반 로드 밸런서 환경에서 운영 가능
- 서버리스 및 에지 인프라에서의 MCP 서버 실행 최적화
- OAuth/OIDC 강화 및 도구/프롬프트 목록 캐싱 지원
-
Model Context Protocol (MCP)은 7월 28일에 2026-07-28 사양을 출시하며, 출시 이후 MCP를 상태 유지(Stateful) 및 스트림 유지 프로토콜로 만들었던 핸드셰이크(Handshake)와 세션 ID(Session ID)를 제거했습니다.
-
이제 모든 요청은 자체적인 프로토콜 버전과 식별 정보를 포함하므로, 공유 세션 저장소(Shared session store) 없이도 일반 로드 밸런서(Load balancer) 뒤에 있는 어떤 서버로든 요청이 도달할 수 있습니다.
-
OAuth 및 OIDC가 실제로 강화되었고, 도구(Tool) 및 프롬프트(Prompt) 목록은 캐싱(Cacheable)이 가능해졌으며, 작업(Tasks)은 공식적인 버전 관리 확장 프레임워크로 이동했습니다.
-
Tier 1 SDK들은 이미 이를 지원하며, 통합 MCP SDK 다운로드 수는 월간 약 5억 회를 돌파하여 연초 대비 4배 증가했습니다.
실제로 중요한 변화: MCP가 상태 유지(Stateful)를 중단하다
출시 이후 MCP는 다음과 같이 작동했습니다: 클라이언트가 연결을 열고, initialize 요청을 보내고, initialized 응답을 받으면, 그 시점부터 세션 내의 모든 요청은 해당 특정 핸드셰이크에 연결하는 Mcp-Session-Id 헤더를 포함합니다. 해당 세션을 보유한 서버는 이를 기억해야 하며, 이는 로드 밸런서 뒤에서 하나 이상의 서버 인스턴스를 실행하는 경우, 로드 밸런서가 동일한 클라이언트의 모든 요청을 매번 동일한 인스턴스로 라우팅해야만 작동한다는 것을 의미합니다. 실제 운영 환경에서 MCP 배포를 실행해 본 사람이라면 이러한 요구사항이 실무에서 어떤 결과를 초래하는지 알고 있습니다. 즉, 스티키 라우팅(Sticky routing) 규칙, 어떤 인스턴스든 세션을 이어받을 수 있도록 하는 공유 Redis 세션 저장소, 그리고 요청을 어디로 보낼지 결정하기 위해 요청 본문(Request body)을 열고 파싱해야 하는 게이트웨이가 필요하게 됩니다.
2026-07-28 사양은 해당 모델을 완전히 제거합니다. 핸드셰이크(Handshake), 세션 ID(Session ID), 그리고 서버가 계속 유지하며 기억해야 하는 열려 있는 스트림(Held-open stream)이 더 이상 존재하지 않습니다. 이제 각 요청은 웹의 다른 곳에서 일반적인 HTTP 요청이 그러하듯, 자체적인 프로토콜 버전, 클라이언트 식별 정보(Client identity), 그리고 기능(Capabilities)을 포함하여 독립적으로 전달됩니다. 이러한 단 한 번의 변화 때문에 이번 릴리스에 대한 보도들이 '무상태(Stateless)'라는 단어를 계속 사용하는 것이며, 여러 매체에서 이를 MCP 출시 이후 사양의 가장 큰 변화라고 부르는 이유이기도 합니다. 이는 이제 MCP 서버가 진정한 서버리스(Serverless) 또는 에지(Edge) 인프라에서 실행될 수 있음을 의미합니다. 서버가 기억해야 할 세션 상태(Session state)가 어디에도 없기 때문에, 요청 하나를 처리하기 위해 실행되었다가 바로 사라질 수 있습니다.
실제로 MCP 서버를 상당한 규모로 운영해 본 사람이라면, 자잘한 기능 추가보다 이 부분에 먼저 주목해야 합니다. 왜냐하면 이는 사용자를 지원하기 위해서가 아니라, 프로토콜 설계 방식의 한계를 우회하기 위해 존재했던 인프라 범주 전체를 제거하기 때문입니다.
또한 이는 누가 합리적으로 서버를 구축할 수 있는지의 여부도 바꿉니다. 상태 유지(Stateful) 서버는 요청 사이에 상태를 유지할 장소가 필요하며, 이는 자연스럽게 장기 실행 프로세스(Long-running process), 계속 켜져 있는 컨테이너, 또는 세션 동안 지속되는 메모리를 가진 무언가로 사용자를 유도합니다. 반면 무상태(Stateless) 서버는 이 중 어느 것도 필요하지 않습니다. 깨어나서 하나의 독립적인 요청에 응답한 뒤 다시 잠드는 함수(Function) 형태가 될 수 있으며, 이는 통합(Integration)을 구축할 가치가 있는지 결정해야 하는 개인 개발자나 소규모 팀에게 매우 다른 비용 및 복잡성 프로필을 제공합니다. 기존 모델은 단지 몇 가지 도구(Tools)를 에이전트(Agent)에게 노출하기 위해 장기 실행 프로세스를 운영하고 관리(Babysit)하고 싶지 않은 사람들을 조용히 걸러내고 있었습니다.
기존 메커니즘을 대체한 것
세션 상태(session state)를 제거한다는 것이 상태가 가능하게 했던 기능들을 포기한다는 의미는 아닙니다. 이는 해당 기능들이 대신 무상태(stateless) 요청을 기반으로 재구축되었음을 의미합니다. 사양(spec)은 기존의 패턴, 즉 서버가 호출 중간에 클라이언트에게 무언가를 묻기 위해 연결을 계속 열어두던 방식을 대체하는 멀티 라운드 트립 요청(Multi Round-Trip Requests)을 도입합니다. 대신, 도구(tool)는 여전히 필요한 사항을 설명하는 resultType: "input_required"와 함께 결과를 반환할 수 있으며, 클라이언트는 해당 답변들을 inputResponses에 첨부하여 원래의 호출을 재시도함으로써 응답합니다. 대화는 여전히 이루어지지만, 하나의 길게 유지되는 연결 대신 독립적인 무상태 요청들을 통해 이루어집니다.
라우팅(Routing)에도 병행적인 수정이 이루어졌습니다. 이제 요청은 Mcp-Method 및 Mcp-Name HTTP 헤더를 포함하므로, 게이트웨이(gateway)나 웹 애플리케이션 방화벽(WAF)이 요청이 무엇을 요구하는지 파악하기 위해 JSON 본문(body)을 파싱하는 대신, 다른 모든 종류의 HTTP 트래픽에서 이미 수행하는 방식대로 헤더를 읽어 라우팅 또는 권한 부여(authorization) 결정을 내릴 수 있습니다. 헤더에 충분한 정보를 노출하지 않았던 프로토콜들을 위해 본문 검사(body inspection)만을 수행하는 인프라가 얼마나 많이 존재하는지를 고려한다면, 이는 사소한 세부 사항처럼 들리지 않을 것입니다. 그리고 MCP도 그중 하나였습니다.
도구(tool), 프롬프트(prompt), 리소스 목록(resource list) 응답에도 ttlMs 및 cacheScope 필드가 추가되어, 클라이언트에게 주어진 목록을 다시 요청하기 전에 얼마나 오랫동안 재사용해도 안전한지 정확히 알려줍니다. 이는 이전의 MCP에는 없었던 명확한 캐싱 계약(caching contract)이며, 세션 동안 동일한 서버를 반복적으로 호출하는 모든 에이전트(agent)에서 나타나는 불필요한 재요청(re-fetching)을 직접적으로 줄여줍니다.
마지막 포인트는 문서상에 보이는 것보다 훨씬 더 중요합니다. 이번 사양(spec)이 나오기 전에는, 클라이언트가 서버에 다시 요청하지 않고서는 서버의 도구 목록(tool list)이 여전히 정확한지 알 수 있는 신뢰할 만한 방법이 없었습니다. 따라서 대부분의 구현체는 매번 요청을 낭비하며 끊임없이 재요청(re-fetch)을 하거나, 혹은 무기한으로 캐싱(cache)하여 서버가 제공하는 기능이 변경될 경우 오래된(stale) 목록을 기반으로 동작할 위험을 감수해야 했습니다. 서버가 자체적으로 TTL(Time To Live)을 게시하면 이러한 추측 과정을 완전히 제거할 수 있습니다. 서버가 자신의 신선도 윈도우(freshness window)를 명시하면 클라이언트는 이를 준수하기만 하면 됩니다. 수십 년 동안 HTTP 캐싱을 안정적으로 유지해 온 바로 그 기본적인 계약이, 에이전트들이 끊임없이 의존하는 프로토콜에 마침내 등장한 것입니다.
보안과 레거시 전송 방식(Legacy Transport)과의 작별
권한 부여(Authorization) 관련 변경 사항은 무상태(stateless) 재작성만큼 화려하지는 않지만, 실제 ID 시스템(identity systems) 뒤에서 MCP 서버를 운영하는 모든 이들에게 그만큼 중요합니다. 이제 권한 부여 서버(Authorization servers)는 RFC 9207에 명시된 iss 파라미터를 반환해야 하며, 클라이언트는 권한 부여 코드(authorization code)를 사용하는 전에 이를 검증해야 합니다. 이를 통해 이전 사양에서 허용되었던 권한 부여 서버 간의 혼동 공격(mix-up attacks) 유형을 차단합니다. 클라이언트 자격 증명(Client credentials)은 이제 이를 발급한 특정 권한 부여 서버에 종속되므로, 한 서버에서 얻은 자격 증명을 다른 서버에 재사용(replay)할 수 없습니다. 데스크톱 및 CLI 애플리케이션을 위한 실질적인 배려도 추가되었습니다. 클라이언트는 이제 등록 과정에서 application_type을 선언하여 localhost 리다이렉트(redirect)를 명시적으로 허용할 수 있으며, 이는 대부분의 로컬 개발 도구가 OAuth 콜백(callback)을 처리해야 하는 실제 방식입니다.
기존의 대부분 MCP 클라이언트가 서버에 자동으로 자신을 등록하기 위해 사용하는 메커니즘인 동적 클라이언트 등록 (Dynamic Client Registration, DCR)은 클라이언트 ID 메타데이터 문서 (Client ID Metadata Documents)를 위해 공식적으로 폐기(deprecated)됩니다. 이는 클라이언트가 매번 프로그래밍 방식으로 등록하는 대신, 자신을 설명하는 정적 문서를 게시하는 더 단순한 모델입니다. 다만, 전환 기간 동안 DCR은 계속 작동하므로 하룻밤 사이에 서비스가 중단되는 일은 발생하지 않습니다. 동일한 유예 기간이 기존의 HTTP+SSE 전송 방식과 Roots, Sampling, Logging에도 적용되며, 이들은 모두 제거되기 전 최소 12개월의 기간을 두고 폐기됩니다. 이는 의도적이고 합리적인 선택입니다. 이 정도로 많은 프로덕션 배포(production deployments)가 이루어진 프로토콜은 스위치를 켠다고 해서 모든 서버와 클라이언트가 발맞추어 업데이트할 것을 기대할 수 없으므로, 사양 작성자들은 완충 기간(runway)을 마련해 두었습니다.
한편, 작업 (Tasks)은 실험적인 핵심 기능에서 벗어나 공식적인 버전 관리 기능인 io.modelcontextprotocol/tasks 확장 기능으로 승격되었습니다. 여기에는 폴링 기반(poll-based)의 tasks/get과 단일 요청-응답 사이클에 맞지 않는 장기 실행 작업을 위한 새로운 tasks/update 메서드가 포함됩니다. MCP Apps와 엔터프라이즈 관리형 권한 부여 (Enterprise Managed Authorization) 또한 동일한 프레임워크를 기반으로 구축된 확장 기능으로 도입되었습니다. 이 프레임워크 자체가 이번 변화의 더 지속 가능한 핵심이며, 이제 MCP는 새로운 기능이 나올 때마다 기본 사양 내부에서 자리를 차지하기 위해 다투는 대신, 핵심 프로토콜을 매번 수정하지 않고도 기능을 추가할 수 있는 실제적이고 문서화된 경로를 갖게 되었습니다.
규모(Scale) 수치가 진짜 헤드라인인 이유
만약 MCP가 소수의 팀만이 사용하는 니치(niche) 프로토콜이었다면 이 모든 것은 그리 중요하지 않았을 것입니다. 하지만 그렇지 않습니다. 생태계 전반의 통합 SDK 다운로드 수는 현재 월간 거의 5억 회에 달하며, 이는 올해 초 이후 4배 증가한 수치입니다. TypeScript와 Python SDK는 각각 총 다운로드 수가 10억 회를 넘어섰습니다. TypeScript, Python, Go, C# SDK는 이미 2026-07-28 사양을 지원하고 있으며, Rust SDK는 베타 버전으로 제공되고 있습니다. 이는 대부분의 에이전트 빌더들이 실제로 사용하는 도구들이 사양이 발표된 직후 거의 즉시 준비되었다는 것을 의미하며, 사양 발표 후 몇 달씩 뒤처지는 상황을 방지했음을 보여줍니다.
그러한 채택 곡선(adoption curve)이야말로 이번 무상태(stateless) 재작성이 단순한 각주가 아닌 핵심 뉴스인 이유입니다. 수백 개의 통합(integration)을 보유한 프로토콜은 파괴적인 아키텍처 변경(breaking architectural change)을 감수하고 그 여파를 조용히 흡수할 여유가 있습니다. 하지만 Claude와 같은 에이전트가 실제로 작동하는 도구, 파일, 서비스들을 연결하는 배관(plumbing) 역할을 하며 월간 다운로드 수가 5억 회에 육박하는 프로토콜은 이러한 변화를 결코 가볍게 결정할 수 없습니다. 12개월의 지원 종료(deprecation) 기간, 하위 호환이 가능한 DCR 폴백(fallback), 그리고 4개의 SDK가 출시 당일에 바로 지원을 시작했다는 사실은 모두 이번 사양 변경이 모든 사용자가 여유가 생길 때까지 기다려주기를 기대하는 백지상태의 재작성(clean-slate rewrite)이 아니라, 기존의 프로덕션 트래픽(production traffic)을 명확히 염두에 두고 설계되었음을 가리킵니다. 저는 이전에 Claude Code에 실제로 연결하여 신뢰할 수 있는 MCP 서버들에 대해 글을 쓴 적이 있는데, 이번 릴리스는 기존의 작동 중인 설정을 첫날부터 변경하도록 요구하지 않으면서도, 그러한 서버들 각각을 더 저렴하게 실행하고 대규모로 더 쉽게 배포할 수 있게 만드는 조용한 변화입니다.
핵심 요약 (Bottom Line)
MCP의 2026-07-28 사양은 실제 프로덕션 트래픽(production traffic)이 프로토콜에 의존하게 될 때 인프라가 성장해야 하는 특정한 방식으로 프로토콜이 성숙해가는 과정입니다. 이는 스티키 라우팅(sticky routing)과 공유 세션 저장소(shared session stores)를 강제했던 상태 유지 세션 모델(stateful session model)을 폐기하고, 어떤 서버 인스턴스라도 처리할 수 있는 자립형 요청(self-contained requests)으로 대체합니다. OAuth 및 OIDC를 둘러싼 보안 강화(security hardening), 목록 결과에 대한 캐싱 계약(caching contract), 그리고 Task 및 App을 위한 공식 확장 프레임워크(formal extensions framework)는 각각 그 자체로도 의미가 있지만, 무상태(stateless) 코어는 MCP 서버가 기존 설계 하에서는 현실적인 옵션이 아니었던 인프라 위에서도 실행될 수 있게 만드는 실질적인 변화입니다. 이미 4개 언어에 걸쳐 SDK 지원이 배포되었고 월간 다운로드 수가 5억 회에 육박하고 있으므로, 이는 에이전트 빌더(agent builders)들이 멀리서 한참 동안 지켜만 볼 수 있는 사양 변경이 아닙니다. 현재 MCP 서버를 운영하고 있다면 마이그레이션(migration) 기간은 넉넉하게 제공되지만, 그 방향은 사실상 선택 사항이 아닙니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기