본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 29. 11:42

MCP가 세션을 삭제했습니다: 7월 28일 사양이 서버에 미치는 영향

요약

MCP(Model Context Protocol)가 2026년 7월 28일 업데이트를 통해 상태 비저장(stateless) 방식으로 전환됩니다. 이 변화는 로드 밸런싱 문제를 해결하지만, 도구 스키마 컨텍스트 비대화라는 비용 문제는 여전히 과제로 남습니다.

핵심 포인트

  • MCP가 세션 기반에서 상태 비저장(stateless) 방식으로 전환됨
  • Mcp-Session-Id 헤더가 삭제되어 스티키 세션 필요성 제거
  • Mcp-Method 및 Mcp-Name 헤더 도입으로 게이트웨이 라우팅 효율화
  • 상태 비저장 전환은 운영 편의성을 높이나 토큰 비용 문제는 미해결

7월 28일 MCP 재작성(rewrite)은 상태 비저장(stateless) 방식으로 전환됩니다. 이는 로드 밸런서(load balancer) 문제를 해결해주지만, 실제로 여러분이 지불하게 될 비용인 '도구 스키마(tool-schema) 컨텍스트 비대화(bloat)' 문제에는 아무런 도움이 되지 않습니다.

만약 지난 1년 동안 MCP 서버를 출시했다면, 여러분은 사양이 말해준 거짓말을 바탕으로 서버를 구축했을 것입니다. 즉, 연결(connection)이란 계속 유지할 수 있는 것이라는 가정 말입니다. 2026년 7월 28일, 그 가정은 삭제됩니다.

5월 21일에 확정된 2026-07-28 출시 후보(release candidate) 버전은 상태 비저장(stateless) 방식을 채택합니다. 더 이상 initialize/initialized 핸드셰이크(handshake)는 없습니다. 클라이언트를 하나의 프로세스에 고정하던 Mcp-Session-Id 헤더도 사라집니다. 모든 튜토리얼이 가르쳐준 "세션을 열고, 따뜻하게 유지하며(keep it warm), 모든 것을 동일한 장비로 라우팅한다"는 모델은 이제 레거시(legacy)가 되었습니다. (7월 28일까지는 여전히 RC 단계이므로, 아래의 통신 세부 사항을 확정된 최종안이 아닌 후보안으로 취급하십시오. 하지만 SDK 팀들은 이미 이에 맞춰 마이그레이션(migrating)을 진행하고 있습니다.)

저는 두 가지 주장을 동시에 하고자 합니다. 첫째, 상태 비저장(stateless)으로 가는 것은 올바른 결정이며, 진작 이루어졌어야 할 일입니다. 둘째, 이는 모두가 불만을 제기했던 운영상의 고통은 해결해주지만, MCP에서 실제로 비용이 많이 발생하는 문제에 대해서는 아무것도 해결해주지 못합니다. 이 두 가지는 서로 충돌하는 것이 아닙니다. 아름다운 라운드 로빈(round-robin) 배포를 구현하고도 토큰 예산을 낭비할 수 있습니다.

통신(wire) 상에서 실제로 변경된 점

기존의 요청 경로(request path)는 다음과 같습니다. 클라이언트가 연결하고, 핸드셰이크를 수행하고, 세션 ID를 받으면, 그 이후의 모든 요청은 해당 ID를 포함해야 하며 해당 ID를 생성한 동일한 서버 인스턴스에 도달해야 합니다.

POST /mcp HTTP/1.1
Content-Type: application/json
Mcp-Session-Id: 4e9c1a7f-2b3d-44a8-9f10-0c2d6a1b88ef
...

Mcp-Session-Id가 바로 로드 밸런서 세금(load-balancer tax)입니다. 인스턴스 B는 인스턴스 A가 initialize 과정에서 무엇을 협상했는지 알 수 없기 때문에, 이는 스티키 세션(sticky sessions)이나 공유 세션 저장소(shared session store)를 강제합니다.

새로운 경로는 세션을 완전히 제거합니다. 연결 설정 시 한 번 협상되었던 클라이언트 메타데이터(metadata)는 이제 요청마다 _meta 필드에 실려 전달됩니다. 또한, 두 개의 새로운 필수 헤더인 Mcp-MethodMcp-Name을 통해 게이트웨이(gateway)와 속도 제한기(rate-limiter)가 JSON 본문을 파싱하지 않고도 라우팅할 수 있게 됩니다.

POST /mcp HTTP/1.1
Content-Type: application/json
Mcp-Method: tools/call
...

initialize에서 발생하던 Capability 교환이 이제는 어떤 인스턴스든 응답할 수 있는 server/discover 호출을 통해 이루어집니다. 목록(List) 및 리소스 응답에서도 ttlMscacheScope를 가져가게 되어 게이트웨이가 HTTP처럼 캐싱할 수 있습니다. 마지막 부분이 보이는 것보다 더 중요합니다. 이 부분에 대해 다시 다루겠습니다.

세션 저장소 삭제하기

대부분의 사람들이 과소평가할 마이그레이션은 서버 상태입니다. 만약 귀하의 서버가 다음과 같다면, 그 줄 전체가 이제 쓸모없는 짐(dead weight)이 됩니다:

# 이전 — 상태 저장형(stateful), 2025-11-25 스타일
sessions = {}  # 인메모리 또는 더 나쁜 경우 Redis를 사용해야 함

...

애프터(After)에는 세션 맵도 없고 on_initialize도 없습니다. 각 핸들러는 요청에 대해 순수(pure)하며, 필요한 것을 _meta에서 읽어 응답합니다:

# 이후 — 무상태형(stateless), 2026-07-28 RC 스타일
def on_discover(req):
    return {"capabilities": SERVER_CAPS}   # 어떤 인스턴스든 응답 가능
...

이로 얻는 이점은 사양 작성자들이 광고한 것과 정확히 같습니다. 즉, 이를

라이프사이클(lifecycle)이 반전됩니다. 서버가 세션(session)에 대해 장기 실행 작업(long-running work)을 추적하는 대신, tools/call은 태스크 핸들(task handle)을 반환하며 _클라이언트(client)_가 드라이버(driver)가 되어 tasks/get, tasks/update, tasks/cancel을 통해 폴링(polling)하고 제어합니다.

// 1. 클라이언트가 장기 실행 도구를 호출함
{"jsonrpc":"2.0","id":7,"method":"tools/call",
 "params":{"name":"reindex","arguments":{"scope":"all"}}}
...

진행 중인 작업의 대시보드를 재구축하기 위해 tasks/list에 의존했다면, 그 패턴은 끝났습니다. 이제 여러분이 태스크 식별자(task identity)를 소유하게 됩니다. 프로토콜이 여러분을 대신해 이를 기억해주지 않으므로, 핸들을 클라이언트 측(또는 도구가 기록하는 실제 데이터 저장소)에 영구적으로 저장(persist)하십시오.

테스트를 방해할 에러 코드 및 인증 변경 사항

두 가지 작은 변경 사항은 주의 깊게 검색(grep)하지 않으면 통합 테스트(integration suite)를 조용히 실패하게 만들 것입니다.

resource-not-found 코드가 MCP 전용 코드인 -32002에서 표준 JSON-RPC 코드인 -32602로 이동합니다. 만약 -32002에 매칭되는 단언(assertion)이나 클라이언트 분기(branch)를 가지고 있다면, 이들은 조용히 실행을 멈출 것입니다.

- if (err.code === -32002) handleMissingResource();
+ if (err.code === -32602) handleMissingResource();

인증(auth) 측면에서는, 6개의 SEP가 MCP를 일반적인 OAuth/OIDC 방향으로 끌어당깁니다. 가장 먼저 타격을 줄 변화는 RFC 9207에 따른 필수 iss 검증입니다. 이제 권한 부여 응답(authorization response)은 반드시 발행자 식별자(issuer identifier)를 포함해야 하며, 클라이언트는 이것이 흐름을 시작한 서버와 일치하는지 확인해야 합니다. 만약 iss를 무시하도록 직접 만든 OAuth 클라이언트를 사용했다면, 이는 기술적으로 취약(혼동 공격, mix-up attacks)했으며 이제는 비준수(non-conformant) 상태가 됩니다. Roots, Sampling, 그리고 Logging 또한 12개월의 제거 유예 기간을 두고 지원 중단(deprecation) 단계에 진입합니다. 7월에 바로 사라지는 것은 아니지만, 이를 기반으로 새로운 것을 구축하지는 마십시오.

왜 이 중 어느 것도 실제 질병을 고치지 못하는가

여기에 저의 반대 의견(contrarian read)이 있습니다. 위의 모든 것은 배관(plumbing) 작업에 불과합니다. 이는 MCP를 _운영(operate)_하는 비용을 낮춰줄 뿐, MCP를 _실행(run)_하는 데 비용이 많이 들게 만드는 근본적인 문제, 즉 모델이 매 턴마다 여러분의 도구 스키마(tool schemas)에 대해 비용을 지불한다는 사실에 대해서는 거의 아무것도 해결해주지 못합니다.

MCP의 공동 제작자인 David Soria Parra는 2026년 4월에 이를 명확하게 설명했습니다. "모델이 실제 추론(reasoning)을 수행하기도 전에 컨텍스트 윈도우(context window)의 상당 부분이 소비됩니다." 무상태성(Statelessness)은 이 문제를 건드리지 않습니다. 오히려 프레임워크를 더 악화시킨다고 볼 수 있습니다. 세션을 삭제함으로써, 서버가 "이 클라이언트는 이미 이 40개의 도구 정의(tool definitions)를 확인했다"라고 기억할 수 있는 유일한 장소를 삭제해 버리기 때문입니다. 따라서 명백한 해결책은 요청 횟수를 줄이는 것이 아니라, 더 많은 요청에 스키마(schemas)와 이전 컨텍스트를 다시 보내는 것이 되어버립니다.

RC(Release Candidate)를 읽은 후 제가 직접 운영 중인 에이전트 중 하나에서 트레이스(traces)를 추출해 보았습니다. 도구 스키마(tool-schema) 블록과 다시 전송된 이전 컨텍스트는 단 하나의 사용자 토큰(user token)이 나타나기도 전에 프롬프트(prompt)의 절반 이상을 정기적으로 잡아먹고 있었습니다. 이것은 사양(spec)의 버그가 아니라, 비용 모델(cost model)의 문제입니다. 그리고 무상태성 재작성(stateless rewrite)의 주요 성과는 운영 측면에서의 승리이지, 토큰 경제성(token-economic) 측면의 승리가 아닙니다.

여기서 RC가 실제로 제공하는 유일한 레버(lever)는 list/resource 응답에 추가된 새로운 ttlMscacheScope입니다. 이 부분에 집중해야 합니다. 호출마다 다시 가져오는 대신 도구 목록(tool listings)을 캐싱(caching)하는 게이트웨이는, 이번 릴리스에서 컨텍스트 비용 문제를 해결하는 것에 가장 근접한 방법이며, 이는 라우팅 헤더(routing-headers) 발표 아래에 묻혀 있습니다. 이를 활용하십시오. 에지(edge)에서 공격적으로 캐싱하고, 에이전트가 실제로 호출하는 범위로 도구 표면(tool surface)을 다듬으십시오. 에이전트가 6개의 도구만 사용하는데 40개의 도구를 한꺼번에 보내는 일을 멈춰야 합니다.

요약 (The takeaway)

여러분에게는 대략 10주의 시간이 있습니다. 작업은 기계적입니다: initialize를 삭제하고, 세션 저장소(session store)를 삭제하며, 클라이언트 정보(client info)를 _meta로 이동시키고, Mcp-Method/Mcp-Name을 추가하며, Task를 클라이언트 주도형(client-driven)으로 재작성하고, -32002-32602 어설션(assertions)을 수정하고, iss를 검증하는 것입니다. 이를 수행하면 배포가 더 단순해지고 운영 비용이 저렴해질 것입니다.

하지만 단순해진 배포를 더 저렴해진 에이전트와 혼동하지 마십시오. 무상태성은 로드 밸런서(load balancer)의 문제를 해결했습니다. 매 턴마다 전체 도구 카탈로그(tool catalog)에 대한 임대료를 지불해야 하는 모델의 문제는 여전히 그대로 남아 있으며, 사양은 캐싱을 통해 이 문제를 회피하는 것을 오히려 약간 더 어렵게 만들었습니다. 운영상의 이점을 위해 마이그레이션하십시오. 그런 다음 진짜 청구서와 싸우러 가십시오.

7월 28일 이전에 마이그레이션(migration)을 진행하실 건가요, 아니면 최종 사양(spec)이 확정될 때까지 기다리실 건가요? 그리고 실제로 자신의 도구 스키마(tool schemas)가 턴(turn)당 어느 정도의 비용을 발생시키는지 측정해 본 분이 계신가요? 여러분의 수치는 얼마인가요? 댓글로 남겨주세요.

AI 자동 생성 콘텐츠

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

원문 바로가기
0

댓글

0