MCP가 세션을 버린 다음에 남은 숙제
MCP의 2026-07-28 스펙에서 initialize/initialized 핸드셰이크가 사라졌습니다(SEP-2575). Mcp-Session-Id 헤더와 프로토콜 레벨 세션도 함께 없어졌습니다(SEP-2567). 프로토콜 버전과 클라이언트 정보, capability는 이제 매 요청 _meta에 실려 다닙니다. 미리 알아야 하면 server/discover를 부르면 되는데, 이것도 필수가 아니라 선택입니다.
결과는 한 줄로 요약됩니다. 원격 MCP 서버는 이제 평범한 HTTP 워크로드입니다. 아무 요청이나 아무 인스턴스에 떨어져도 되고, 스티키 라우팅과 공유 세션 저장소가 프로토콜 층에서 필요 없어졌습니다.
8월 22일 새 로드맵이 나왔습니다. 기능 목록으로 읽으면 다섯 갈래의 할 일 목록입니다. 그런데 항목을 하나씩 따라가 보면 대부분이 세션을 없앤 대가를 뒤늦게 치르는 작업입니다.
사라진 것
7월 스펙이 걷어낸 것은 세션만이 아닙니다.
제거·강등된 것 |
SEP |
대체 |
|---|---|---|
|
SEP-2575 |
매 요청 |
|
SEP-2567 |
클라이언트가 관리하는 명시적 상태 핸들 |
서버 발신 요청 |
SEP-2322 |
Multi Round-Trip Requests |
Tasks (코어 실험 기능) |
SEP-2663 |
|
Roots, Sampling, Logging |
SEP-2577 |
12개월 오프램프 후 폐기 |
Dynamic Client Registration |
- |
Client ID Metadata Documents |
레거시 HTTP+SSE 전송 |
- |
Streamable HTTP |
대신 들어온 것도 있습니다. 리스트 결과가 캐시 가능해져 tools/list, prompts/list, resources/list, resources/read 응답에 ttlMs와 cacheScope가 붙습니다(SEP-2549). 게이트웨이와 WAF가 라우팅과 미터링에 쓸 수 있도록 Mcp-Method, Mcp-Name 헤더가 생겼습니다(SEP-2243). 익스텐션이라는 형식 틀이 생겨 Tasks, MCP Apps, Enterprise Managed Authorization이 그 아래로 들어갔습니다.
세션 제거의 대체재로 가장 중요한 것이 MRTR입니다. 예전에는 서버가 사용자에게 뭘 물어봐야 할 때 클라이언트 쪽으로 요청을 걸었습니다. 세션이 없으니 그럴 수 없습니다. 이제 서버는 resultType: "input_required"와 필요한 요청 목록을 응답으로 돌려주고, 클라이언트가 inputResponses에 답을 담아 다시 부릅니다. 대화가 서버 메모리가 아니라 요청과 응답 사이를 왕복하는 데이터에 담기게 된 것입니다.
상태는 어디로 갔나
이 볼트 블로그의 MCP 1년, 생태계는 어디까지 왔나는 4월에 남은 균열 두 개를 적어 뒀습니다. 하나가 "Streamable HTTP로 원격 배포는 쉬워졌지만 상태 있는 세션이 로드 밸런서와 충돌한다, 표준 방법이 없다"였고, 다른 하나가 세션 격리가 안 되면 한 사용자의 데이터가 다른 세션으로 샌다는 컨텍스트 블리딩이었습니다.
7월 스펙은 두 균열을 한 칼로 처리했습니다. 세션이 없으면 로드 밸런서와 싸울 일도, 세션 사이로 샐 일도 없습니다. GitHub MCP 서버는 이미 새 스펙으로 올라가면서 Redis 세션 저장소를 통째로 걷어냈습니다.
그런데 같은 이야기 안에 반대 방향 사례가 함께 들어 있습니다. 오래 걸리는 작업을 비동기로 처리하는 패턴을 설명하면서, 초기 태스크 상태를 Redis 같은 공유 데이터스토어에 저장하고 클라이언트에 taskId를 돌려주라고 안내합니다. Redis를 없앨 수 있게 됐다는 이야기와 Redis에 넣으라는 이야기가 한 문서에 같이 있습니다.
모순은 아닙니다. 두 상태가 다른 층에 있습니다. 사라진 것은 프로토콜이 강제하던 상태이고, 남은 것은 애플리케이션이 원래 갖고 있던 상태입니다. 스펙도 이걸 명시합니다. 프로토콜 세션을 없앴다고 애플리케이션까지 무상태가 돼야 하는 건 아니고, 상태를 이어가야 하면 HTTP API가 늘 하던 대로 툴에서 명시적 핸들(basket_id 같은 것)을 발급하면 됩니다.
겹쳐 놓으면 보이는 것은 이 지점입니다. 상태가 사라진 게 아니라 책임자가 바뀐 것입니다. 예전에는 프로토콜이 세션 관리를 요구했고, 그래서 모든 구현이 같은 방식으로 틀렸거나 같은 방식으로 맞았습니다. 이제는 각자 알아서 핸들을 설계합니다. 프로토콜 층의 표준화 하나가 사라지면서 애플리케이션 층의 파편화 여지가 열렸다는 뜻이고, 8월 로드맵의 첫 워크스트림이 정확히 그 자리를 다시 메우려는 작업입니다. Tasks 익스텐션을 스펙 본체로 성숙시키고, 서버 발신 이벤트를 웹훅과 채널로 되살리겠다는 항목입니다.
한 가지 덧붙이면, 인프라 쪽 설명에는 수치가 하나도 없습니다. 지연 시간 비교도, 스케일링 측정도 없이 파드 고정이 필요 없어졌고 페일오버가 투명해졌다는 구조적 서술만 있습니다. 이전 병목이 얼마나 컸는지도, 새 이득이 얼마인지도 아직 공개된 숫자로는 확인할 수 없습니다.
신원
7월 스펙의 인가 강화는 목표가 분명했습니다. 서버는 RFC 9728 Protected Resource Metadata를 구현해 인가 서버 발견이 자동으로 되게 하고, 클라이언트는 RFC 8707 Resource Indicators로 토큰이 어느 MCP 서버를 향하는지 명시합니다. 서버가 여럿일 때 토큰이 재사용되는 것을 막는 장치입니다.
여기에 RFC 9207 발급자 검증이 필수가 됐고(SEP-2468), 자격 증명이 발급한 인가 서버에 묶입니다(SEP-2352). 하나의 클라이언트가 여러 MCP 서버에 붙어 있을 때, 뚫린 서버 하나가 다른 서버의 인가 서버인 척하는 mix-up 공격을 프로토콜 층에서 차단합니다. 등록 방식도 Dynamic Client Registration에서 Client ID Metadata Documents로 옮겨 갑니다. 매번 동적으로 등록하는 대신 메타데이터를 발견 가능한 위치에 미리 올려 두는 방식입니다.
닫힌 구멍이 뭔지는 분명한데, 열린 채 남은 구멍도 분명합니다. 이 스펙은 에이전트가 여러 MCP 서버에 걸쳐 자기 자격 증명을 어떻게 관리할지, 수명이 짧은 에이전트 신원을 어떻게 발급하고 회전시킬지를 다루지 않습니다. 그 일은 구현 층에 남겨져 있습니다.
로드맵이 이 공백을 그대로 인정합니다. 원문은 이렇게 적었습니다.
지금의 MCP 인가는 사람이 브라우저에서 접근을 승인하는 것을 중심으로 만들어져 있습니다. 대화형 클라이언트에는 잘 맞지만, 호출자 중에 자기 신원으로 클라우드 워크로드로 돌아가는 에이전트, 자리에 없는 사용자를 대신하는 에이전트, 하위 에이전트에 더 좁은 권한을 위임하는 에이전트가 점점 늘고 있습니다.
그래서 DPoP 채택, Workload Identity Federation, 표준 토큰 교환이 로드맵에 올라왔습니다. 붙여넣은 API 키와 수명 긴 토큰 대신 기존 표준 위에서 에이전트 신원을 인식하고 신뢰하겠다는 방향입니다.
토론에서 갈리는 지점이 여기입니다. 두 갈래가 있습니다. 하나는 워크로드가 이미 갖고 있는 자격 증명을 RFC 7523과 OIDC 발견으로 재사용하는 쪽입니다. 이미 세워진 신뢰를 그대로 쓰자는 것이고, 지금 비인간 신원을 다루는 지배적 방식의 연장입니다. 다른 하나는 DPoP로 요청마다 서명된 증명을 요구하는 쪽입니다. 자격 증명을 클라이언트가 쥔 키와 요청 맥락에 묶습니다.
둘은 사실 층이 다릅니다. Workload Identity Federation이 클라이언트가 처음에 토큰을 얻는 경로이고, DPoP는 그 토큰을 리소스 서버에 제시하는 방법입니다. DPoP 증명은 그 자체로 완결돼 있어서 리소스 서버가 추가 상태를 관리할 필요가 없습니다. 새로 생기는 상태는 클라이언트가 들고 있는, 보통 수명이 짧은 개인 키 하나뿐입니다. 무상태 코어와 어울리는 선택입니다.
에이전트마다 서비스 계정을 파는 방식이 왜 답이 아닌지도 실무 쪽에서 나옵니다. 컴플라이언스 때문에 "누가 했는지"에 답할 수 있어야 하는데, 서비스 계정이 사방에 깔리면 그 답이 사라집니다. 반대로 에이전트 워크플로가 대시보드에 접근할 때마다 사람이 브라우저에서 OAuth를 승인하게 하면 루프가 멈춥니다. 사람을 넣을 수도 없고 신원을 지울 수도 없는 자리가 이 문제의 형태입니다.
카탈로그
세션이 하던 세 번째 일이 "무엇을 이미 알려줬는지" 기억하는 것입니다. 세션이 없으면 툴 카탈로그를 매 요청 통째로 던지든지, 다른 방법을 만들든지 해야 합니다. 캐시 가능한 리스트 결과(SEP-2549)가 첫 번째 대응이고, 로드맵의 progressive discovery가 두 번째입니다. 서버가 작은 진입점만 먼저 내놓고 대화가 좁혀질수록 카탈로그를 더 열어 보이는 방식입니다.
이 항목에 대한 구현자들의 반응이 로드맵 전체에서 가장 날카롭습니다. 요약하면 늦었다는 것입니다. 하네스 두 개에 MCP 지연 로딩을 이미 직접 넣었고, 지금은 그것마저 버리고 전부 code mode로 옮기는 중이라는 이야기가 스레드 최상단에 있습니다.
code mode는 툴을 나열해 모델에게 고르게 하는 대신, 툴을 코드에서 부를 수 있는 API로 노출하고 모델에게 코드를 쓰게 하는 방식입니다. Cloudflare가 밀고 있는 방향이고, 스레드에서 여러 명이 여기에 동의합니다. 툴 호출을 복잡한 로직으로 엮을 수 있고 런타임 성능도 낫다는 것이 이유로 나옵니다. 다만 정량 데이터를 묻는 질문에는 아무도 답하지 못했습니다. 이 판단은 지금까지 체감으로만 지지되고 있습니다.
겹쳐 읽으면 이렇게 됩니다. 표준은 툴 나열을 싸게 만드는 방법을 표준화하는 중인데, 앞서 가는 구현자들은 툴 나열 자체를 그만두는 중입니다. progressive discovery가 필요한 이유는 카탈로그가 크기 때문이고, code mode는 카탈로그를 모델에게 보여주지 않는 것으로 그 문제를 우회합니다. 로드맵이 따라잡으려는 지점과 구현자들이 서 있는 지점이 어긋나 있습니다.
남은 것
무상태 전환은 잘 된 결정으로 보입니다. 4월에 균열이라고 적어 뒀던 것 두 개가 실제로 닫혔고, 프로덕션 서버가 세션 저장소를 걷어낼 수 있게 됐습니다. 초기 릴리스에 별도 전송 프로토콜을 만들었던 선택을 되돌려 평범한 HTTP로 수렴한 것도 방향이 맞습니다.
다만 로드맵을 기능 목록으로 읽으면 이 그림이 안 보입니다. 다섯 워크스트림 중 셋이 세션이 하던 일을 다른 이름으로 되만드는 작업입니다. 서버 발신 이벤트는 서버가 먼저 말을 걸던 능력이고, 에이전트 신원은 누가 부르는지 알던 것이고, progressive discovery는 무엇을 알려줬는지 기억하던 것입니다. 각각 더 나은 형태로 돌아오고 있지만, 돌아오는 중이라는 사실 자체가 무상태 전환의 실제 비용입니다.
제 생각에는 신원 쪽이 셋 중 가장 먼저 굳을 것 같습니다. DPoP와 Workload Identity Federation 둘 다 MCP 바깥에서 이미 굴러가는 표준이고, 무상태 코어와 충돌하지 않으며, 컴플라이언스라는 밀어붙이는 힘이 뒤에 있습니다. 반면 카탈로그 쪽은 code mode 같은 우회로가 먼저 자리를 잡으면 표준이 도착했을 때 이미 다른 문제를 풀고 있을 가능성이 있습니다. 스레드에서 누군가 던진 질문이 남습니다. 이거 SPIFFE 다시 만드는 것 아니냐는 말인데, 에이전트 신원 논의가 워크로드 신원 논의와 얼마나 다른 문제인지는 아직 아무도 명확히 답하지 않았습니다.
참고: MCP Roadmap · The 2026-07-28 Specification · Scaling AI Agent Infrastructure with the MCP Stateless updates (Google Developers Blog) · The biggest MCP spec update ships July 28 (WorkOS) · Hacker News 토론 #49399591 · Code mode (Cloudflare)