MCP 클라이언트 구현은 LLM 앱 안의 커넥터가 JSON-RPC 2.0으로 MCP 서버의 도구와 데이터를 업무에 붙이는 작업입니다. 로컬은 stdio, 원격은 Streamable HTTP로 연 뒤 서버 기능을 확인하고 도구를 호출하면 됩니다. Claude MCP처럼 호스트가 이미 있는 경우에도 클라이언트는 권한과 호출 규칙, 프로토콜 버전만 맞추면 됩니다.
구현 전에 서버가 제공하는 Resources, Prompts, Tools를 구분하고 전송 방식과 인증을 정해야 합니다. 2026-07-28 스펙은 요청마다 버전과 신원을 실어 보내는 무상태 모델을 쓰므로 예전 initialize 핸드셰이크만 가정하면 연결이 어긋납니다. 이 순서를 건너뛰면 도구가 보여도 호출이 거절됩니다.
MCP 클라이언트가 하는 일과 구현 전 준비

MCP 클라이언트는 Host가 연 연결 안에서 서버와 JSON-RPC 2.0 메시지를 주고받는 커넥터입니다. 서버는 컨텍스트와 기능을 제공하고 클라이언트는 그 기능을 모델이 업무에 쓰도록 중계합니다. 구현 전에는 로컬 stdio인지 원격 Streamable HTTP인지, 인증은 OAuth로 토큰을 받을지부터 정해야 합니다. 도구 목록만 보고 바로 호출하면 권한과 프로토콜 버전이 어긋나 실패하기 쉽습니다.
공식 스펙은 MCP를 LLM 애플리케이션과 외부 데이터·도구를 표준으로 연결하는 공개 프로토콜로 둡니다. 업무 자동화 MCP를 붙이려면 서버가 줄 Resources, Prompts, Tools 범위를 먼저 적어두십시오. 인증 방식을 나중에 바꾸면 헤더와 토큰 처리가 함께 흔들립니다.
서버·도구·세션 개념을 한 번에 잡기
Host는 연결을 시작하는 LLM 앱이고 Client는 호스트 안의 커넥터이며 Server는 기능을 제공하는 서비스입니다. 서버가 클라이언트에 줄 수 있는 핵심은 Resources, Prompts, Tools입니다. Resources는 데이터, Prompts는 템플릿 메시지, Tools는 모델이 실행하는 함수입니다. 세션을 오래 붙잡아 두는 모델은 더 이상 기본이 아닙니다.
2026-07-28 스펙은 initialize와 Mcp-Session-Id를 폐기하고 요청마다 _meta에 프로토콜 버전과 신원, capabilities를 실어 보냅니다. Sampling은 이 버전에서 deprecated입니다. 서버가 사용자에게 추가 정보를 요청하는 elicitation은 클라이언트 기능입니다.
실무에서 쓰는 MCP 클라이언트 구현 흐름
(출처: Codedeck)
공식 Python SDK의 Client는 in-process 서버 객체, Streamable HTTP URL, stdio 같은 커스텀 transport로 MCP 서버에 연결합니다. URL 문자열이면 Streamable HTTP로 붙고 같은 머신이면 stdio가 단순하고 로그도 바로 보입니다. 연결 뒤에는 list_tools와 call_tool 같은 프로토콜 동작을 async 메서드로 호출하면 됩니다.
원격 전송은 클라이언트에서 서버로 HTTP POST를 보내고 스트리밍은 선택적 SSE입니다. 인증은 bearer나 API key, 커스텀 헤더를 쓸 수 있으며 원격에는 OAuth로 토큰을 받는 방식이 권장됩니다. 같은 머신에서 서버를 띄울 때는 프로세스 생명주기를 클라이언트가 책임집니다.
초기화부터 도구 호출까지 최소 시퀀스
다른 요청을 보내기 전에 server/discover RPC로 지원 버전과 capabilities를 확인합니다. 아키텍처 문서상 서버는 이 요청을 구현해야 합니다. 예전 initialize와 initialized 핸드셰이크만 넣으면 2026-07-28 서버와 세션 가정이 어긋납니다.
확인이 끝나면 도구 목록을 받은 뒤 필요한 도구만 call_tool로 실행합니다. 요청마다 _meta에 프로토콜 버전과 클라이언트 신원, capabilities를 실어야 무상태 요청 모델과 맞습니다.
도구 이름과 인자는 서버가 공개한 스키마를 한 글자도 바꾸지 말고 써야 합니다. 임의 필드를 보내면 호출이 실패하고 업무 자동화가 멈춥니다.
연결 오류·권한·도구 호출 실패를 줄이는 점검 포인트
연결 실패는 전송 계층과 프로토콜 버전을 먼저 봅니다. stdio는 프로세스 실행과 표준입출력이 막혔는지, Streamable HTTP는 POST 경로와 SSE 수신이 맞는지 확인합니다. 원격이면 토큰 만료와 스코프 부족이 권한 오류로 자주 납니다.
도구 호출 실패는 서버가 해당 Tools를 실제로 노출했는지, 인자 스키마가 맞는지부터 점검합니다. 클라이언트가 capabilities를 _meta에 빠뜨리거나 discover 없이 호출하면 서버가 기능을 거절할 수 있습니다. 스키마가 맞아도 사용자 확인이 필요한 도구는 elicitation 응답이 없으면 멈춥니다.
로그에는 HTTP 상태와 JSON-RPC 오류 코드가 같이 남는지 봅니다. 한쪽만 보면 전송 문제와 도구 문제를 섞어 고치게 됩니다.
| 점검 구간 | 먼저 볼 항목 | 실패가 잦은 조건 |
|---|---|---|
| 전송 | stdio 프로세스와 Streamable HTTP POST | 경로 오인, SSE 미수신 |
| 권한 | OAuth 토큰과 스코프 | 만료, API key 누락 |
| 도구 호출 | Tools 노출과 인자 스키마 | discover 생략, _meta 누락 |
권한과 원격 인증을 점검하는 순서
원격 MCP 서버 연결에서는 토큰을 받은 뒤에야 도구를 호출하는 편이 안전합니다. OAuth가 권장되며 bearer나 API key, 커스텀 헤더도 쓸 수 있습니다. 토큰 스코프가 도구 실행을 포함하지 않으면 목록은 보여도 실행이 거절됩니다.
만료 시각을 클라이언트에 저장하고 재발급이 실패하면 호출을 멈추고 사용자에게 elicitation으로 재로그인을 요청할 수 있습니다. 로컬 stdio는 보통 토큰이 없어도 되지만 파일 권한과 실행 계정은 따로 봐야 합니다.
헤더 이름이 서버 문서와 다르면 401이 반복됩니다. 클라이언트가 매 요청에 최신 토큰을 붙이는지부터 확인하십시오. 스코프 변경 후에는 discover를 다시 보내 도구 목록이 바뀌었는지 봅니다.
도구 호출이 거절될 때 확인할 값
호출이 거절되면 서버가 그 이름을 Tools로 노출했는지부터 봅니다. 목록에 없는 이름을 보내면 스키마를 고쳐도 통과하지 않습니다. 인자는 타입과 필수 항목이 맞아야 하며 빈 문자열을 넣어도 실패할 수 있습니다.
JSON-RPC 오류 코드와 메시지에 필드 이름이 있으면 그 필드만 고칩니다. capabilities를 _meta에 빠뜨린 경우에도 서버가 도구 실행을 막을 수 있습니다. 오류 본문이 비어 있으면 HTTP 상태만 보고 전송 계층을 의심합니다.
모델이 임의로 도구를 고르지 못하게 클라이언트에서 허용 목록을 두면 오호출이 줄어듭니다. 업무 자동화 MCP에서는 쓰기 도구와 읽기 도구를 나누어 권한을 거는 편이 사고 범위를 줄입니다.
MCP 클라이언트 구현 핵심 정리
MCP 클라이언트 구현의 뼈대는 Host 안에서 서버와 JSON-RPC 2.0으로 말하고 Resources·Prompts·Tools를 업무에 붙이는 일입니다. 전송은 로컬 stdio와 원격 Streamable HTTP를 고르고 원격 인증은 OAuth 토큰을 우선합니다. Python SDK를 쓰면 연결 대상만 바꿔도 같은 호출 코드를 재사용할 수 있습니다.
2026-07-28 기준으로는 discover로 기능을 확인한 뒤 요청마다 _meta를 실어 호출하는 순서가 안전합니다. Claude MCP 호스트를 쓰더라도 클라이언트는 버전, 권한, 도구 스키마를 같은 방식으로 맞춰야 합니다. 연결 오류는 전송과 토큰부터, 호출 실패는 도구 노출과 인자부터 보면 재작업을 줄일 수 있습니다. 이 점검 순서를 코드에 고정하면 재현 없는 실패를 줄입니다.