Sign in to save your progressYou can keep reading without an account, but completed lessons won't be saved.
Sign in

MCP 클라이언트와 서버는 JSON 메시지를 교환하여 통신하지만, 이러한 메시지는 실제로 어떻게 전송될까요? 사용되는 통신 채널을 **전송 방식(transport)**이라고 하며, 이를 구현하는 방법에는 여러 가지가 있습니다 - HTTP 요청부터 WebSocket, 심지어 엽서에 JSON을 적는 방법까지 있습니다(다만 마지막 방법은 프로덕션 환경에서 사용하는 것을 권장하지 않습니다).

Stdio 전송 방식

MCP 서버나 클라이언트를 처음 개발할 때 가장 일반적으로 사용되는 전송 방식은 stdio 전송 방식입니다. 이 방식은 간단합니다: 클라이언트가 MCP 서버를 서브프로세스로 실행하고 표준 입력 및 출력 스트림을 통해 통신합니다.

stdio 전송 방식 다이어그램: MCP 클라이언트가 서버의 stdin을 통해 MCP 서버로 메시지를 보내고, 서버는 stdout을 통해 메시지를 다시 보냅니다; 양쪽 모두 언제든지 메시지를 보낼 수 있으며, 클라이언트와 서버가 동일한 머신에서 실행될 때만 작동합니다

작동 방식은 다음과 같습니다:

  • 클라이언트는 서버의 stdin을 사용하여 서버로 메시지를 보냅니다
  • 서버는 stdout에 작성하여 응답합니다
  • 서버나 클라이언트 모두 언제든지 메시지를 보낼 수 있습니다
  • 클라이언트와 서버가 동일한 머신에서 실행될 때만 작동합니다

Stdio 실제로 살펴보기

별도의 클라이언트를 작성하지 않고도 터미널에서 직접 MCP 서버를 테스트할 수 있습니다. uv run server.py로 서버를 실행하면 stdin을 수신하고 stdout에 응답을 작성합니다. 즉, JSON 메시지를 터미널에 직접 붙여넣고 서버의 응답을 즉시 확인할 수 있습니다.

터미널 출력에는 초기화 및 도구 호출에 대한 예시 메시지를 포함한 전체 메시지 교환 내용이 표시됩니다.

MCP 연결 시퀀스

모든 MCP 연결은 특정한 세 단계의 메시지 핸드셰이크로 시작해야 합니다:

MCP 핸드셰이크 시퀀스 다이어그램: 클라이언트가 서버로 Initialize Request를 보내고, 서버는 Initialize Result로 응답하며, 그 다음 클라이언트가 Initialized Notification을 보내는데 이에 대한 결과는 돌아오지 않습니다

  1. Initialize Request - 클라이언트가 먼저 이것을 보냅니다
  2. Initialize Result - 서버가 기능(capabilities)으로 응답합니다
  3. Initialized Notification - 클라이언트가 확인합니다(응답이 예상되지 않음)

이 핸드셰이크가 끝난 후에만 도구 호출이나 프롬프트 목록 조회와 같은 다른 요청을 보낼 수 있습니다.

메시지 유형과 흐름

MCP는 양방향으로 흐르는 다양한 메시지 유형을 지원합니다:

클라이언트와 서버 간 MCP 메시지 유형 차트: Call Tool Request → Call Tool Result와 같은 클라이언트 주도 요청/결과 쌍, Create Message Request 및 List Roots Request와 같은 서버 주도 쌍, 그리고 응답이 필요하지 않은 각 측의 단방향 알림

핵심은 일부 메시지는 응답이 필요하지만(요청 → 결과) 다른 메시지는 그렇지 않다는 것입니다(알림). 클라이언트와 서버 모두 언제든지 통신을 시작할 수 있습니다.

네 가지 통신 시나리오

어떤 전송 방식을 사용하든 네 가지 다른 통신 패턴을 처리해야 합니다:

"이러한 패턴들을 stdio로 어떻게 구현할 수 있을까요?"라는 제목의 다이어그램으로, 클라이언트에서 서버로의 초기 요청, 서버에서 클라이언트로의 응답, 서버에서 클라이언트로의 초기 요청, 클라이언트에서 서버로의 응답이라는 네 가지 패턴을 나열하며, 그 옆에는 MCP 클라이언트가 MCP 서버의 stdin 및 stdout에 연결된 모습이 표시됩니다

  • 클라이언트 → 서버 요청: 클라이언트가 stdin에 작성합니다
  • 서버 → 클라이언트 응답: 서버가 stdout에 작성합니다
  • 서버 → 클라이언트 요청: 서버가 stdout에 작성합니다
  • 클라이언트 → 서버 응답: 클라이언트가 stdin에 작성합니다

stdio 전송 방식의 장점은 그 단순함에 있습니다 - 이 두 채널을 사용하여 어느 쪽이든 언제든지 통신을 시작할 수 있습니다.

왜 이것이 중요한가

stdio 전송 방식을 이해하는 것이 중요한 이유는 양방향 통신이 원활하게 이루어지는 "이상적인" 사례를 보여주기 때문입니다. HTTP와 같은 다른 전송 방식으로 넘어가면 서버가 항상 클라이언트로 요청을 시작할 수 없는 제약을 마주하게 됩니다. stdio 전송 방식은 다른 전송 방식의 제약을 다루기 전에 완전한 MCP 통신이 어떤 모습인지 이해하기 위한 기준선 역할을 합니다.

개발 및 테스트 목적으로는 stdio 전송 방식이 완벽합니다. 클라이언트와 서버가 서로 다른 머신에서 실행되어야 하는 프로덕션 배포의 경우, 각각의 장단점을 가진 다른 전송 방식 옵션을 고려해야 합니다.