✨ 공부하며 성장하는 기록 공간입니다.
아직 부족한 점이 많고 배워야 할 것도 많지만, 그만큼 배우는 즐거움도 큽니다.
틀리거나 부족한 내용이 있다면 언제든지 편하게 지적해 주세요 😁
이 블로그는 오픈소스 프로젝트 githru-vscode-extension을 공부하고 기여한 내용을 정리한 공간입니다.
처음보다 성장해 있는 나 자신을 기대하며 꾸준히 기록해나가겠습니다!
MCP 3-tier 아키텍처

MCP는 Host-Client-Server로 구성된 3-tier 아키텍처를 채택합니다.
각 계층은 명확한 역할과 책임을 가지며 이를 통해 유연하고 확장가능한 시스템을 구현할 수 있습니다.
- MCP Server
- 도구(tools)와 데이터 소스(resources), 프롬프트(prompts)를 표준 인터페이스로 노출합니다.
- 알림(Notifications)으로 상태변화를 실시간으로 전파하며, 최소 권한과 로깅 등 보안 규약을 적용합니다.
- 이는 로컬 STDIO 서버 또는 원격 HTTP(SSE)서버 모두 가능합니다.
- MCP Client
- LLM에 포함되어 MCP 서버와 통신합니다.
- HOST 내에서 서버별로 1개씩 인스턴스화되어 해당 서버와 1:1 연결을 유지합니다.
- 초기화 시 프로토콜/능력(capabilities) 협상을 수행하고, tools/list, resources/read, tools/call 등 데이터 레이어 요청을 처리합니다.
- MCP Host
- Claude, Cursor 등과 같은 LLM 및 클라이언트를 통합하는 애플리케이션입니다.
- 각 MCP Client의 기능을 취합해 LLM에게 사용 가능한 도구/데이터를 제공하고, 사용자 동의/승인 플로우와 UI를 담당합니다.
MCP 서버
AI 앱(Host/Client) 과 외부 서비스 사이에서 표준화된 컨텍스트 공급자 역할 수행
MCP 서버는 LLM이 외부 세계(데이터, API, 서비스 등)에 안전하게 접근할 수 있도록 도구(tools) 와 리소스(resources) 를 표준화된 인터페이스로 제공합니다.
어떤 서비스든 MCP 서버가 될 수 있다.
MCP는 어느 특정 기술 스택에 종속되지 않습니다.
이는 이전 포스팅에서 살펴본, 파일시스템, 데이터베이스, Github 등 어떤 서비스든 JSON-RPC 기반의 인터페이스만 구현하면 MCP 서버로 동작할 수 있습니다.
예를 들어 Github는 MCP Server는 다음과 같은 작업을 LLM을 통해 수행할 수 있도록 해줍니다.
- Issue 생성
- PR 목록 조회
- 라벨관리, 커밋 요약 등
이 모든 과정은 LLM이 직접 Github API를 호출하는 것이 아니라 MCP 서버가 안전하게 중계합니다.
MCP 서버의 역할.
| 역할 | 설명 | 예시 |
| Tools 제공자 | LLM이 실행할 수 있는 명령을 정의 | summarizePRs, createIssue, 등 ... |
| Resources 제공자 | 컨텍스트 데이터를 표준 포맷으로 제공 | 파일 내용, DB 결과, API 응답 등 |
| Prompts 제공자 | 재사용 가능한 프롬프트 템플릿 제공 | "코드 리뷰 요약", "릴리스 노트 작성" |
| Notification 발행자 | 서버 상태나 도구 변경사항을 실시간 전달 | tools/list_changed 알림 |
MCP 서버는 도구 실행 로직을 실제로 수행하는 주체이자,
데이터 소스에 대한 접근권한을 처리하는 Gateway의 역할을 합니다.
이 각각은 모두 JSON-RPC 메소드를 통해 접근이 가능합니다.
동작 원리
- Lifecycle Management: initialize 단계에서 capabilities 협상
- Tools/Resources/Prompts Discovery: LLM이 사용 가능한 기능 탐색
- Notification: 서버에서 도구 변경사항을 실시간으로 클라이언트에 푸시
보안과 제어
모든 MCP 서버는 보안을 최우선으로 설계되어 있습니다.
- 사용자 동의 기반 접근: LLM이 MCP 서버를 사용하기 전에, 사용자는 명시적으로 연결을 승인해야 합니다.
- 최소 권한 원칙(Least Privilege): 서버는 지정된 범위 내의 리소스만 노출합니다.
- 로깅 및 감사: 어떤 도구가 언제, 누구에 의해 호출되었는지 추적할 수 있습니다.
- API 인증 통합: OAuth, API 키, 토큰 기반 인증을 통한 안전한 호출이 가능.
이 덕분에 LLM이 임의로 민감한 데이터를 읽거나, 승인되지 않은 작업을 수행하는 위험을 최소화할 수 있습니다.
MCP 서버 배포 형태
| 유형 | 설명 | 예시 |
| 로컬(Local) | Host와 같은 머신에서 실행되며 STDIO로 통신 | FIleSystem MCP 서버, Local DB |
| 원격(Remote) | 네트워크를 통해 연결되며 HTTP(SSE)로 통신 | Github, Jira 등 SaaS MCP 서버 |
로컬 서버는 개발 환경에서 빠른 응답 속도를,
원격 서버는 기업 데이터 및 협업 플랫폼과의 연동을 담당합니다.
Claude Desktop이나 Cursor 같은 Host는
여러 MCP 서버(Local + Remote)를 동시에 연결해 멀티 컨텍스트 환경을 구성할 수 있습니다.
MCP Server의 구성요소
Tools - LLM이 행동을 수행하는 수단
🔹 역할
Tools는 MCP 서버가 LLM에게 노출하는 실행 가능한 함수형 인터페이스입니다.
LLM은 사용자의 요청에 따라 필요한 도구를 스스로 선택하고, tools/call을 통해 실행을 요청합니다.
🔹 프로토콜 메소드
| Method | 설명 | 반환값 |
| tools/list | 사용 가능한 도구 목록 탐색 | 각 도구의 이름, 설명, 입력 스키마 |
| tools/call | 특정 도구 실행 | 실행 결과(JSON, Text, image) |
Resources - AI가 이해할 수 있는 데이터 제공
🔹 역할
Resources는 MCP 서버가 노출하느 읽기전용 데이터 소스로,
파일 시스템, 데이터베이스, API 응답 등 모델이 참고할 수 잇는 컨텍스트 정보를 제공합니다.
🔹 프로토콜 메소드
| Method | 설명 | 반환값 |
| resources/list | 접근 가능한 리소스 목록 조회 | URI와 메타데이터 |
| resources/read | 리소스 데이터 읽기. | 본문+MIME 타입 |
| resources/templates/list | 동적 URI 템플릿 조회 | 파라미터화된 리소스 목록 |
🔹 URI 설계 예시
- file:///project/README.md — 파일 콘텐츠
- repo://githru/issues/open — API 데이터
- travel://forecast/{city}/{date} — 파라미터화된 템플릿
🔹 특징
- 정적 리소스(Direct) 와 동적 템플릿(Resource Templates) 모두 지원
- 리소스별 MIME 타입 지정(application/json, text/markdown 등)
- 실시간 업데이트가 필요할 경우 resources/subscribe 로 변경 알림 수신 가능
Prompts - 사용자가 주도하는 워크플로우 템플릿
🔹 역할
Prompts는 MCP 서버가 제공하는 재사용 가능한 프롬프트 템플릿입니다.
사용자가 특정 작업을 쉽게 수행하도록 미리 정의된 입력 필드와 구조를 제공합니다.
🔹 프로토콜 메서드
| Method | 설명 | 반환값 |
| prompts/list | 사용 가능한 프롬프트 목록 조회 | 이름, 제목, 설명, 인자 |
| prompts/get | 특정 프롬프트 상세 조회 | 인자 정의, 기본값 등 |
Tools / Resources / Prompts 상호작용 예시

“Prompts가 워크플로우를 시작하고, Resources에서 컨텍스트를 수집하며, Tools를 통해 행동을 수행한다.”
예시:
사용자가 “/plan-vacation” 프롬프트 실행 →
1️⃣ Resources: calendar://events/June-2025, weather://forecast/Barcelona
2️⃣ Tools: searchFlights(), bookHotel(), createCalendarEvent()
3️⃣ 결과: 일정 + 예약 + 이메일까지 자동 처리
MCP Server 구현 예시(TypeScript)
import { createServer } from "mcp-sdk";
import { z } from "zod";
const server = createServer(
{
name: "searchFlights",
description: "Search for available flights",
inputSchema: {
type: "object",
properties: {
origin: { type: "string", description: "Departure city" },
destination: { type: "string", description: "Arrival city" },
date: { type: "string", format: "date", description: "Travel date" }
},
required: ["origin", "destination", "date"]
}
}
);
server.listenStdio();
Request
searchFlights(origin: "NYC", destination: "Barcelona", date: "2024-06-15")'OSSCA > 2025' 카테고리의 다른 글
| [OSSCA2025] MCP 개요 (0) | 2025.10.21 |
|---|---|
| [OSSCA2025] 2025 OSSCA 발대식 후기 (0) | 2025.07.14 |