my_mcp_server

namekun/my_mcp_server

3.1

If you are the rightful owner of my_mcp_server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.

This is a personal study example of an MCP server providing multiple tools from a single server.

Tools
3
Resources
0
Prompts
0

MY MCP Server

여러 개의 MCP 도구를 한 서버에서 제공하는 개인 스터디용 예제입니다.

주요 기능:

  • summarize_youtube: YouTube 자막을 가져와 요약 반환
  • transcript_stats: 자막의 통계(세그먼트 수, 길이 등) 반환
  • ping: 서버 헬스체크

MCP(Model Context Protocol) SDK: mcp (Anthropic)
Transcript: youtube-transcript-api


디렉터리 구조

.
├─ server.py                  # 얇은 엔트리포인트
├─ mcp_server/
│  ├─ __init__.py
│  ├─ core.py                 # MCP 서버 생성/핸들러 + 레지스트리 연동
│  ├─ registry.py             # ToolRegistry (툴 스펙/핸들러 등록/라우팅)
│  ├─ utils/
│  │  ├─ __init__.py
│  │  ├─ youtube.py           # 자막 fetch + dict/객체 호환 + ID 추출
│  │  └─ text.py              # 요약 등 텍스트 유틸
│  └─ tools/
│     ├─ __init__.py          # ALL = [각 툴 모듈]
│     ├─ summarize_youtube.py # 요약 툴
│     ├─ transcript_stats.py  # 통계 툴
│     └─ ping.py              # 핑(헬스체크)

요구사항

  • Python 3.10+
  • mcp (예: pip install mcp)
  • youtube-transcript-api

버전 확인:

pip show mcp
pip show youtube-transcript-api

설치 & 실행

# 1) (선택) 가상환경
python -m venv .venv
source .venv/bin/activate  # Windows: .venv\Scripts\activate

# 2) 의존성 설치
pip install mcp youtube-transcript-api

# 3) 실행 (로그 레벨 조정 가능)
LOG_LEVEL=DEBUG python server.py

이 서버는 stdio 기반 MCP 서버입니다. MCP 클라이언트(예: IDE 플러그인, MCP 호환 앱)에서 stdio 서버로 등록해 호출합니다.


제공 도구(툴)

1) summarize_youtube

  • 설명: YouTube 자막을 가져와 요약을 반환
  • 입력(JSON Schema):
    {
      "type": "object",
      "properties": {
        "url": { "type": "string", "description": "YouTube 비디오 URL" },
        "language": { "type": "string", "description": "자막 언어 코드(ko, en, ja 등)" }
      },
      "required": ["url"]
    }
    
  • 출력: TextContent (요약 및 기본 정보)

2) transcript_stats

  • 설명: 자막 통계(세그먼트 수, 길이 등)만 반환
  • 입력(JSON Schema):
    {
      "type": "object",
      "properties": {
        "url": { "type": "string" },
        "language": { "type": "string" }
      },
      "required": ["url"]
    }
    
  • 출력: TextContent

3) ping

  • 설명: 서버 헬스체크
  • 입력: 없음

4) commit_suggester

  • 설명: Git 변경 내용을 읽어 현재 브랜치와 변경 파일을 기반으로 Conventional Commits 스타일 또는 사용자 정의 포맷에 맞는 커밋 메시지 후보를 생성합니다. 브랜치 이름이 feature/xxx이면 type을 feat으로, scope을 xxx으로 자동 추정합니다. 사용자가 path를 주면 그 경로의 Git 리포지터리를 대상으로 합니다.

  • 입력 주요 필드 예시:

    {
      "mode": "staged",                    # staged, working, range
      "range": "HEAD~3..HEAD",             # mode=range일 때
      "format": "{emoji} {type}({scope}): {subject}",  # 사용자 정의 템플릿
      "rules": {
        "types": ["feat","fix"],
        "require_scope": true,
        "subject_max": 50
      },
      "language": "ko",
      "suggestions": 3,
      "breaking": false,
      "debug": true,
      "path": "./"                         # 특정 하위 디렉토리 리포지터리 지정
    }
    
  • 기능 요약:

    • 변경 파일/스테이징 상태 수집 (mode)
    • 타입/스코프 추정: 파일명 + 브랜치명 기반 자동 보정
    • 커밋 메시지 포맷: Conventional Commits 기본 또는 사용자 정의 템플릿 지원
    • 경로 지정: path로 특정 서브디렉토리의 Git 리포지터리 사용
    • 디버그 모드: 내부 결정 과정 로그 포함
    • BREAKING CHANGE 포함 옵션
  • 예시 사용:

    • 스테이징된 변경으로 한국어 Conventional Commit 메시지 2개 제안:
      {"mode":"staged","language":"ko","suggestions":2}
      
    • feature/user-auth 브랜치에서 scope을 자동으로 user-auth로 잡고 메시지 생성:
      {"mode":"staged","language":"en","rules":{"require_scope":true},"suggestions":1}
      
    • 하위 폴더 subproject/ 리포지터리 기준으로 emoji 포함 포맷:
      {
        "mode":"working",
        "format":"{emoji} {type}({scope}): {subject}",
        "allow_emoji": true,
        "path":"subproject/"
      }
      
  • 팁:

    • format 템플릿에 들어가는 변수: {type}, {scope}, {subject}, {emoji}, {branch}, {files_changed}, {body} 등.
    • rules.subject_max을 줄이면 제목 길이를 제한할 수 있음.
    • require_scope을 켜면 scope이 없을 땐 기본 core가 들어감.

로깅

  • 전역 로그 레벨은 환경변수 LOG_LEVEL 로 제어합니다. (DEBUG / INFO / WARNING / ERROR)
  • 주요 로거
    • mcp.entry : 진입점(server.py)
    • mcp.core : MCP 서버 시작/중지, call_tool 라우팅/에러
    • mcp.utils.youtube : 자막 fetch 단계 로깅

예:

LOG_LEVEL=DEBUG python server.py

개발 팁

  • 툴 추가 방법

    1. mcp_server/tools/your_tool.py 생성
    2. tool_spec (mcp.types.Tool), async def handle(arguments) 구현
    3. mcp_server/tools/__init__.pyALL 목록에 모듈을 추가
  • YouTube 자막 주의

    • youtube-transcript-api 버전에 따라 각 세그먼트가 dict 또는 FetchedTranscriptSnippet(객체) 일 수 있습니다.
      본 프로젝트는 공통 접근 헬퍼로 두 형태 모두 지원합니다.

Claude(클로드) 데스크톱에 등록하기

Claude Desktop에서 이 MCP 서버를 사용하려면 데스크톱 설정 파일에 MCP 서버를 등록해야 합니다.

1) 설정 파일 위치

운영체제별 기본 경로는 다음 중 하나입니다.

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json

파일이 없다면 직접 생성해도 됩니다. JSON 포맷을 반드시 지켜주세요.

2) 로컬 파이썬 프로세스로 등록 (권장: 개발용)

서버를 로컬에서 직접 실행하는 방식입니다. cwd를 프로젝트 루트로 맞춰주세요.

{
  // 기존 설정이 있다면 병합하세요
  "mcpServers": {
    "my-mcp-server": {
      "command": "python3",
      "args": ["server.py"],
      "cwd": "/Users/user/Desktop/DEV/my_mcp_server",
      "env": {
        "LOG_LEVEL": "INFO"
      }
    }
  }
}
  • commandpython 또는 python3를 사용하세요(환경에 맞게).
  • 가상환경을 쓰는 경우 command에 가상환경의 파이썬 경로를 지정해도 됩니다. (예: "/Users/user/Desktop/DEV/my_mcp_server/.venv/bin/python")

3) Docker 컨테이너로 등록 (배포/격리 실행)

이미지를 빌드한 뒤, Claude가 컨테이너를 STDIN/STDOUT로 구동하도록 설정합니다.

{
  "mcpServers": {
    "my-mcp-server-docker": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i",
        "-e", "LOG_LEVEL=INFO",
        "my-mcp-server:latest"
      ]
    }
  }
}

-i 옵션이 중요합니다(표준입력을 열어 MCP가 통신할 수 있게 함). 필요 시 --pull=always를 추가해 최신 이미지를 받도록 할 수 있습니다.

4) 적용 방법

  1. claude_desktop_config.json 수정/저장
  2. Claude Desktop을 재시작
  3. Claude 대화창에서 @ 또는 사이드패널의 MCP 섹션에서 my-mcp-server(또는 설정한 이름)를 확인 후 사용

등록 명은 자유롭게 정해도 되지만, README의 예시와 동일하게 쓰면 문서와 일치해 편합니다.

트러블슈팅

  • 'FetchedTranscriptSnippet' object is not subscriptable

    • 원인: 세그먼트가 dict가 아닐 때 entry['text']로 접근
    • 해결: 공통 헬퍼를 통해 getattr/dict.get 모두 대응 (이미 반영됨)
  • Server.list_tools() takes 1 positional argument but 2 were given

    • 원인: MCP 저수준 Server의 데코레이터는 팩토리 함수이므로 괄호 필요/불필요 혼동
    • 해결: 현재 코드는 @self.server.list_tools() / @self.server.call_tool() 형태로 정상 동작하도록 구성
  • 자막이 없는 영상 / 지역 제한 / 비공개

    • “사용 가능한 자막을 찾을 수 없습니다” 메시지를 반환합니다. 다른 영상 또는 언어코드로 재시도하세요.

라이선스

MIT (각 라이브러리의 라이선스는 해당 저장소 참고)