MCP SSE 수신 검수: JSON 응답인데 왜 파싱이 실패할까
MCP Streamable HTTP의 JSON·SSE 응답을 대조합니다. UTF-8 분할·줄바꿈·빈 줄·다중 data와 파서의 단독 CR 종료 차이를 합성 표본으로 확인합니다.
이 글을 쓴 알파카랩스카카오·네이버·쿠팡 출신, 재하청 0%, 대기업·공공기관 등 18개사+ 레퍼런스
MCP SSE 수신은 형식·이벤트 경계·JSON을 나눠 검수합니다. 2026-11-07 기준, 빈 줄 없이 끊긴 이벤트는 확정하지 않습니다.
도구가 JSON-RPC 결과를 만들었는데 수신 쪽에서 JSON 오류가 날 수 있습니다. HTTP 본문 전체가 JSON 객체인지, SSE 이벤트 안에 JSON이 들어 있는지부터 구분해야 합니다. MCP 연동의 인수 담당자는 같은 내용의 두 응답 형식을 대조해 누락이 생긴 단계를 찾을 수 있어야 합니다.
메시지를 해석한 뒤의 진행률·완료 판단은 MCP 진행률 검수에서, 이미 복원된 결과의 설명과 데이터가 충돌하는 문제는 MCP 도구 결과 일치 검수에서 다룹니다. 이 글은 그 앞단인 HTTP 응답과 SSE 이벤트 복원에 집중합니다.
JSON-RPC 응답을 JSON으로 읽으면 왜 실패하나요?#
전송 형식이 다르기 때문입니다. JSON 응답은 본문의 객체를 해석하고, SSE 응답은 이벤트를 먼저 복원한 뒤 data 내용을 해석합니다. 수신 헤더의 Content-Type을 확인하지 않고 본문 전체를 JSON.parse에 넘기면 SSE의 필드명과 주석에서 실패할 수 있습니다.
MCP 2026-07-28 Streamable HTTP 사양은 요청 응답으로 application/json 객체와 text/event-stream을 모두 지원하도록 클라이언트에 요구합니다. Accept에도 두 형식을 나열합니다. 사양 버전은 2026-07-28, 확인일은 2026-11-07입니다. 아래 표본은 요청의 인증·버전 메타데이터가 적합하다는 가정 아래 응답 수신만 발췌합니다.
JSON 분기에서는 객체 해석과 응답 검증을 확인합니다. SSE 분기에서는 UTF-8 바이트 조각을 이어 디코딩하고, 줄과 이벤트를 조립한 뒤 JSON을 해석합니다. 네트워크에서 한 번 받은 조각이 문자 하나, 줄 하나 또는 이벤트 하나라는 가정은 두지 않습니다.
같은 응답을 어떻게 잘라서 검수하나요?#
내용을 고정하고 바이트 분할과 줄끝을 바꿉니다. 정상 표본만 반복하기보다 미완성 이벤트, 잘못된 JSON과 다른 요청의 응답도 구분해 넣습니다. 다음은 실제 고객 데이터가 없는 합성 관측입니다.
| 합성 수신 조건 | 기대하는 전달 단위 | 이 시험의 관측 | 인수 판정 |
|---|---|---|---|
| application/json의 정상 응답 | JSON 객체 1개 | 객체 1개, 현재 요청 일치 1개 | JSON 분기 확인 |
| LF SSE, 주석과 여러 data 줄 | 이벤트 1개 | 이벤트 1개, 현재 요청 일치 1개 | 주석 제외·data 결합 확인 |
| 같은 SSE의 CRLF 줄끝 | 이벤트 1개 | 이벤트 1개, 현재 요청 일치 1개 | CRLF 분할 복원 확인 |
| 같은 SSE의 단독 CR 줄끝으로 종료 | 표준상 이벤트 1개 | 이 호출 구성에서는 이벤트 0개 | 기대와 다름, 해당 경로 인수 보류 |
| 마지막 빈 줄이 없는 SSE | 이벤트 0개 | 이벤트 0개 | 미완성 이벤트를 결과로 확정하지 않음 |
| 이벤트는 닫혔지만 data가 잘못된 JSON | 이벤트 1개, JSON 해석 실패 | 이벤트 1개, JSON 오류 1개 | 프레임 오류와 내용 오류 분리 |
| 다른 요청 ID인 req-b의 정상 JSON | 이벤트 1개, 현재 요청 반영 0개 | 이벤트 1개, 현재 요청 일치 0개 | 엉뚱한 요청에 결과를 연결하지 않음 |
두 분할 방식에서 같은 관측을 재현했지만, 모든 표준 경계를 통과한 결과는 아닙니다. 단독 CR 종료 행은 표준 기대와 관측이 다릅니다. 해당 파서 호출 구성에서 얻은 제한된 결과이며 모든 클라이언트나 운영 SDK의 동작으로 일반화하지 않습니다. 네트워크·프록시·인증·전체 JSON-RPC/MCP 적합성이나 업무 완료를 시험한 것도 아닙니다.
입력 본문·표준 기대·실제 관측은 합성 수신 표본 JSON에서 확인할 수 있습니다. 관측값을 그대로 합격 기대값으로 바꾸지 말고, 사용하는 수신 경로에서 표준 기대를 충족하는지 다시 대조합니다.
빈 줄과 여러 data 줄은 어떻게 확인하나요?#
빈 줄은 이벤트 경계이며, 여러 data 줄은 한 이벤트의 데이터로 연결됩니다. 콜론으로 시작하는 주석은 이벤트 데이터가 아닙니다. 따라서 data 한 줄마다 JSON 객체 하나로 취급하는 방식도 맞지 않을 수 있습니다.
WHATWG HTML의 이벤트 스트림 해석 규칙은 UTF-8, LF·CRLF·단독 CR 줄끝, 빈 줄의 전달 동작을 설명합니다. 여러 data 필드는 줄바꿈으로 결합하며, 마지막 빈 줄 전에 끝난 미완성 이벤트는 전달하지 않습니다. 문서 갱신 표기는 2026-11-06, 확인일은 2026-11-07입니다.
아래는 시험에 사용한 LF 응답 본문을 만드는 가상 문자열입니다. 줄끝을 명시하기 위해 자바스크립트 문자열로 보여줍니다. HTTP 요청 구현이나 완성된 MCP 클라이언트 코드가 아니며, Content-Type은 text/event-stream이라고 가정합니다.
const sseBody =
': keep-alive\n\n' +
'event: message\n' +
'data: {"jsonrpc":"2.0","id":"req-a","result":{\n' +
'data: "resultType":"complete","content":[{"type":"text","text":"조회 완료"}]}}\n\n';첫 주석 블록은 결과가 아닙니다. 뒤의 data 줄을 합치면 줄바꿈이 포함된 JSON 객체가 되고, 마지막 두 줄바꿈이 이벤트 경계를 만듭니다. 본문 전체를 JSON.parse한 대조 실행은 실패했으며, 이벤트를 복원한 뒤의 JSON 해석은 이 LF 표본에서 성공했습니다.
실제 파서에서 차이가 나면 어떻게 인수하나요?#
표준 기대와 관측의 차이를 남기고 해당 수신 경로의 합격을 보류합니다. 서버 출력, 디코더, 파서와 스트림 종료 처리 중 어느 단계에서 차이가 생기는지 좁혀야 합니다. 특정 패키지를 썼다는 사실만으로 적합성을 인정하지 않습니다.
이번 단독 CR 관측은 파서 작성자의 v3.0.8 사용 설명을 참고해 조각 공급과 종료 처리를 구성한 결과입니다. 다른 호출 방식·버전·중계 구간까지 확인한 결론은 아닙니다. 바이트를 이어 붙이거나 끝에 개행을 강제로 추가해 미완성 입력을 정상처럼 바꾸는 보정은 기대 조건과 별도로 검토합니다.
프로토콜 버전도 고정합니다. MCP 2026-07-28 변경 기록은 이전 세션·GET 스트림과 SSE Last-Event-ID 재개 제거를 설명합니다. 일반 EventSource의 GET·재접속 동작을 그대로 MCP POST 수신에 적용하지 않습니다. 기존 버전 서버의 호환 경로는 그 버전의 계약으로 따로 검수합니다.
인수표에는 응답 형식, 바이트 입력, 분할 방식, 기대 이벤트, JSON 해석 결과와 요청 연결 결과를 적습니다. 수신에 성공한 뒤에도 도구의 오류·추가 입력·업무 검수는 남습니다. 연결이 끊겼다는 이유로 쓰기 요청을 무조건 다시 보내는 재시도 정책은 이 글의 파싱 시험으로 정하지 않습니다.
MCP SSE 수신 검수 FAQ#
Content-Type을 보지 않고 JSON으로 읽어도 되나요?
Streamable HTTP 클라이언트는 JSON 객체와 SSE 응답을 모두 처리해야 합니다. SSE는 이벤트를 먼저 복원한 뒤 data 안의 JSON을 해석합니다. 서버가 한 형식만 반환한 시연으로 두 형식의 인수를 끝내지 않습니다.
네트워크 조각마다 JSON.parse하면 되나요?
조각 경계는 문자·줄·이벤트 경계와 일치하지 않습니다. UTF-8 문자 중간이나 JSON 중간에서 조각이 나뉠 수 있습니다. 스트리밍 디코딩과 SSE 이벤트 복원을 거친 완성 데이터에 JSON 해석을 적용합니다.
연결이 끝나면 남은 data도 이벤트로 처리하나요?
마지막 빈 줄이 없으면 미완성 이벤트를 전달하지 않는 것이 SSE 규칙입니다. 실제 파서의 종료 처리도 함께 시험해야 합니다. 입력에 없던 빈 줄을 덧붙여 정상 결과로 바꾸지 않습니다.
단독 CR 시험이 다르면 패키지 전체가 부적합한가요?
이 글의 관측만으로 모든 사용 방식과 버전을 판정하지 않습니다. 사용한 버전·조각 공급·종료 처리와 표준 기대의 차이를 특정해 남깁니다. 해당 수신 경로는 원인을 확인하고 기대 조건을 충족하기 전까지 인수를 보류합니다.
SSE 이벤트를 받았으면 도구 실행도 성공한 건가요?
이벤트 수신, JSON 해석, 현재 요청에 맞는 응답인지는 서로 다른 검사입니다. 도구 결과의 오류나 추가 입력 요구, 실제 업무 결과도 이후 단계에서 확인합니다. 이벤트 개수를 성공한 업무 건수로 바꾸지 않습니다.
수신 경계 인수표 초안 협의#
알파카랩스는 AX 서비스에서 업무 진단과 시스템 구축·운영을 연결하는 제공 방식을 설명합니다. 이는 자사 공개 설명이며 이 파싱 시험을 특정 고객에게 납품한 실적으로 제시하지 않습니다. 비식별 응답 샘플과 사용 프로토콜·수신 구성·기대 결과를 주시면 수신 경계 인수표 초안을 협의합니다. 소요 시간은 자료와 버전·중계 구간을 확인한 뒤 정합니다.
형식부터 이벤트까지 수신 경계를 검수합니다
비식별 응답과 사용 버전으로 수신 경계 인수표 초안을 협의합니다. 소요 시간은 자료와 버전·중계 구간을 확인한 뒤 정합니다.
수신 경계 인수표 초안 협의