
MCP가 세션 ID를 버리고 스테이트리스(Stateless)가 되는 2026-07-28 사양
요약
Anthropic이 주도하는 MCP(Model Context Protocol)가 세션 ID를 제거하고 스테이트리스(Stateless) 방식으로 전환되는 2026-07-28 사양을 공개했습니다. 이를 통해 서버 확장성 문제를 해결하고, 상태 관리 주체를 서버에서 모델(에이전트)로 명시적으로 이동시켰습니다.
핵심 포인트
- 세션 ID 기반의 핸드셰이크를 삭제하여 서버 확장성 및 로드 밸런싱 문제 해결
- Mcp-Method 등 헤더 기반의 통신으로 딥 패킷 인스펙션 없이 요청 분배 가능
- 상태를 서버가 숨기지 않고 모델이 인자로 직접 다루는 구조로 변경하여 디버깅 및 안전성 향상
- Anthropic의 Messages API와 유사한 스테이트리스 설계 철학 적용
리모트 MCP 서버를 2대 이상 배치하는 순간 밟게 되는 지뢰가 있다. 첫 번째 서버가 발행한 세션 ID를 로드 밸런서(Load Balancer)의 변덕으로 배정된 두 번째 서버가 알지 못한다는 문제다. 이를 피하기 위해 모두 스티키 세션(Sticky Session)을 적용하거나, 공유 세션 스토어(Shared Session Store)를 중간에 두거나, 게이트웨이에서 리퀘스트 바디(Request Body)를 들여다보며 분배해 왔다. 본래 HTTP 세계가 진작에 졸업했을 고충을, AI 에이전트 업계는 2년에 걸쳐 다시 반복하고 있었다.
그 전제를 오늘 공개된 Model Context Protocol의 2026-07-28 사양이 통째로 버렸다. MCP(LLM에 외부 도구 및 데이터를 연결하기 위한 표준 프로토콜. Anthropic이 주도함)에 있어 출시 이후 가장 큰 개정이며, 심지어 파괴적 변경(Breaking Change)을 포함한다. 핵심은 한마디로 말할 수 있다. 프로토콜에서 세션(Session)이라는 개념을 없앴다.
지금까지의 MCP는 클라이언트가 먼저 initialize를 보내고, 서버가 Mcp-Session-Id 헤더를 반환하는 핸드셰이크(Handshake)로 시작되었다. 이후의 리퀘스트는 해당 세션 ID를 들고 다니며, 사실상 '이 서버 인스턴스에 고정'된다. TechCrunch의 취재에서 에이전트 기반 스타트업 Arcade의 Nate Barbettini 씨는 이 구조의 고충을 다음과 같이 지적했다.
"서버 농장의 각 머신이, 다른 머신이 배포한 세션 ID를 전부 알고 있어야만 한다."
2026-07-28 버전은 이 initialize / initialized 핸드셰이크와 Mcp-Session-Id 헤더를 모두 삭제했다(SEP-2567). 모든 리퀘스트가 자기 완결적(Self-contained)이다. 대신 Streamable HTTP의 리퀘스트에는 새로운 헤더가 필수 사항이 되었다.
POST /mcp HTTP/1.1
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
...
Mcp-Method와 Mcp-Name이 있음으로써, 게이트웨이나 레이트 리미터(Rate Limiter)는 내용물(JSON 바디)을 열어보지 않고도 헤더만으로 "어떤 도구의 어떤 조작인지"를 판단하여 분배할 수 있다. 딥 패킷 인스펙션(Deep Packet Inspection)이 필요 없다. 사양 책정을 주도한 David Soria Parra 씨는 독립 매체 The Register에 설계 사상을 "상태를 서버에서 떼어내 와이어(Wire, 통신로) 측으로 옮기는 것"이라고 표현했다. 이는 Anthropic의 스테이트리스(Stateless)한 Messages API와 같은 발상이다.
여기서 오해하기 쉬운 점은, 스테이트리스화가 '상태를 가질 수 없게 된다'는 뜻은 아니라는 점이다. 서버는 이전과 마찬가지로 상태를 유지할 수 있다. 다만 유지하는 방식이 바뀐다. 사양의 표현을 빌리자면, HTTP API가 예전부터 해왔던 방식을 수행하면 된다. 도구가 basket_id나 browser_id와 같은 명시적인 핸들(Handle, 식별자)을 반환하고, 모델이 이를 다음 호출의 일반적인 인자(Argument)로 전달하는 방식이다.
즉 create_basket이 반환한 basket_id를 후속되는 add_item이 인자로 참조한다. 상태는 트랜스포트 계층(Transport Layer) 어딘가에 숨겨지는 것이 아니라, 모델이 읽고 추론할 수 있는 인자로서 겉으로 드러난다. 개인적으로는 이 점이 이번 개정에서 가장 탁월한 부분이라고 생각한다. 에이전트가 자신이 다루는 상태를 "보이지 않는" 채로 조작하게 만드는 설계는 디버깅 측면에서도, 안전성 측면에서도 다루기 어려웠다. 상태를 모델의 손바닥 위로 되돌려 놓은 것이다.
참고로 리퀘스트 메타데이터를 전달하는 방식에 대해서는 보도 간의 차이가 있다. 공식 블로그는 헤더를 강조하는 반면, The Register는 프로토콜 버전과 클라이언트 정보가 _meta 파라미터에 담긴다고 쓰고 있다. 라우팅용 헤더와 그 외의 메타 정보 전달은 별개의 문제로 해석하는 것이 자연스럽지만, SDK로 구현할 때는 자신이 사용하는 언어의 베타 구현을 확인하는 것이 좋다.
세션이 사라진 부수적인 결과로, tools/list와 같은 리스트 계열 응답에 ttlMs와 cacheScope가 추가되었다. HTTP의 Cache-Control을 그대로 도입한 것으로, 클라이언트는 "이 도구 목록이 몇 밀리초 동안 신선한지", "사용자 간에 공유해도 되는지"를 명시적으로 알 수 있다. 결과적으로 스티키 라우팅(Sticky Routing)이나 공유 세션 스토어도 필요 없이, 단순한 라운드 로빈(Round Robin) 로드 밸런서 뒤에서 MCP 서버를 돌릴 수 있게 된다. 운영 비용 측면에서 은근히 효과적인 변화다.
파괴적(breaking)이긴 하지만, 갑자기 작동이 중단되는 것은 아니다. SEP-2577을 통해 세 가지 기능이 비권장(deprecated) 처리되었으나, 적어도 향후 1년 동안은 작동한다.
| 기능 | 상태 | 이행 대상 |
|---|---|---|
| Roots | 비권장 | 도구 인자(tool arguments)・리소스 URI(resource URI)・서버 설정 |
| ... |
Tasks (장시간의 비동기 처리)는 코어(core)에서 확장(Extension)으로 이동하며, tools/call이 태스크 핸들(task handle)을 반환하고 tasks/get・tasks/update・tasks/cancel로 구동되는 형태가 되었다. tasks/list는 삭제되었다. 세션이 없으면 안전하게 스코프(scope)를 끊을 수 없다는 이유가 명확히 기재되어 있다. 이 "세션을 없앴으니, 세션을 전제로 한 API도 정리한다"라는 일관성은 호감을 준다.
새로 설치된 Extensions 프레임워크는 역방향 DNS 형식의 ID를 가지며, extensions 맵에서 능력을 협상(negotiate)한다. 첫 번째 공식 Extension은 서버 측에서 UI를 그리는 MCP Apps(SEP-1865)다. 그 외에도 도구 스키마(tool schema)가 JSON Schema 2020-12를 지원하게 되었고, 리소스 부재 에러가 독자적인 -32002에서 JSON-RPC 표준인 -32602로 변경되었다. 사소해 보이지만 기존 클라이언트의 에러 핸들링(error handling)을 망가뜨릴 수 있으므로 주의가 필요하다.
열광만을 전달하는 것은 성실하지 못한 태도다. Parra 씨 본인도 독자 구현 세력에 대해 "올바르게 수정하는 것은 상당한 노력이 들 것"이라고 인정하고 있다. Stacklok은 하위 호환성(backward compatibility)이 보장되지 않는 점을 경고하고 있으며, 2026-07-28 버전의 서버가 오래된 클라이언트와 작동하지 않을 가능성이 있어 폴백(fallback)이나 변환 계층을 직접 준비해야 할 수도 있다. 사양 스케줄을 보면, 출시 후보(release candidate)는 5월 21일에 확정되었고, 10주간의 검증 기간을 거쳐 오늘 7월 28일이 최종판이 되는 흐름이다.
뒤집어 말하면, 이번 통증은 단 한 번으로 끝내도록 설계되어 있다. 비권장(deprecated)은 최소 12개월이며 그동안 계속 작동한다는 공식 정책이 도입되었고, 표준화 트랙인 SEP는 적합성 스위트(conformance suite)에 대응 시나리오가 포함될 때까지 Final이 될 수 없게 되었다. 사양 측에서는 "2026-07-28 버전을 구현해 두면, 향후 개정 사항에 대해 트랜스포트(transport)나 라이프사이클(lifecycle) 코드를 다시 작성하지 않고도 추종할 수 있을 것"이라고 언급하고 있다.
REST API가 십수 년 전에 배웠던 "스테이트리스(stateless)하게 만들면 수평 확장이 가능하다"라는 교훈을, 에이전트의 도구 계층이 지금 다시 경험하고 있다. 그뿐인 이야기라고 할 수도 있지만, 핸드셰이크(handshake)와 세션 ID라는 두 가지 작은 메커니즘을 제거하는 것만으로 MCP 서버의 운영은 Kubernetes 사용자가 기대하는 일반적인 클라우드 네이티브(cloud-native) 형태에 가까워진다. 만약 당신이 원격 MCP 서버를 운영하고 있다면, 먼저 자신의 도구가 암묵적으로 세션 상태에 의존하고 있지 않은지 점검하고, 의존하고 있다면 핸들을 반환하는 설계로 다시 작성하는 것이 첫걸음이 될 것이다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기