MCP 서버 구축

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

written by tiaz0128

MCP(Model Context Protocol)

Model Context Protocol (MCP)는 대규모 언어 모델(LLM)이 애플리케이션과 상호작용할 수 있도록 표준화된 방식으로 컨텍스트를 제공하는 프로토콜입니다.

LLM이 내가 사용하는 여러가지 어플리케이션을, 하나의 도구(tool)로써 활용할 수 있게 만들어주는 방법이라 할 수 있습니다. 마치 나를 잘 알고 나의 일을 돕는 비서처럼, LLM이 에이전트(Agent)로써 거듭날 수 있게 만들어 줍니다.

MCP 주요 구성 요소

MCP 서버 구성 요소

MCP 서버 프로젝트 구조

뭘 만드나?

세미나에 참석한 인원을 조회하고 관리하는 에이전트를 MCP 서버로 만들어 보겠습니다.

uv 설치

uv는 pip와 같은 패키지 매니저 입니다. MCP Python SDK 공식 문서에서는 uv 사용을 권장하고 있습니다. Installing uv 페이지를 참고해서 설치 합니다.

폴더 구조

예시에서는 도커를 이용해서 MCP 서버를 구동합니다.
project/
├── Dockerfile
├── pyproject.toml
├── src
│   ├── attendance-A.md
│   ├── attendance-B.md
│   ├── seminar.py
│   └── server.py
└── uv.lock

MCP 서버 코드

예제에서는 `tool`과 `prompt`를 사용해보겠습니다.

attendance-A.md, attendance-B.md에 각각 참석자 명단이 존재합니다. 그리고 seminar_attendees 함수에서 해당 파일을 읽어서 리스트 형태로 돌려주는 코드입니다.

src/server.py
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)

프롬프트(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 클라이언트와 연동할 수 있는 방법은 도커를 이용하는 방법이였습니다.

Dockerfile
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 연동

'Claude Desktop 설정 방법'에 대해 더 자세히 알고 싶으시다면, "MCP 옵시디언 연동" 글을 확인 해주세요!
claude_desktop_config.json
{
  "mcpServers": {
    "seminar_attendees": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-p",
        "3010:3000",
        "mcp/seminar"
      ]
    }
  }
}

Cursor 연동

'Cursor 설정 방법'에 대해 더 자세히 알고 싶으시다면, "MCP Cursor 연동" 글을 확인 해주세요!
mcp.json
{
  "mcpServers": {
    "seminar_attendees": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-p",
        "3010:3000",
        "mcp/seminar"
      ]
    }
  }
} 

질의 해보기

Claude Desktop

Claude Desktop에서 MCP에서 첨부 버튼을 클릭하고 입력창에 내용을 입력하면, @mcp.prompt()로 만들어둔 탬플릿을 사용 가능합니다. 마치 프롬프트엔지니어링 기법처럼 활용 가능했습니다!

Claude Desktop

Cursor

커서에는 따로 MCP에서 첨부와 같이 컨텍스트를 지정할 수 있는 기능이 없어서 질의를 제대로 하기 위해서는 추가적인 정보를 작성해줘야 했습니다.

Cursor MCP Server

마무리

생각보다 MCP 서버를 직접 만드는게 너무 쉽지 않나요?

그냥 대충 질문해도 찰떡같이 알아듣는 LLM에게 MCP 서버라는 도구(tool)만 만들어 주면, 내가 해야하는 귀찮은 일들을 너무나 잘 처리해줬습니다!

꼭 자신만의 MCP 서버를 만들어보시길 바랍니다! 감사합니다! 😊

참고 문헌

MCP AI python

tiaz0128

Eat Sleep Coding.

Never Never GiveUp.

Security  |  BackEnd  |  Multi Cloud