MCP(Model Context Protocol) 구조 분석 – 로컬 MCP 서버 구현

zion·2026년 2월 27일

1. LLM은 왜 외부 시스템을 모를까?

LLM은 학습 시점까지의 정적 데이터만을 기반으로 동작한다.
따라서 다음과 같은 정보에는 접근할 수 없다.

  • 현재 DB 상태
  • 실시간 배포 현황
  • GitHub 이슈 목록
  • 내부 비즈니스 데이터

기존에는 이러한 문제를 해결하기 위해 서비스별 맞춤 연동 코드를 작성해야 했다.
그러나 이 방식은 다음과 같은 한계를 가진다.

  • 연동 방식이 서비스마다 상이함
  • 재사용 불가능
  • 클라이언트 종속적인 구현
  • 표준 부재로 인한 확장성 부족

이 문제를 해결하기 위해 등장한 것이 MCP(Model Context Protocol)이다.


2. MCP의 설계 목적

MCP는 AI와 외부 시스템 간의 상호작용을 표준화하기 위한 프로토콜이다.

핵심 철학은 다음과 같다.

AI의 판단 영역과 실행 영역을 명확히 분리한다.

  • AI(Claude)는 어떤 도구를 사용할지 판단한다.
  • MCP 서버는 실제 실행만 담당한다.
  • 프로토콜은 그 사이의 통신 규격을 정의한다.

이 설계는 확장성과 재사용성을 동시에 확보한다.


3. 프로토콜 구조: JSON-RPC 기반 설계

MCP는 JSON-RPC 2.0 위에서 동작한다.

{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { ... } }

모든 통신은 method 호출 형태로 이루어진다.

핵심 구성 요소

구성 요소역할
ResourcesAI가 읽는 데이터 소스
Prompts재사용 가능한 프롬프트 템플릿
ToolsAI가 실행하는 함수

여기서 중요한 점은:

Tool 선택 로직은 서버에 존재하지 않는다.

Claude는 tools/list를 통해 메뉴를 받고,
각 Tool의 descriptioninputSchema를 기반으로 호출을 결정한다.

즉, MCP 서버 설계에서 가장 중요한 요소는
명확한 description과 정확한 input schema 정의다.


4. Wikipedia MCP 서버 구현

실제 프로토콜 흐름을 확인하기 위해 Wikipedia API 기반 MCP 서버를 구현했다.

Tool 등록

server.registerTool(
  "search",
  {
    description: "Wikipedia에서 키워드로 문서를 검색합니다",
    inputSchema: {
      keyword: z.string(),
      lang: z.enum(["ko", "en"]).default("ko"),
    },
  },
  async ({ keyword, lang }) => {
    const url = `https://${lang}.wikipedia.org/w/api.php?action=query&list=search&srsearch=${encodeURIComponent(keyword)}&format=json&origin=*&srlimit=5`;
    const res = await fetch(url);
    const data = await res.json();
    const results = data.query.search.map((item, i) => `${i + 1}. ${item.title}`);
    return { content: [{ type: "text", text: results.join("\n") }] };
  }
);

Zod로 정의한 스키마는 JSON Schema로 변환되어 Claude에 전달된다.
Claude는 이를 기반으로 arguments를 자동 구성한다.

서버는 “어떤 상황에서 search를 써야 하는지”를 판단하지 않는다.
그 판단은 전적으로 Claude의 역할이다.


5. 실제 프로토콜 흐름 분석

Inspector를 통해 확인한 호출 순서는 다음과 같다.

  1. initialize
  2. tools/list
  3. tools/call

tools/list – 메뉴 제공

{ "method": "tools/list" }

서버는 사용 가능한 Tool 목록을 반환한다.

tools/call – 실행 요청

{
  "method": "tools/call",
  "params": {
    "name": "search",
    "arguments": { "keyword": "인공지능" }
  }
}

Claude는 inputSchema를 참고해 arguments를 자동 생성한다.

이 구조는 AI의 추론 능력을 활용하는 설계다.
서버는 로직을 최소화하고 실행 책임만 가진다.


6. Sampling: 양방향 상호작용

MCP의 흥미로운 기능 중 하나는 Sampling이다.

일반 흐름:

Claude → MCP 서버

Sampling 흐름:

MCP 서버 → Claude

서버가 데이터를 수집한 뒤,
Claude에게 다시 요약·분석을 요청할 수 있다.

이는 데이터 수집 계층과 추론 계층을 분리하는 구조를 가능하게 한다.


7. Transport 계층: Stdio vs SSE

MCP 메시지 자체는 동일하지만, 전달 방식이 다르다.

구분StdioSSE
통신 방식표준 입출력HTTP + Server-Sent Events
Claude Desktop 지원지원미지원
서버 실행 방식Claude가 직접 실행독립 서버

중요한 점은:

Transport는 메시지 전달 방식일 뿐, 프로토콜 로직과는 무관하다.

이 설계는 프로토콜 계층과 네트워크 계층을 명확히 분리한다.


8. 설계적 인사이트

Wikipedia 서버를 구현하며 얻은 핵심 인사이트는 다음과 같다.

  1. MCP는 단순 API 래퍼가 아니다.
  2. AI 중심 설계를 전제로 한 프로토콜이다.
  3. 서버 로직을 최소화할수록 유연성이 높아진다.
  4. description 설계가 곧 UX 설계다.

즉, MCP 서버는 단순한 “백엔드 서비스”가 아니라
AI의 추론을 보조하는 실행 레이어에 가깝다.


결론

MCP는 AI와 외부 시스템 간의 상호작용을 표준화하는 프로토콜이다.
JSON-RPC 기반 구조, Tool 중심 설계, Transport 분리 구조는 확장성과 재사용성을 고려한 설계다.

Wikipedia 서버 구현을 통해 확인한 것은 단순 사용법이 아니라,
AI 중심 아키텍처가 어떻게 프로토콜 수준에서 설계되는지에 대한 이해였다.

profile
be_zion

0개의 댓글