MCP 차기 스펙 미리보기: 세션을 버리고 상태 비저장으로
MCP 서버를 직접 만들어보신 분이라면 한 번쯤 이런 고민을 해보셨을 것 같은데요. 서버를 여러 대로 늘려서 트래픽을 나눠 받으려는데, 클라이언트마다 세션이 묶여 있어서 같은 서버로만 요청을 보내야 하는 상황 말이죠. 로드밸런서에 스티키 세션을 걸거나, 세션 정보를 따로 저장소에 빼두거나, 방법을 찾긴 하지만 어딘가 번거롭고 찜찜했습니다. 😅
그런데 이번에 공개된 MCP 차기 스펙의 릴리스 후보가 바로 이 지점을 정면으로 건드립니다. 2026년 5월 21일에 공개된 2026-07-28 릴리스 후보는 프로토콜이 세상에 나온 이후 가장 큰 폭의 개정이라고 소개되고 있는데요. 최종 명세는 7월 28일에 확정될 예정입니다. 아직 후보 단계라 세부 사항은 바뀔 수 있지만, 방향성만큼은 분명해서 미리 살펴볼 가치가 충분합니다.
MCP가 처음이시라면 Model Context Protocol 소개를 먼저 읽고 오시면 이 글이 훨씬 잘 읽힐 거예요. 이번 글은 “무엇이 어떻게 바뀌는가”에 초점을 맞춰 정리해 보겠습니다.
가장 큰 변화: 상태 비저장 프로토콜
이번 개정의 핵심을 한 문장으로 요약하면, MCP가 세션 기반에서 상태 비저장(stateless) 구조로 바뀐다는 것입니다.
기존 MCP는 클라이언트와 서버가 연결을 맺을 때 initialize 요청을 보내고 서버가 응답하면 initialized 알림을 보내는 핸드셰이크 과정을 거쳤습니다. 이때 서버는 Mcp-Session-Id라는 헤더로 세션을 발급하고, 이후 모든 요청이 같은 세션에 묶였죠. 한마디로 서버가 “이 클라이언트가 누구였는지”를 계속 기억하고 있어야 했습니다.
차기 스펙은 이 구조를 통째로 들어냅니다. initialize와 initialized 핸드셰이크가 사라지고, 프로토콜 차원의 세션과 Mcp-Session-Id 헤더도 폐지됩니다. 그래서 어떤 점이 좋아질까요? 서버가 더 이상 요청 사이의 상태를 기억할 필요가 없으니, MCP 서버를 평범한 라운드 로빈 로드밸런서 뒤에 그냥 세워두면 됩니다. 어느 서버 인스턴스가 요청을 받든 상관이 없어지는 거죠. 스티키 라우팅도, 인스턴스끼리 공유하는 세션 저장소도, 어느 서버로 보낼지 판단하려고 요청 본문을 들여다보는 일도 필요 없어집니다.
이건 단순한 편의 개선이 아니라, MCP 서버를 일반적인 웹 서비스처럼 운영하고 확장할 수 있게 만드는 토대입니다. 오토스케일링, 무중단 배포, 서버리스 환경 같은 익숙한 HTTP 인프라 위에 MCP를 그대로 얹을 수 있게 되니까요.
그러면 상태는 어디에 둘까?
“세션을 없앤다”는 말을 들으면 자연스럽게 떠오르는 질문이 있죠. 그럼 여러 번에 걸친 대화의 맥락은 어떻게 이어가나요? 🤔
답은 “상태를 클라이언트가 들고 다닌다”입니다. 서버가 상태를 기억하는 대신, 도구 호출 결과로 상태를 가리키는 손잡이(handle)를 클라이언트에게 넘겨주는 방식이에요. 클라이언트는 다음 호출 때 그 손잡이를 인자로 다시 전달합니다.
예를 들어 장바구니를 다루는 서버가 있다고 해봅시다. 개념적으로는 이런 흐름이 됩니다.
1. add_item 호출 → 서버가 basket_id "bk_123"을 결과로 반환
2. add_item 호출 (basket_id="bk_123") → 같은 장바구니에 항목 추가
3. checkout 호출 (basket_id="bk_123") → 결제 진행
서버 입장에서는 매 요청이 독립적입니다. basket_id라는 값만 보고 어떤 장바구니인지 찾아내면 되니까요. 이 패턴이 익숙하게 느껴진다면 정확합니다. 우리가 웹 애플리케이션에서 상태를 데이터베이스에 저장하고 ID로 조회하던 방식과 똑같거든요. MCP가 특별한 세션 메커니즘을 쓰는 대신, 검증된 상태 비저장 설계 관행을 그대로 따르기로 한 셈입니다.
라우팅과 캐싱을 위한 새 헤더
상태 비저장 구조를 제대로 살리려면 인프라 단에서 요청을 빠르게 분류할 수 있어야 합니다. 그래서 두 개의 헤더가 새로 들어왔는데요. Mcp-Method와 Mcp-Name입니다.
POST /mcp HTTP/1.1
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: search
Content-Type: application/json
{"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{"name":"search","arguments":{"q":"otters"},
"_meta":{"io.modelcontextprotocol/clientInfo":
{"name":"my-app","version":"1.0"}}}}
헤더만 봐도 “이건 search 도구를 호출하는 tools/call 요청이구나”를 알 수 있죠. 덕분에 로드밸런서나 게이트웨이가 JSON 본문을 파싱하지 않고도 라우팅을 결정할 수 있습니다. 본문 안에 같은 정보가 들어 있긴 하지만, 본문을 열어보는 비용을 아끼려고 핵심 정보를 헤더로 끌어올린 거예요.
캐싱도 명확해집니다. 응답에 ttlMs와 cacheScope를 담을 수 있게 되었는데요. ttlMs는 응답이 얼마 동안 신선한지를, cacheScope는 이 응답을 사용자끼리 공유해도 안전한지를 나타냅니다. HTTP의 Cache-Control 모델을 그대로 가져온 설계라, 웹 캐싱에 익숙하다면 바로 이해되실 겁니다. 자주 바뀌지 않는 도구 목록 같은 응답을 안전하게 캐시해서 서버 부하를 줄일 수 있게 되는 거죠.
SSE 대신 다중 라운드 트립
기존 MCP에서 서버가 도구 실행 도중 사용자에게 무언가를 물어봐야 할 때는 Server-Sent Events(SSE)로 연결을 계속 열어둔 채 양방향으로 주고받았습니다. 그런데 연결을 길게 유지하는 방식은 상태 비저장 구조와 잘 맞지 않죠. 연결이 곧 상태니까요.
그래서 차기 스펙은 다중 라운드 트립(multi round-trip) 방식으로 바꿉니다. 서버가 추가 입력이 필요하면 연결을 붙잡고 있는 대신, inputRequired 결과를 반환하면서 끝냅니다.
{
"resultType": "inputRequired",
"inputRequests": {
"confirm": {
"type": "elicitation",
"message": "Delete 3 files?",
"schema": { "type": "boolean" }
}
},
"requestState": "eyJzdGVwIjoxLCJmaWxlcyI6WyJhIiwiYiIsImMiXX0="
}
여기서 눈여겨볼 건 requestState 필드입니다. 서버가 “지금까지 진행한 상태”를 인코딩해서 클라이언트에게 넘긴 값이에요. 클라이언트는 사용자에게 “파일 3개를 삭제할까요?”라고 물어 답을 받은 다음, 원래 호출을 다시 보냅니다. 이때 사용자의 답(inputResponses)과 함께 서버가 줬던 requestState를 그대로 되돌려 보내죠. 서버는 그 상태를 복원해 멈췄던 지점부터 이어서 처리합니다.
연결을 계속 유지하는 대신 상태를 주고받으니, 앞에서 본 손잡이 패턴과 철학이 정확히 일치합니다. 모든 요청이 독립적이고, 맥락은 클라이언트가 들고 다니는 거죠.
확장 프레임워크와 MCP Apps
이번 개정은 명세 본체를 가볍게 유지하면서, 부가 기능은 확장(extension)으로 분리하는 방향도 함께 잡았습니다. 확장은 역방향 DNS 형식의 ID로 식별되고 별도 저장소에서 독립적으로 버전이 관리됩니다. 명세 본체와 생명주기가 분리되어 있어서, 명세를 건드리지 않고도 새 기능을 실험하고 발전시킬 수 있게 되는 거예요.
공식 확장 중 눈길을 끄는 건 MCP Apps입니다. 서버가 샌드박스 처리된 iframe 안에서 렌더링할 대화형 HTML 화면을 제공하는 확장인데요. 텍스트 기반 도구 호출을 넘어, 서버가 사용자에게 직접 시각적인 화면을 보여주는 길이 열린 셈입니다.
기존에 실험적 기능으로 들어가 있던 Tasks도 확장으로 재편됩니다. 오래 걸리는 작업을 다루는 기능인데요. 서버가 tools/call에 작업 손잡이로 응답하면, 클라이언트가 tasks/get으로 진행 상황을 조회하고 tasks/update나 tasks/cancel로 제어하는 구조입니다. 다만 2025-11-25 실험적 Tasks API를 이미 쓰고 있었다면 새로운 생명주기에 맞춰 마이그레이션이 필요하니 주의하세요.
인증도 한층 더 단단해집니다
MCP의 인증은 OAuth 2.1 기반으로 설계되어 있는데요. 이 부분은 MCP Authentication 가이드에서 자세히 다뤘으니 배경이 궁금하면 참고하시면 좋습니다.
차기 스펙에서는 여러 건의 제안을 통해 인증이 한층 더 엄격해집니다. 우선 RFC 9207을 따라 인가 응답의 iss(발급자) 매개변수를 반드시 검증하도록 했습니다. 응답이 정말 우리가 신뢰하는 인가 서버에서 온 것인지 확인하는 장치죠. 또한 OpenID Connect의 application_type 선언을 요구하고, 새 인가 서버로 옮겨갈 때는 재등록을 거치도록 했습니다. 전반적으로 “신뢰하되 검증한다”는 원칙을 더 촘촘하게 구현한 방향입니다.
정리되는 기능들
새 기능이 들어오는 만큼, 역할을 다했거나 더 나은 대안이 생긴 기능은 정리됩니다. 이번에 폐기(deprecated)로 표시되는 기능은 세 가지인데요.
- Roots — 클라이언트가 접근 가능한 디렉터리 범위를 알려주던 기능으로, 도구 매개변수나 리소스 URI, 서버 설정으로 대체합니다.
- Sampling — 서버가 클라이언트의 모델에게 추론을 요청하던 기능으로, 서버가 LLM 제공자 API와 직접 통합하는 방식으로 대체합니다.
- Logging — 프로토콜 차원의 로깅으로, 표준 입출력(stdio)이나 OpenTelemetry로 대체합니다.
중요한 점은, 이번 단계에서는 어디까지나 폐기 표시만 한다는 것입니다. 실제 제거까지는 최소 12개월의 유예 기간이 보장됩니다. 갑자기 기능이 사라져서 서비스가 깨지는 일은 없으니, 그동안 차분히 대안으로 옮겨가면 됩니다. 이렇게 활성(Active) → 폐기(Deprecated) → 제거(Removed) 단계를 최소 12개월 간격으로 거치는 기능 생명주기 정책이 이번에 명문화된 것도 의미 있는 변화입니다.
그 밖에 챙겨볼 변화들
큰 줄기 외에도 실무에 영향을 주는 개선이 몇 가지 더 있습니다.
도구의 inputSchema와 outputSchema가 JSON Schema 2020-12를 지원하게 됩니다. oneOf, anyOf, allOf 같은 조합과 조건문, $ref와 $defs 같은 참조를 쓸 수 있어 훨씬 표현력 있는 스키마를 정의할 수 있게 되는데요. 다만 외부 URI를 가리키는 $ref를 자동으로 따라가 역참조하는 것은 금지됩니다. 보안상 임의의 외부 주소를 끌어오지 못하게 막은 거죠. JSON Schema 자체가 생소하다면 JSON Schema로 데이터 구조 정의하고 검증하기를 먼저 보시길 권합니다.
분산 추적도 표준화됩니다. W3C Trace Context를 따르게 되어, OpenTelemetry 호환 백엔드에서 요청이 거쳐 간 전체 경로를 추적할 수 있습니다. 여러 서버와 도구를 거치는 복잡한 호출에서 병목을 찾기가 한결 수월해지겠죠.
마지막으로 작지만 호환성에 영향을 주는 변화가 하나 있습니다. 리소스를 찾지 못했을 때의 오류 코드가 MCP 고유 코드였던 -32002에서 JSON-RPC 표준인 -32602(Invalid Params)로 바뀝니다. 만약 클라이언트 코드에서 -32002를 직접 비교해 처리하고 있었다면 반드시 수정해야 하니 잊지 마세요.
마치며
이번 MCP 2026-07-28 릴리스 후보를 한마디로 정리하면, “MCP를 평범한 HTTP 서비스처럼 다룰 수 있게 만드는 개정”입니다. 세션을 들어내고 상태를 클라이언트가 들고 다니게 하면서, 로드밸런서 뒤에 그냥 세워두면 되는 구조로 바뀌었어요. 헤더로 라우팅하고 HTTP처럼 캐싱하고, 길게 연결을 붙잡는 대신 상태를 주고받는 다중 라운드 트립까지, 결국 모두 같은 뿌리에서 나온 변화입니다. 여기에 확장 프레임워크와 생명주기 정책으로 장기적으로 성장할 수 있는 뼈대도 마련했고요.
지금 당장 코드를 고칠 필요는 없습니다. 아직 릴리스 후보이고, 폐기되는 기능에도 넉넉한 유예 기간이 있으니까요. 다만 MCP 서버를 운영하거나 만들고 계신다면, 세션에 의존하던 부분이 있는지, 오류 코드를 직접 비교하는 곳은 없는지 미리 점검해 두면 7월에 최종 명세가 나왔을 때 한결 여유 있게 대응할 수 있을 거예요.
MCP 생태계를 더 둘러보고 싶다면 서버를 찾고 배포하는 MCP Registry 글도 함께 읽어보시길 추천합니다. 변경 사항의 원문이 궁금하다면 MCP 공식 명세 사이트에서 전체 드래프트를 확인할 수 있습니다.
This work is licensed under
CC BY 4.0