제가 공부한 내용을 정리하는 블로그입니다.
아직 많이 부족하고 배울게 너무나도 많습니다. 틀린내용이 있으면 언제나 가감없이 말씀해주시면 감사하겠습니다😁
서론
다른 프로젝트에서나 회사에서 MCP 서버를 개발해왔다. MCP의 통신 규약인 JSON-RPC 2.0이라는 것과, 이것의 개략적인 특징정도 뿐만 알고 있을 뿐이였다.(원격실행.. 메소드 이름 필요.. 등)
하지만 왜 이 통신규약이 필요하며 어떻게 발전하게 되었는지, 기존 JSON과의 차이점과 특징을 바탕으로 MCP의 통신 규약에 대해서 더욱 자세하게 공부하기 위해 해당 포스팅을 진행한다.
MCP 동작 원리
MCP(Model Context Protocol)을 공부하다보면 JSON-RPC 2.0이라는 용어를 자주 만나게 된다.
이는 MCP Client와 MCP Server가 서로 메시지를 주고 받을 때 사용하는 통신 규약이 JSON-RPC 2.0이기 때문이다.
MCP의 동작방식을 제대로 이해하기 위해서 관계를 설명하기 쉽게 표현하자면
JSON
↓
JSON-RPC 2.0
↓
MCP Message
라고 표현할 수 있다.
- JSON: 데이터를 표현하는 형식
- JSON-RPC 2.0: JSON을 이용하여 함수 호출과 응답을 표현하는 RPC 프로토콜
- MCP: JSON-RPC 2.0 메시지를 기반으로 Client와 Server가 통신하는 프로토콜
JSON 이란
JSON은 JavaScript Object Notation의 약자로, 데이터를 문자열 형태로 표현하기 위한 경량 데이터 형식이다.
해당 데이터 포맷은 현재 Server-Client API 통신에서 가장 널리 사용되는 데이터 형식 중 하나이다.
예를 들어 사용자 정보를 JSON으로 표현하면 다음과 같다.
{
"name": "Kim",
"age": 30,
"developer": true
}
이렇게 JSON에서 사용할 수 있는 주요 데이터 타입은 다음과 같다.
- String
- Number
- Boolean
- Object
- Array
- Null
조금 더 복잡한 데이터로는 배열이나 dictionary 형태도 가능하다.
{
"name": "Kim",
"skills": [
"Java",
"Python",
"MCP"
],
"profile": {
"career": 3,
"backend": true
}
}
이처럼 JSON은 Key-Value 형태의 데이터 구조를 표현하는 방법이다.
만약 서버에서 Client가 보낸 값에 따라서 실제로 어떤 동작을 해야하는지가 규정되어야 한다면 별도의 규칙이 필요할 것이다.
이때 등장한 것이 JSON-RPC이다.
RPC란
먼저 RPC란 Remote Procedure Call, 원격 프로시저 호출을 의미한다. 다음 코드를 살펴보자.
int result = add(10, 20);
우리는 일반적으로 코드 내에서 함수 호출을 다음과 같이 작성한다.
하지만 이는 Client가 지정한 동작이 아닌, 서버 내에서 지정한 동작이며, 호출하려고 하는 함수가 다른 프로세스나 다른 서버에 있다면 직접 호출 할 수 없다.
예를 들어 다음과 같이 코드를 작성하고 싶을 때는 이러한 과정이 필요하다.
// Client가 원하는 동작
result = Server.add(10, 20)
// 실제 네트워크 상에서 필요한 과정
Client
│
│ "add 함수를 10, 20으로 실행해줘"
▼
Server
│
│ add(10, 20)
▼
Result = 30
│
▼
Client
RPC는 이러한 과정을 추상화하여 다른 곳에 존재하는 함수를 마치 로컬 함수처럼 호출할 수 있도록 하는 통신 방식이다.
JSON-RPC란
JSON-RPC는 RPC 메시지를 JSON 형식으로 표현하기 위한 프로토콜이다.
즉, RPC + JSON = JSON-RPC라고 이해하면 쉽다. 현재는 일반적으로 사용하는 버전은 JSON-RPC 2.0이다.
JSON-RPC 2.0에서는 Client가 Server의 메서드를 호출하기 위해 정해진 형태의 JSON 메시지를 보낸다.
예를 들어 add(10, 20)을 호출한다고 생각해보자.
{
"jsonrpc": "2.0",
"id": 1,
"method": "add",
"params": {
"a": 10,
"b": 20
}
}
각 필드는 다음과 같은 의미를 가진다.
| 필드 | 의미 |
| jsonrpc | JSON-RPC 버전 |
| id | 요청과 응답을 연결하기 위한 식별자 |
| method | 호출하려는 메소드 |
| params | 메소드에 전달할 파라미터 |
Server는 message를 식별해 해당하는 메소드를 실행한다.(ex> add(10, 20))
그 이후 다음과 같이 응답할 수 있다.
{
"jsonrpc": "2.0",
"id": 1,
"result": 30
}
여기서 중요한 것이 id다.
Client가 여러 요청을 동시에 보낼 수 있기 때문에 Server의 응답이 어떤 요청에 대한 결과인지 구분할 방법이 필요하다.
이때 같은 id를 사용함으로써 요청과 응답을 연결할 수 있다.
JSON-RPC 2.0의 세가지 메시지
JSON-RPC를 이해할 때 세가지의 메시지가 중요하다.(Request, Response, Notification)
Request
Client가 Server에 어떤 작업을 요청하는 메시지이다.
{
"jsonrpc": "2.0",
"id": 1,
"method": "add",
"params": {
"a": 10,
"b": 20
}
}
Request에는 일반적으로 id가 존재하며, Server는 이 id를 통해 응답한다.
Respone
Request를 처리한 결과이다. 성공했다면 result를 반환한다.
{
"jsonrpc": "2.0",
"id": 1,
"result": 30
}
반대로 처리 과정에서 문제가 발생하면 error를 반환한다.
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32601,
"message": "Method not found"
}
}
에러의 필드 명은 다음과 같다.
- code: 정해진 오류 코드 (예: -32601은 메서드 없음)
- message: 사람이 읽을 수 있는 설명
- data: 선택적으로 제공되는 추가 디버깅 정보
Notification
Notification은 Request와 비슷하지만 중요한 차이가 있다.
id가 없다.
{
"jsonrpc": "2.0",
"method": "log",
"params": {
"message": "Server started"
}
}
id가 없다는 것은 응답을 기대하지 않는다는 의미다.
따라서 구조적으로 보면 다음과 같다.
// Request
Client ─────────▶ Server
◀─────────
Response
// Notification
Client ─────────▶ Server
응답 없음
이 Request / Response / Notification 구조는 MCP를 공부할 때도 매우 중요하다.
MCP와 JSON-RPC 2.0
MCP는 JSON-RPC 2.0을 기반으로 메시지를 주고받는다.
MCP는 어떤 메소드와 기능을 제공하고, Client와 Server가 어떻게 상호작용할 것인지에 대한 동작 방식이고,
JSON-RPC 2.0은 MCP Server와 MCP Client가 서로 통신을 하기 위한 데이터 규약이라고 볼 수 있다.
실제 예시를 살펴보면, MCP Client가 MCP Server가 제공하는 Tool 목록을 알고 싶을 때 자체적으로 MCP에서는 tools/list라는 메소드를 사용할 수 있다. 이때의 Request와 Response는 다음과 같다.
// Request
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}
// Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{
"name": "get_weather",
"description": "현재 날씨를 조회합니다."
}
]
}
}
만약 조회한 tool을 통해서 실제 메소드 호출을 한다고 가정해보면 개념적으로 다음과 같은 흐름이다.
1. 사용자 -> AI
서울 날씨 알려줘.
2. LLM 또는 MCP Host/Client 측에서 필요한 Tool을 판단. MCP Server에 Tool 실행 요청
3. MCP Server 응답 후 응답 값 반환
4. LLM 노출
사용자
│
▼
LLM / AI Application
│
▼
MCP Client
│
│
│ MCP Protocol
│
│ JSON-RPC 2.0 Message
│
▼
Transport
(stdio / Streamable HTTP)
│
▼
MCP Server
│
▼
Tool / Resource / Prompt
│
▼
DB / API / File / External System
이를 통해서 MCP는 언어에 구애받지 않고, 프로토콜에 의지하지 않는 처리가 가능하다.
'AI > MCP' 카테고리의 다른 글
| [MCP] MCP Transport - SSE와 Streamable HTTP (0) | 2026.10.08 |
|---|---|
| [MCP] MCP에서 JSON-RPC를 채택한 이유 (0) | 2026.10.06 |