본문 바로가기

AI관련

MCP 서버 직접 만들기: Python FastMCP

반응형

MCP 서버를 직접 만들어서 Claude에게 나만의 도구를 제공하는 방법을 다룬다. Python FastMCP를 사용해 TODO 관리 서버를 구현하고, Claude Code에 등록하는 전체 과정을 설명한다.

사전 지식: MCP 개념과 Claude Code 설정 방법은 https://leesmemo.tistory.com/16 를 참고한다.

 

1. MCP 서버의 3요소

MCP 서버는 세 가지를 Claude에게 제공할 수 있다.

요소역할특징예시

Tools 실행 부수 효과 허용 add_todo(), send_message()
Resources 읽기 읽기 전용 데이터 todos://all, config://settings
Prompts 템플릿 재사용 프롬프트 daily_review, code_review

이 글에서는 Tools와 Resources 구현에 집중한다.

2. 환경 설정

MCP 패키지는 Python 3.10 이상이 필요하다. uv를 사용한 가상환경 구성을 권장한다.

# 1. uv 설치 (없는 경우)
brew install uv

# 2. 프로젝트 디렉토리 생성
mkdir my-mcp-server && cd my-mcp-server

# 3. 가상환경 생성
uv venv .venv --python 3.12

# 4. 활성화
source .venv/bin/activate

# 5. MCP 패키지 설치
uv pip install mcp

 

3. 기본 서버 구조

FastMCP로 서버를 만드는 기본 패턴이다.

from mcp.server.fastmcp import FastMCP
import json

# 서버 초기화
mcp = FastMCP("My Server")

# Tool 정의
@mcp.tool()
def my_function(param: str) -> str:
    """함수 설명 - AI가 이 설명을 보고 언제 호출할지 판단한다"""
    return f"결과: {param}"

# Resource 정의
@mcp.resource("data://items")
def get_items() -> str:
    """데이터 설명"""
    return json.dumps(items)

if __name__ == "__main__":
    mcp.run()

핵심: docstring이 중요하다. AI는 이 설명을 읽고 도구 사용 시점을 판단한다.

4. 실전 예시: TODO 서버

다음 코드를 todo_server.py로 저장하면 바로 실행 가능하다.

from mcp.server.fastmcp import FastMCP
from datetime import datetime
import json

mcp = FastMCP("Todo Server")

todos = []
next_id = 1


@mcp.tool()
def add_todo(title: str, priority: str = "medium") -> str:
    """새 할 일을 추가한다"""
    global next_id

    todo = {
        "id": next_id,
        "title": title,
        "priority": priority,
        "completed": False,
        "created_at": datetime.now().isoformat()
    }

    todos.append(todo)
    next_id += 1

    return json.dumps({
        "success": True,
        "message": f"할 일 추가됨: {title}",
        "todo": todo
    }, ensure_ascii=False)


@mcp.tool()
def list_todos(filter_by: str = "all") -> str:
    """할 일 목록을 조회한다"""
    filtered = todos.copy()

    if filter_by == "pending":
        filtered = [t for t in filtered if not t["completed"]]
    elif filter_by == "completed":
        filtered = [t for t in filtered if t["completed"]]

    return json.dumps({
        "count": len(filtered),
        "todos": filtered
    }, ensure_ascii=False, indent=2)


@mcp.tool()
def complete_todo(todo_id: int) -> str:
    """할 일을 완료 처리한다"""
    for todo in todos:
        if todo["id"] == todo_id:
            todo["completed"] = True
            return json.dumps({
                "success": True,
                "message": f"완료됨: {todo['title']}"
            }, ensure_ascii=False)

    return json.dumps({"error": "할 일을 찾을 수 없음"})


@mcp.resource("todos://stats")
def get_stats() -> str:
    """할 일 통계"""
    total = len(todos)
    completed = len([t for t in todos if t["completed"]])
    return json.dumps({
        "total": total,
        "completed": completed,
        "pending": total - completed,
        "completion_rate": f"{(completed/total*100):.1f}%" if total > 0 else "0%"
    }, ensure_ascii=False)


if __name__ == "__main__":
    mcp.run()

 

5. Claude Code에 서버 등록

등록

claude mcp add todo-server -- /full/path/.venv/bin/python /full/path/todo_server.py

확인:

claude mcp list

제거

claude mcp remove todo-server

 

6. 실제 사용 예시

사용자: 블로그 글 작성 할 일 추가해줘
Claude: add_todo 호출

사용자: 할 일 목록 보여줘
Claude: list_todos 호출

사용자: 1번 완료 처리해줘
Claude: complete_todo 호출

 

7. 트러블슈팅

Python 버전 에러

uv venv .venv --python 3.12
uv pip install mcp

서버 연결 실패

절대 경로 사용 권장.

FastMCP API 변경

# 최신 방식
mcp = FastMCP("Todo Server")

 

8. MCP Inspector

npx @modelcontextprotocol/inspector python todo_server.py

기능:

  • Tool/Resource 목록 확인
  • 직접 호출 테스트
  • 응답 검증

9. 실무 팁

설명 명확히 작성

@mcp.tool()
def search_documents(query: str, limit: int = 10) -> str:
    """검색어로 문서를 검색한다

    문서 찾기 요청 시 사용
    """

에러 처리

try:
    ...
except Exception as e:
    return json.dumps({"error": str(e)})

 

10. 활용 아이디어

서버용도

Jira MCP 이슈 관리
Slack MCP 메시지 전송
DB MCP 데이터 조회
배포 MCP 자동 배포

정리

  • FastMCP로 MCP 서버를 쉽게 만들 수 있다
  • @mcp.tool()로 실행 도구 정의
  • docstring이 AI 사용 판단의 핵심
  • Claude Code에 등록해서 바로 활용 가능
  • Inspector로 테스트 필수

관령 링크

참고 자료

반응형