MCP 서버 구축
나만의 MCP 서버 직접 만들어보기

MCP(Model Context Protocol)
Model Context Protocol (MCP)는 대규모 언어 모델(LLM)이 애플리케이션과 상호작용할 수 있도록 표준화된 방식으로 컨텍스트를 제공하는 프로토콜입니다.
LLM이 내가 사용하는 여러가지 어플리케이션을, 하나의 도구(tool)로써 활용할 수 있게 만들어주는 방법이라 할 수 있습니다. 마치 나를 잘 알고 나의 일을 돕는 비서처럼, LLM이 에이전트(Agent)로써 거듭날 수 있게 만들어 줍니다.
MCP 주요 구성 요소
- 호스트(Host) : LLM 기반 애플리케이션 (예: Claude Desktop, Cursor, Docker AI…)
- 클라이언트(Client) : 서버와 1:1 연결 유지
- 서버(Server) : 특정 기능이나 리소스 제공
MCP 서버 구성 요소
- 도구(Tools) : LLM이 작업(사이드 이펙트 포함)을 수행하도록 기능 제공 (예: POST 엔드포인트와 유사)
- 프롬프트(Prompts) : LLM과의 상호작용을 위한 템플릿 문장을 작성
- 리소스(Resources) : LLM에 읽기 전용 데이터를 제공 (예: GET 엔드포인트와 유사)
MCP 서버 프로젝트 구조
뭘 만드나?
세미나에 참석한 인원을 조회하고 관리하는 에이전트를 MCP 서버로 만들어 보겠습니다.
uv 설치
uv는 pip와 같은 패키지 매니저 입니다. MCP Python SDK 공식 문서에서는 uv 사용을 권장하고 있습니다. Installing uv 페이지를 참고해서 설치 합니다.
폴더 구조
project/
├── Dockerfile
├── pyproject.toml
├── src
│ ├── attendance-A.md
│ ├── attendance-B.md
│ ├── seminar.py
│ └── server.py
└── uv.lock
MCP 서버 코드
attendance-A.md
, attendance-B.md
에 각각 참석자 명단이 존재합니다. 그리고 seminar_attendees
함수에서 해당 파일을 읽어서 리스트 형태로 돌려주는 코드입니다.
from mcp.server.fastmcp import FastMCP
from seminar import seminar_attendees
from datetime import datetime
import json
mcp = FastMCP("Seminar Management System")
@mcp.tool()
def get_seminar_details(party_name: str) -> str:
attendees = seminar_attendees(party_name)
seminar_info = {
"name": party_name,
"total_attendees": len(attendees),
"attendees": attendees,
}
return json.dumps(seminar_info, ensure_ascii=False, indent=2)
@mcp.tool()
def register_attendee(party_name: str, attendee_name: str) -> str:
# 실제 구현에서는 데이터베이스에 참석자를 추가하는 로직이 있을 것입니다
return f"성공: {attendee_name}님이 {party_name} 세미나에 등록되었습니다."
@mcp.prompt()
def prompt(message: str) -> str:
return f"""
당신은 세미나 관리 시스템의 AI 어시스턴트입니다.
사용 가능한 도구:
- get_seminar_details(party_name) - 특정 세미나의 상세 정보를 조회합니다.
- register_attendee(party_name, attendee_name) - 새 참석자를 등록합니다.
사용자 메시지: {message}
"""
if __name__ == "__main__":
mcp.run()
도구(tool)
- LLM이 실행할 수 있는 함수로 등록
@mcp.tool()
프롬프트(prompt)
- LLM과의 상호작용을 위한 템플릿
- 입력된 message를 받아 LLM에 전달할 재사용 가능한 지시문 제공
@mcp.prompt()
MCP 서버 디버깅과 구동
MCP Inspector 사용
MCP Inspector는 서버를 테스트하고 디버깅하는 가장 좋은 방법입니다. 아래 명령은 개발 모드에서 MCP 서버를 실행하고 Inspector 인터페이스를 표시하여 리소스, 도구 및 프롬프트를 테스트할 수 있게 해줍니다.
$ mcp dev src/server.py
Starting MCP inspector...
Proxy server listening on port 3000
🔍 MCP Inspector is up and running at http://localhost:5173 🚀
디버깅 팁
Claude Desktop에서 MCP 서버를 연동하면 claude_desktop_config.json
폴더 하위에 logs
폴더에서 로그를 확인 할 수 있습니다.
Dockerfile
개발한 MCP 서버를 환경에 상관없이 가장 쉽게 MCP 클라이언트와 연동할 수 있는 방법은 도커를 이용하는 방법이였습니다.
FROM python:3.11-slim
WORKDIR /app
# curl 설치
RUN apt-get update && apt-get install -y curl
# 전체 프로젝트 복사
COPY . .
# uv 설치 (전역 설치 위치로 들어감)
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
# uv가 설치된 경로를 PATH에 추가
ENV PATH="/root/.local/bin:${PATH}"
# 가상환경 생성 및 프로젝트 설치
RUN uv venv .venv && uv pip install -r pyproject.toml
# 필요한 포트 오픈
EXPOSE 3000
EXPOSE 5173
# MCP 서버 실행
ENTRYPOINT ["uv", "run", "mcp", "run", "src/server.py:mcp"]
호스트 연결
Docker Image
우선 아래의 명렁으로 MCP 서버 도커 이미지를 생성합니다.
$ docker image build -t mcp/seminar .
Claude Desktop 연동
{
"mcpServers": {
"seminar_attendees": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-p",
"3010:3000",
"mcp/seminar"
]
}
}
}
Cursor 연동
{
"mcpServers": {
"seminar_attendees": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-p",
"3010:3000",
"mcp/seminar"
]
}
}
}
질의 해보기
Claude Desktop
Claude Desktop에서 MCP에서 첨부
버튼을 클릭하고 입력창에 내용을 입력하면, @mcp.prompt()
로 만들어둔 탬플릿을 사용 가능합니다. 마치 프롬프트엔지니어링 기법처럼 활용 가능했습니다!


Cursor
커서에는 따로 MCP에서 첨부
와 같이 컨텍스트를 지정할 수 있는 기능이 없어서 질의를 제대로 하기 위해서는 추가적인 정보를 작성해줘야 했습니다.
마무리
생각보다 MCP 서버를 직접 만드는게 너무 쉽지 않나요?
그냥 대충 질문해도 찰떡같이 알아듣는 LLM에게 MCP 서버라는 도구(tool)만 만들어 주면, 내가 해야하는 귀찮은 일들을 너무나 잘 처리해줬습니다!
꼭 자신만의 MCP 서버를 만들어보시길 바랍니다! 감사합니다! 😊