MCP 진행 메시지가 마지막에 몰릴 때: SSE 응답 버퍼링 진단

MCP 진행 메시지가 마지막에 한꺼번에 나타난다면, 모델 속도보다 먼저 메시지가 어디에서 모이는지 확인한다. 서버가 늦게 만들었는지, 프록시가 응답을 모았는지, 클라이언트가 다 받은 뒤 화면을 갱신했는지는 서로 다른 문제다. 세 경우 모두 사용자에게는 “오래 멈췄다가 한 번에 끝남”으로 보일 수 있다.

이 글은 MCP 2026-07-28의 Streamable HTTP와 NGINX HTTP 프록시를 기준으로 한 진단 안내다. 공식 문서 확인일은 2026년 10월 14일이다. 아래 시간표는 가상 사례이고 설정은 검토용 예시다. 실제 운영 서버의 지연을 측정하거나 설정 변경 효과를 시험한 기록은 아니다.

먼저 스트리밍 응답인지 확인한다

MCP 전송 규격에서 요청 응답은 단일 JSON 또는 요청별 SSE일 수 있다. JSON 한 개로 끝나는 응답에 중간 메시지가 없다는 이유만으로 버퍼링 장애라고 부를 수는 없다. 응답의 Content-Type이 text/event-stream인지, 서버가 실제 중간 알림을 생성하는지부터 확인한다.

같은 규격은 SSE 시작 시 서버가 X-Accel-Buffering: no 응답 헤더를 포함하도록 권고한다. 이것은 프록시 버퍼링을 줄이기 위한 신호이지 모든 호스트와 CDN에 통하는 보장서가 아니다. 진행 알림은 자신이 속한 요청의 응답 스트림에 흐르므로, 다른 연결을 보고 기다리지 않았는지도 살핀다.

세 시점을 나눠 기록한다

권장 관측 지점은 서버가 이벤트를 만들어 전송 계층에 넘긴 때, 클라이언트가 바이트를 읽은 때, 완성된 이벤트를 화면에 반영한 때다. 서버의 함수 호출 로그만으로 네트워크 송신 완료를 단정하지 않는다. 서로 다른 컴퓨터의 시각을 빼려면 시계 오차도 고려해야 한다. 먼저 각 지점 안에서 관측한 간격과 이벤트 순번을 비교하는 편이 안전하다.

관측 패턴다음 조사 위치
서버 생성 자체가 끝에 몰림계산 단계, 이벤트 생성 조건, 애플리케이션 출력 처리
서버는 나눠 내보내지만 수신이 몰림서버 출력 버퍼, 프록시·게이트웨이·CDN 경로
수신은 나뉘는데 화면만 몰림전체 본문 대기 코드, 이벤트 조립, UI 갱신 주기
주석만 도착하고 결과가 없음연결 유지와 업무 진행을 구분하고 최종 응답 확인

표의 두 번째 행은 프록시를 확정하는 검사가 아니다. 중간 계층이 여러 개라면 어느 구간의 전송을 관측했는지 적어야 한다. 접근이 허용된 시험 경로에서만 동일한 읽기 요청을 비교한다. 인증이나 접근 제한을 피해 서버에 직접 접속해서는 안 된다.

가상 사례: 서버 기록에 이벤트 1·2·3이 요청 시작 후 1·2·3초에 나타나고, 클라이언트에는 모두 3초 무렵 도착했다고 하자. 이 기록은 생성과 수신 사이를 조사할 이유가 된다. 하지만 서버 기록이 flush 이전인지 이후인지 모른다면 “NGINX가 2초를 지연했다”고 계산할 근거는 부족하다. 화면의 정지 시간 하나를 특정 제품의 지연 수치로 옮기지 않는다.

NGINX에서는 응답 버퍼링을 본다

NGINX 공식 문서의 proxy_buffering 기본값은 on이다. off이면 업스트림 응답을 받는 대로 클라이언트로 전달하며 전체 응답을 미리 읽으려 하지 않는다. 또한 업스트림의 X-Accel-Buffering 응답 헤더로 제어할 수 있지만, proxy_ignore_headers 설정이 이 처리를 비활성화할 수 있다.

# Review within the existing MCP proxy location.
# This is one directive, not a complete server configuration.
proxy_buffering off;

위 한 줄은 이미 올바르게 구성된 MCP 프록시 location 안에서 검토할 응답 설정이다. 새 서버 설정 전체로 복사하지 않는다. 기존 인증, TLS, upstream, 라우팅을 보존하고 시험 환경에서 유효성 검사와 비교 관측을 거친다. 다른 요청까지 영향을 받지 않도록 적용 범위를 좁힌다. 버퍼링을 끄면 느린 클라이언트에 대한 자원 사용 양상도 달라질 수 있으므로 지연만 보지 않고 연결 수와 자원 상태를 함께 관측한다.

proxy_request_buffering은 클라이언트가 보내는 요청 본문 쪽 설정이다. 서버에서 돌아오는 이벤트 지연을 조사하면서 이름이 비슷하다는 이유로 이것부터 바꾸지 않는다. X-Accel-Buffering도 클라이언트 요청에 추가하는 임의의 해결 헤더로 취급하지 않는다. 어떤 계층이 응답 헤더를 만들고 처리하는지 확인해야 한다.

관측 도구가 출력을 모으는 경우도 있다

curl의 --no-buffer(-N)는 curl 출력 스트림의 버퍼링을 끈다. 서버나 CDN의 버퍼를 끄는 옵션이 아니다. 기존에 승인된 읽기 전용 시험 요청이 있다면 다른 조건을 그대로 두고 이 옵션을 더해 출력 양상이 달라지는지 비교할 수 있다.

# Add to an already validated read-only curl request:
--no-buffer

명령 전체를 싣지 않은 이유는 요청의 프로토콜 버전·인증·메서드가 환경마다 다르기 때문이다. 일반 SSE 예제의 GET 명령을 MCP에 그대로 옮기지 않는다. 여기서 설명하는 2026-07-28 revision은 요청별 POST 응답을 사용한다. 구버전 클라이언트의 연결 방식은 해당 버전 문서와 별도로 맞춘다.

stdout 뒤에 연결한 파이프나 로그 수집기가 다시 모아 출력할 수도 있다. “curl에서는 나뉘어 보인다”는 관측은 비교에 유용하지만, 이것만으로 앱의 UI 또는 서버 전체가 정상이라고 결론 내리지 않는다. 공유 기록에는 이벤트 순번·관측 지점·시간 간격만 남기고 인증값, 쿠키, 실제 고객 본문은 제외한다.

수정 후에는 같은 요청으로 경계를 다시 확인한다

확인 항목남길 증거
응답 형식실제 Content-Type과 요청에 대응하는 스트림
이벤트 도착첫 완성 이벤트와 이후 이벤트 간격
화면 갱신수신 이벤트 순서와 표시 순서의 대응
완료 판정중간 알림 뒤 원래 요청의 최종 응답
변경 범위시험한 프록시 위치, 실제 버전, 변경 전후 조건

연결 유지 주석이 흘러온다는 것은 데이터가 오고 있다는 관측이다. 업무가 진행됐거나 성공했다는 증거는 아니다. 지연을 줄이려다가 결과 확인 없이 쓰기 요청을 반복하면 별개의 중복 실행 문제가 생긴다. 쓰기의 결과가 불확실하면 허용된 상태 조회부터 한다.

이벤트를 나누어 읽는 방법은 SSE data와 이벤트 경계 진단, 기다림의 종료 조건은 요청 id와 응답 연결 진단에서 이어서 볼 수 있다. 파싱이 맞는지와 제때 도착하는지는 별도로 확인해야 한다.

적용 범위와 한계: MCP 규격 revision은 2026-07-28이다. NGINX와 curl은 2026년 10월 14일의 공식 온라인 문서를 대조했으며 특정 설치 버전에서 실행하지 않았다. 따라서 배포 전에는 실제 nginx -v, curl --version, 사용 SDK 버전과 프록시 체인을 별도로 기록해야 한다. 이 글에는 운영 지연 개선 수치나 실제 장애 해결 주장이 없다.


다른 글 보기 · 주제 탐색 · 작성자와 편집 기준 · 문의·정정 요청

RUDA DIRECTOR에서 더 알아보기

지금 구독하여 계속 읽고 전체 아카이브에 액세스하세요.

계속 읽기