본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 06. 20:32

MCP 2026-07-28 RC: 무상태 전송 (Stateless Transport)

요약

MCP 2026-07-28 RC는 기존의 스티키 라우팅 방식을 탈피하여 무상태 전송(Stateless Transport) 아키텍처를 도입합니다. 이를 통해 세션 종속성을 제거하고 서버의 수평적 확장성과 장애 복구 능력을 대폭 향상시킵니다.

핵심 포인트

  • 무상태 전송 도입으로 특정 서버 인스턴스 종속성 제거
  • 스티키 라우팅 없이 플릿 내 어떤 서버든 요청 처리 가능
  • 수평적 확장, 블루/그린 배포, 장애 복구 용이성 확보
  • 상태가 필요한 경우 공유 저장소를 활용하는 자기 완결적 요청 구조

무엇인가 (What): **MCP 2026-07-28 릴리스 후보 (release candidate)**는 전송 (transport) 방식을 재설계하여, tools/call 요청 자체가 서버가 이를 처리하는 데 필요한 모든 필드(프로토콜 버전, 기능 (capabilities), 인증 컨텍스트 (auth context), 라우팅 키 (routing keys))를 포함하도록 합니다. 핵심적인 프레임워크는 **무상태 전송 (stateless transport)**입니다. 즉, 특정 인스턴스에 세션별로 고정될 필요 없이 플릿 (fleet) 내의 어떤 서버라도 모든 요청을 처리할 수 있습니다.

이유 (Why): 이전 설계는 **스티키 라우팅 (sticky routing)**을 강제했습니다. 세션이 수명 동안 단일 서버에 종속되었기 때문에, 로드 밸런서 (load balancer)가 세션 ID별로 연결을 고정하거나 세션 상태를 대역 외 (out-of-band)로 복제해야 했습니다. 이로 인해 수평적 확장 (horizontal scaling), 블루/그린 배포 (blue/green deploys), 장애 복구 (crash-recovery) 모두에 어려움이 있었습니다. 2026-07-28 RC는 차기 안정화된 MCP 사양 (spec)의 핵심 변경 사항이며, MCP와 통신하는 모든 하네스 (harness)에 영향을 미칩니다.

이전 버전과의 비교 (vs prior): 초기 MCP 전송 방식은 첫 번째 요청을 서버 로컬 상태를 설정하는 핸드셰이크 (handshake)로 취급했습니다. 따라서 이후의 요청들은 반드시 동일한 인스턴스에 도달해야 했습니다. 새로운 설계는 프로세스 내 세션 (in-process session)을 제거합니다. 각 요청은 자기 완결적 (self-contained)이며, 요청 간에 지속되는 상태(구독 (subscriptions), 샘플링 세션 (sampling sessions), 인증 토큰 (auth tokens))가 진정으로 필요한 경우에는 특정 서버의 메모리가 아닌, 어떤 서버든 읽을 수 있는 **공유 저장소 (shared store)**에 저장됩니다.

비유하자면

창구가 많은 우체국의 주소가 적힌 봉투와 같습니다.

                    tools/call  (편지 한 통)
                              │
                ┌─────────────┴─────────────┐
...
  • tools/call = 직원에게 편지를 전달하는 것
  • 스티키 라우팅 (sticky routing) = 자신의 책상에 있는 수첩에만 배송 정보를 기록하는 직원 — 상태를 확인하려면 반드시 '그' 직원에게 다시 와야 함
  • 자기 완결적 요청 (self-addressed request) = 봉투에 목적지, 발신인, 추적 ID가 인쇄된 편지 — 어떤 창구에서도 읽을 수 있음
  • 공유 세션 저장소 (필요한 경우) = 우체국의 중앙 추적 데이터베이스 — 어떤 직원이라도 이를 조회할 수 있음
  • 수평적 확장 (horizontal scaling) = 같은 사무실에 창구를 열 개 더 여는 것; 어떤 창구라도 당신을 응대할 수 있음

빠른 용어 사전 (Quick glossary)

MCPModel Context Protocol — LLM 호스트를 외부 도구 서버(tool servers)에 연결하기 위한 개방형 프로토콜입니다. 호스트는 모델과 에이전트의 도구 루프(tool loop)를 실행하며, 서버는 JSON-RPC를 통해 도구(tools), 리소스(resources), 프롬프트(prompts)를 노출합니다.

SEPSpecification Enhancement Proposal — MCP의 RFC 스타일 변경 문서입니다. 2026-07-28 RC에는 전송(transport) 재작업, 새로운 확장(Extensions) 프레임워크, MCP 앱(Apps), 작업(Tasks), 그리고 권한 부여(authorization) 수정 사항을 다루는 22개의 범위 지정된 SEP가 포함되어 있습니다.

Sticky routing (스티키 라우팅) — 세션 ID를 해당 세션의 수명 동안 단일 백엔드 인스턴스에 고정하는 로드 밸런싱(load-balancing) 패턴입니다. 로드 밸런서는 세션 ID를 해싱하여 항상 동일한 서버로 라우팅합니다. 해당 서버에 과부하가 걸리거나, 재시작되거나, 교체되기 전까지는 잘 작동합니다.

Self-contained request (자기 완결적 요청) — 서버가 요청을 처리하는 데 필요한 모든 필드 — 프로토콜 버전, 선언된 클라이언트 기능(capabilities), 라우팅 키, 인증 컨텍스트(auth context) — 가 요청 자체와 함께 전달되는 요청 형태입니다. 서버는 동일한 소켓(socket) 상의 이전 메시지로부터 어떠한 사전 상태(prior state)도 가정하지 않습니다.

Shared session store (공유 세션 저장소) — 플릿(fleet) 내의 어떤 서버라도 읽고 쓸 수 있는 프로세스 외 저장소(Redis급, 데이터베이스, 오브젝트 스토어 등)입니다. 요청 간 상태(cross-request state)가 진정으로 필요한 소수의 MCP 상호작용 — 장기 구독(long-lived subscriptions), 샘플링 세션(sampling sessions), OAuth 토큰 등 — 에 사용됩니다. 전송(transport) 자체는 여전히 무상태(stateless)이며, 저장소는 요청 간에 유지되어야 하는 상태를 위한 하나의 _구현 패턴(implementation pattern)_입니다.

Tasks extension (SEP-2663) (작업 확장) — 오래 실행되는 도구를 위한 비동기 핸들(async-handle) 모델입니다. 서버는 Task 핸들을 반환하며, 클라이언트는 tasks/get, tasks/update, tasks/cancel을 통해 이를 제어합니다. 작업 핸들이 클라이언트가 필요로 하는 유일한 요청 간 키(cross-request key)이기 때문에 무상태 전송(stateless transport)과 자연스럽게 결합됩니다.

뉴스. 2026년 5월 22일, MCP 프로젝트에 PR #2750이 반영되었습니다 — 이는 2026-07-28 사양 출시 후보(release candidate)에 대한 블로그 공지입니다. 해당 포스트는 무상태 전송(stateless transport) 재작업을 주요 변경 사항으로 내세우며, 이전과 이후의 HTTP 예시를 통해 자기 완결적인 tools/call 요청을 보여줍니다. 확장 기능(Extensions), MCP 앱(MCP Apps), 그리고 태스크(Tasks)가 새로운 기능적 이야기로 이어지며, 권한 부여(authorization) 변경 사항은 SEP(Specification Extension Proposal)별로 나열하기보다 해결하는 실패 모드(failure modes)를 중심으로 요약되었습니다. 범위가 지정된 22개의 모든 SEP는 공지사항에서 링크로 연결되어 있습니다.

창구가 많은 우체국을 상상해 보세요. 느린 경로는 **고정된 직원(sticky clerk)**과 같습니다. 당신이 3번 직원에게 편지를 건네면, 3번 직원은 그 세부 사항을 자신의 서랍에 있는 개인 수첩에만 적어둡니다. 만약 당신이 배송 상태를 확인하러 다시 온다면, 반드시 그녀의 창구에서 기다려야 합니다 — 다른 어떤 직원도 당신에게 아무것도 말해줄 수 없습니다. 만약 3번 직원이 바쁘거나, 휴식 시간에 들어가거나, 퇴사한다면, 당신의 배송 추적 정보는 그녀와 함께 사라집니다. 그녀의 창구 앞 줄은 길어지지만, 다른 창구들은 조용합니다. 이것이 바로 현재의 스티키 라우팅(sticky-routed) 방식의 MCP가 처한 모습입니다. 에이전트의 도구 사용(tool-use) 루프가 세션을 열면, 로드 밸런서(load balancer)가 해당 세션을 특정 서버에 고정(pin)시키고, 모든 후속 호출은 반드시 동일한 서버로 전달되어야 합니다. 한 서버에만 트래픽이 몰리고, 나머지 서버들은 유휴 상태로 남게 됩니다.

빠른 경로는 **자주식 봉투 (self-addressed envelope)**와 같습니다. 모든 편지 앞면에 수신인, 발신인, 추적 ID를 적어두면, 우체국 직원이 귀하의 배송에 관한 어떤 것도 기억할 필요가 없어집니다. 어느 창구라도 상관없습니다. 이것이 2026-07-28 프레이밍 (framing)의 핵심입니다. 각 tools/call은 자신이 기대하는 프로토콜 버전, 클라이언트가 선언한 기능 (capabilities), 서버 플릿 (server fleet)에 필요한 라우팅 키 (routing keys), 그리고 인증 컨텍스트 (auth context)를 요청 자체에 모두 담아 전달합니다. 서버는 봉투를 읽고 즉시 행동합니다. 따로 기록해둘 수첩도, "나중에 다시 오세요"라는 말도 필요 없습니다. 0.5초 후에 도착하는 두 번째 요청이 완전히 다른 서버에 도달하더라도 동일한 동작을 수행할 수 있습니다.

명확히 짚고 넘어갈 만한 미묘한 차이가 있습니다. 몇몇 MCP 상호작용은 실제로 요청 간의 메모리 (cross-request memory)를 필요로 합니다. 예를 들어 장기 구독 (long-lived subscriptions), 샘플링 세션 (sampling sessions), 단일 호출보다 오래 유지되어야 하는 OAuth 토큰 등이 이에 해당합니다. 새로운 설계는 이러한 것들이 존재하지 않는 척하지 않습니다. 대신 이를 외부화합니다. 비유에서 언급한 중앙 추적 데이터베이스는 서버가 요청 간의 상태 (cross-request state)를 복원 (hydrate)해야 할 때 쿼리할 수 있는 공유 저장소 (shared store) (Redis와 유사한 것, 데이터베이스, 또는 오브젝트 스토어)입니다. 전송 (transport)은 여전히 무상태 (stateless)입니다. 즉, 요청 자체가 자급자족적 (self-contained)입니다. 공유 저장소라는 _구현 패턴 (implementation pattern)_이 아주 작은 조각의 상태 유지 (stateful) 동작이 플릿 전체에서 작동할 수 있게 만드는 것입니다. 이 두 개념을 혼동하기 쉬우나 명확히 구분할 가치가 있습니다. 프로토콜의 변경은 전송 계층 (transport layer)에서 이루어지는 것이며, 공유 저장소는 서버가 요청보다 오래 유지되어야 하는 최소한의 상태를 영속화 (persist)하기 위해 선택할 수 있는 하나의 방법입니다.

용량(capacity)에 대한 논거는 설명할 필요도 없이 명확합니다. 300개의 동시 에이전트 세션이 있고, 각 세션이 초당 약 2회의 호출로 MCP 트래픽을 유지하며 3대의 서버 플릿(fleet)에 접속한다고 가정해 봅시다. 스티키 라우팅(Sticky routing)은 세션이 열릴 때 각 세션을 하나의 서버에 할당합니다. 부하는 거의 균등하게 분산되지 않습니다. 34개의 "헤비 유저(power user)" 세션이 한 서버의 부하를 포화 상태 근처까지 몰아붙이는 동안, 다른 서버들은 1020% 수준에 머물 수 있습니다. 수치로 보면, 전형적인 스티키 불균형(sticky-imbalance) 실행 시 S1은 약 92%의 사용률을 보이는 반면, S2와 S3는 각각 약 8%와 약 41%에 머물 수 있습니다 (예시). 동일한 워크로드 하에서 무상태 전송 (Stateless transport)을 사용하면, 로드 밸런서(load balancer)가 모든 호출을 독립적으로 분산(spray)할 수 있습니다. 초당 600회의 동일한 호출이 세 대의 서버에 각각 약 49%씩 도달하게 되며 (예시), 이는 수직 확장(vertical scaling)을 수행하기 전 가용 플릿 헤드룸(fleet headroom) 측면에서 약 1.9배의 개선을 의미합니다.

재작업(rework)이 가치를 증명하는 지점

에이전트 하네스(agent harness) 세계에서 스티키 라우팅의 실패 모드(failure modes)는 잘 알려져 있습니다. 즉, 하나의 서버에 부하가 집중되거나, 블루/그린 배포(blue/green deploys) 시 세션을 비우기 위해 몇 분 동안 대기해야 하거나, 투명하게 경로를 재설정할 수 없는 장애 복구(crash recovery) 문제입니다. 2026-07-28 RC는 전송(transport) 계층에서 이 세 가지 문제를 모두 해결합니다. 자기 완결적(Self-contained) 요청은 그 무엇에도 고정되지 않으므로, 서버를 순환 교체(roll out)하는 배포는 몇 초 내에 완료됩니다. 대기 중인 요청은 단순히 다음 서버로 전달될 뿐입니다. 서버가 충돌(crash)하면 진행 중이던 요청은 중단되지만, 클라이언트는 플릿을 대상으로 재시도합니다. 다음 호출은 다른 곳에 도달하여 진행됩니다. 충돌 시 살아남아야 하는 유일한 상태는 워크로드가 공유 저장소(shared store)에 저장하기로 선택한 것이며, 이는 상호작용의 아주 적은 부분에 불과합니다.

RC가 실제로 변경하는 사항의 형태는 구체적입니다. 아래 표는 기존(legacy) 전송 방식과 새로운 전송 방식을 대조하여 보여줍니다.

측면 (Aspect)스티키 라우팅 전송 (Sticky-routed transport, 기존 방식)무상태 전송 (Stateless transport, 2026-07-28 RC)
세션 수명 (Session lifetime)세션 수명 동안 하나의 서버에 결합됨세션별 서버 결합 없음
...

관련된 설계 포인트 중 알아둘 만한 내용이 있습니다. Tasks 확장 (SEP-2663)은 한 단계 위 계층에서 상호 보완적인 아이디어를 제공합니다. 즉, 클라이언트에게 재연결 시에도 폴링 (polling) 할 수 있는 수명이 긴 taskId를 제공하는 것입니다. SEP-2663이 완전히 유용하게 작동하려면 전송 방식의 재작업이 필요했습니다. 재연결 시 폴링되는 taskId는 다음 tasks/get 요청이 핸들을 발행했던 동일한 서버로 전달되지 않아도 작동해야 하기 때문입니다. 무상태 전송 (Stateless transport)이 바로 이를 가능하게 합니다. 클라이언트는 taskId라는 유일한 요청 간 키 (cross-request key)를 지니고, 서버 플릿 (server fleet)은 공유 저장소 (shared store)로부터 작업 상태를 수화 (hydrate)하며, 폴링 호출은 가장 한가한 서버로 전달됩니다.

RC가 변경하는 범위는 프로토콜 의미론 (protocol semantics)이 아니라 전송 (transport) 그 자체입니다. 도구 (tools)는 여전히 도구 결과를 반환하고, 리소스 (resources)는 여전히 리소스 콘텐츠를 반환하며, 메서드 호출의 와이어 포맷 (wire format)은 동일한 JSON-RPC 엔벨로프 (envelope)를 사용합니다. 변하는 것은 서버가 가정할 수 있는 범위입니다. 즉, 동일한 연결에서의 이전 호출에 대해 어떠한 것도 가정할 수 없게 됩니다. 이 단 하나의 원칙만으로도 모든 하네스 운영자 (harness operator)의 삶을 더 편하게 만들 수 있으며, 비용 및 지연 시간 (Cost & Latency) 모듈에서 권장하는 병렬 도구 호출 (parallel-tool-call) 패턴을 플릿 내에서 실제로 구현 가능하게 만듭니다.

FAQ

MCP 2026-07-28 RC에서 무상태 전송 (stateless transport)이란 무엇을 의미하나요?

이는 tools/call 요청 자체가 서버가 이를 처리하는 데 필요한 모든 필드—프로토콜 버전, 선언된 클라이언트 기능 (capabilities), 라우팅 키 (routing keys), 인증 컨텍스트 (auth context)—를 포함한다는 것을 의미합니다. 서버는 동일한 연결에서의 이전 호출로부터 어떠한 상태도 가정할 수 없습니다. 그 결과, 플릿 내의 어떤 서버라도 모든 요청을 처리할 수 있으므로 로드 밸런서 (load balancer)에서 스티키 세션 (sticky session) 결합이 필요하지 않게 됩니다.

요청 간에 반드시 유지되어야 하는 상태를 위한 스티키 라우팅 (sticky routing)은 무엇으로 대체되나요?

공유 저장소 (shared store)입니다. 교차 요청 메모리(cross-request memory)가 필요한 MCP 상호작용의 작은 하위 집합 — 장기 구독(long-lived subscriptions), 샘플링 세션(sampling sessions), OAuth 토큰 — 은 특정 서버의 프로세스 외부로 이동하여, 전체 플릿(fleet)이 읽을 수 있는 Redis급 저장소(또는 데이터베이스, 오브젝트 스토어)로 옮겨집니다. 전송(transport) 자체는 여전히 무상태(stateless)입니다. 공유 저장소는 요청 간에 유지되어야 하는 상태의 조각을 위한 구현 패턴입니다.

전송 재설계가 Tasks 확장(SEP-2663)과 어떤 관련이 있나요?

이들은 상호 보완적으로 작동합니다. SEP-2663은 서버가 클라이언트가 나중에 폴링(polling)할 수 있는 장기 유지 taskId를 반환할 수 있게 합니다. 무상태 전송은 이러한 폴링이 전체 플릿에 걸쳐 견고하게 작동하도록 만드는 핵심 요소입니다. 즉, 다음 tasks/get 요청이 핸들을 발행했던 동일한 서버에 도달할 필요가 없습니다. 이 둘이 결합되면 에이전트의 허니스(harness)가 세션 어피니티(session affinity) 없이도 서버 재시작, 블루/그린 배포(blue/green deploys), 로드 밸런서 재편성(load-balancer reshuffles) 상황에서 생존할 수 있습니다.

무상태 전송을 지원하기 위해 기존 MCP 서버 코드에서 무엇을 변경해야 하나요?

구체적으로는 다음과 같습니다: 연결(connection)로부터 상태를 읽는 것을 중단해야 합니다. 서버가 세션 설정 시 한 번 학습하고 연결 수명 동안 기억했던 모든 필드 — 선언된 클라이언트 기능(capabilities), 프로토콜 버전, 인증 신원(auth identity), 라우팅 테넌트(routing tenant) — 는 이제 각 tools/call 요청으로부터 읽어야 합니다. 이미 모든 결정을 들어오는 요청 페이로드(payload)를 기반으로 내리던 서버는 변경 사항이 최소화될 것입니다. 연결별 캐시(협상된 기능, OAuth 인트로스펙션 결과, 테넌트 라우팅 결정 등)를 구축해 온 서버는 해당 캐시를 전체 플릿이 읽을 수 있는 공유 저장소로 외부화하거나, 클라이언트가 다시 보낼 수 있도록 클라이언트로 밀어내야 합니다. 대부분의 프로덕션 MCP 서버는 그 중간 단계에 위치할 것입니다. 즉, 전면 재작성보다는 몇 가지 작은 마이그레이션이 필요할 것입니다.

무상태 전송이 MCP 인증(authentication) 및 인가(authorization)에 어떤 영향을 미치나요?

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0