post read2 분 소요

JSON-RPC 2.0은 원격 함수를 호출하는 메시지를 JSON 객체로 표현하는 규약이다. 요청과 응답의 모양은 정하지만, 그 JSON을 HTTP로 보낼지 표준입출력으로 보낼지는 정하지 않는다.

요청의 식별자를 성공과 오류 응답에 연결하고 알림은 응답하지 않는 흐름

MCP처럼 JSON-RPC를 사용하는 프로토콜을 읽을 때도 메시지 규약과 전송 방식을 분리해야 한다. 먼저 JSON-RPC 자체의 네 가지 메시지부터 살펴본다.

네 가지 메시지 형태

모든 메시지는 "jsonrpc": "2.0"을 포함한다. 나머지 필드 조합으로 역할이 갈린다.

형태 method id result error 응답
요청 있음 있음 없음 없음 필요
알림 있음 없음 없음 없음 금지
성공 응답 없음 있음 있음 없음 요청에 대한 결과
에러 응답 없음 있음 없음 있음 요청에 대한 실패

요청과 성공 응답

{"jsonrpc":"2.0","method":"subtract","params":{"minuend":42,"subtrahend":23},"id":1}

수신자가 메서드를 실행하면 요청의 id를 그대로 담아 결과를 보낸다.

{"jsonrpc":"2.0","result":19,"id":1}

알림

알림은 요청에서 id만 빠진 형태다.

{"jsonrpc":"2.0","method":"update","params":{"status":"ready"}}

수신자는 처리에 성공해도, 실패해도 응답하지 않는다. 결과 확인이 필요 없는 상태 통지에만 사용해야 한다.

에러 응답

실패 응답은 result 대신 error를 쓴다. 두 필드는 한 응답에 함께 올 수 없다.

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32601,
    "message": "Method not found"
  },
  "id": 1
}

params는 배열과 객체를 모두 허용한다

일반 JSON-RPC 2.0은 위치 인자 배열과 이름 인자 객체를 모두 허용한다.

{"jsonrpc":"2.0","method":"subtract","params":[42,23],"id":1}
{"jsonrpc":"2.0","method":"subtract","params":{"minuend":42,"subtrahend":23},"id":2}

배열은 순서가 계약이고 객체는 키 이름이 계약이다. JSON-RPC를 채택한 상위 프로토콜은 둘 중 하나만 허용할 수 있다. MCP는 객체 형태만 사용한다.

동시에 보낸 요청은 id로 구분한다

응답은 요청한 순서대로 돌아온다는 보장이 없다.

보냄 id=1 ────────────────┐
보냄 id=2 ───────┐        │
받음 id=2 ◀──────┘        │
받음 id=1 ◀───────────────┘

id는 요청자가 정하고 응답자는 값을 바꾸지 않고 돌려준다. 일반 명세는 문자열, 숫자, null을 허용하지만 null과 소수 숫자는 피하는 편이 안전하다.

응답은 값뿐 아니라 JSON 타입도 같아야 한다. 숫자 2를 문자열 "2"로 바꾸어 돌려주면 서로 다른 식별자다.

표준 에러 코드

error 객체에는 정수 code, 짧은 message, 선택적인 data가 들어간다.

코드 이름 의미
-32700 Parse error JSON 파싱 실패
-32600 Invalid Request 요청 객체 형식 오류
-32601 Method not found 메서드가 없음
-32602 Invalid params 인자 오류
-32603 Internal error 수신자 내부 오류
-32000~-32099 Server error 구현이 세분화할 수 있는 예약 범위

요청의 id를 알아낼 수 없는 파싱 실패는 id: null로 응답한다.

{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error"},"id":null}

배치 요청

일반 JSON-RPC 2.0은 여러 요청과 알림을 배열에 묶을 수 있다.

[
  {"jsonrpc":"2.0","method":"sum","params":[1,2],"id":1},
  {"jsonrpc":"2.0","method":"notify","params":[7]},
  {"jsonrpc":"2.0","method":"get","id":2}
]

응답도 배열이지만 알림에 해당하는 항목은 생기지 않는다. 처리와 응답 순서가 달라질 수 있으므로 배치 안에서도 id로 짝을 맞춘다.

배치는 왕복 횟수를 줄이는 대신 부분 실패와 병렬 처리 규칙이 복잡해진다. JSON-RPC를 쓰는 상위 프로토콜이 배치를 지원하지 않는 경우도 있다.

JSON-RPC와 MCP를 구분해서 읽기

MCP는 JSON-RPC 2.0의 메시지 형태를 사용하지만 허용 범위를 좁힌다.

항목 JSON-RPC 2.0 MCP 2026-07-28
params 배열 또는 객체 객체만
요청 id 문자열, 숫자, null 문자열 또는 숫자
배치 허용 미지원
메타데이터 별도 규정 없음 params._meta 사용
완료 상태 메서드별 결과 구조 resultType으로 상태 구분

따라서 JSON-RPC 명세에 존재하는 기능이 MCP에서도 그대로 지원된다고 가정하면 안 된다. 다음 글에서는 이 메시지가 실제 MCP의 stdio와 Streamable HTTP에서 어떻게 오가는지 이어서 살펴본다.

참고 자료

'Development' 카테고리의 다른 글

댓글남기기