Skip to main content
Glama
README.md
# VibeTutor MCP

> **내가 실제로 쓴 코드** 위에 학습 개념을 붙여 설명하는 AI 튜터 MCP 서버.
> 로컬 코드를 분석하여 일관된 양식의 **맞춤형 실습 교재(PDF/HTML/Markdown)**를 자동 생성하고 검색 가능한 개인 학습 자산으로 누적합니다.

---

## 목차

- [주요 기능](#주요-기능)
- [요구 사항](#요구-사항)
- [설치 방법](#설치-방법)
    - [로컬 설치 (uv)](#로컬-설치-uv)
    - [Docker 설치](#docker-설치)
- [Claude / MCP 클라이언트 연동](#claude--mcp-클라이언트-연동)
- [사용법](#사용법)
    - [MCP 도구 · 리소스](#mcp-도구--리소스)
    - [환경 변수](#환경-변수)
- [프로젝트 구조](#프로젝트-구조)
- [알려진 제약 사항](#알려진-제약-사항)
- [라이선스](#라이선스)

---

## 주요 기능

| 기능              | 설명                                                          |
|-----------------|-------------------------------------------------------------|
| **다중 포맷 출력**    | PDF(인쇄·배포용) · HTML(웹 열람용, 변환 비용 없음) · Markdown(원문 보존용) 중 선택 생성 |
| **맞춤형 교재 생성**   | 로컬 코드를 AST로 스캔하여 실제 코드 예제가 삽입된 교재를 생성                        |
| **표준 교재 양식 강제** | 마크다운 입력을 표준 양식으로 변환하여 누가/언제 만들어도 일관된 교재 출력                   |
| **한글 PDF 출력**   | Pretendard 폰트 임베딩으로 한글이 깨지지 않는 인쇄용 PDF                       |
| **학습 자산 인덱싱**   | SQLite에 교재 메타데이터를 누적, 제목 부분일치로 검색 가능                        |
| **재현성 보장**      | 콘텐츠 해시(SHA-256)로 동일 입력 → 동일 산출물 보장                          |
| **실패 진단**       | 각 처리 단계(스캔 → 렌더 → 변환 → 저장) 실패 시 단계·원인·힌트 제공                 |

---

## 요구 사항

| 항목                                            | 버전                         |
|-----------------------------------------------|----------------------------|
| Python                                        | 3.11 이상                    |
| [uv](https://docs.astral.sh/uv/)              | 최신 권장                      |
| [Docker](https://www.docker.com/get-started/) | Windows에서 PDF 생성 시 필수      |
| WeasyPrint 네이티브 의존성                           | Pango / cairo / GDK-PixBuf |

> **⚠️ Windows 로컬 환경:** WeasyPrint가 GTK 네이티브 라이브러리를 요구하므로
> PDF 변환은 **Docker**를 통해서만 가능합니다. 린트·타입검사·테스트는 로컬에서 실행 가능합니다.

---

## 설치 방법

### 로컬 설치 (uv)

1. 저장소 클론

```cmd
git clone https://github.com/PEANUTBUTTER1001/vibetutor-mcp.git
cd vibetutor-mcp
```

2. 의존성 설치 (.venv 자동 생성)

```
uv sync
```

### Docker 설치

모든 네이티브 의존성이 컨테이너에 포함되어 있어 OS에 상관없이 동일한 PDF를 생성합니다.

이미지 빌드

```cmd
docker build -t vibetutor-mcp .
```

한글 PDF 1장 생성 테스트 (output\ 폴더에 저장)

```
docker run --rm ^
  -e VIBETUTOR_PROJECT_ROOT=/app/src ^
  -v "%cd%\output":/app/output ^
  -v "%cd%\scripts":/app/scripts ^
  vibetutor-mcp /app/.venv/bin/python scripts/smoke_generate.py
```

---

## Claude / MCP 클라이언트 연동

VibeTutor MCP는 **stdio 전송**으로 동작합니다. Claude Desktop 또는 다른 MCP 클라이언트의 설정 파일에 아래 내용을 추가하세요.

### Claude Desktop (`claude_desktop_config.json`)

```json
{
  "mcpServers": {
    "vibetutor": {
      "command": "uv",
      "args": [
        "run",
        "--directory",
        "/절대경로/vibetutor-mcp",
        "vibetutor-mcp"
      ],
      "env": {
        "VIBETUTOR_PROJECT_ROOT": "/분석할-프로젝트-루트-경로"
      }
    }
  }
}
```

> `VIBETUTOR_PROJECT_ROOT`를 교재에 포함할 코드가 있는 프로젝트 루트로 지정하세요.
> 지정하지 않으면 vibetutor-mcp 패키지 디렉터리를 스캔합니다.

### Docker로 서버 실행 시

```json
{
  "mcpServers": {
    "vibetutor": {
      "command": "docker",
      "args": [
        "run",
        "--rm",
        "-i",
        "-v",
        "C:\\분석할\\프로젝트\\루트:/workspace",
        "-v",
        "C:\\원하는\\출력\\경로:/app/output",
        "-e",
        "VIBETUTOR_PROJECT_ROOT=/workspace",
        "vibetutor-mcp"
      ]
    }
  }
}
```

---

## 사용법

### MCP 도구 · 리소스

연동 후 Claude에서 아래 도구와 리소스를 사용할 수 있습니다.

#### Tool — `Generate book from markdown`

마크다운 텍스트를 입력받아 통 교재를 생성합니다. `output_format` 파라미터로 산출물 포맷을 선택하며,
생성된 교재는 `output/` 폴더에 저장되고 SQLite에 메타데이터가 기록됩니다.

**출력 포맷 (`output_format`)**

| 값                | 설명                                          | Docker 필요 여부 |
|-------------------|-----------------------------------------------|----------------|
| `pdf` (기본값)      | 인쇄·배포용 완성 교재. 한글 폰트 임베딩, 표지·콜로폰 포함           | 필요             |
| `html`            | 웹에서 바로 열어보는 교재. PDF와 동일 레이아웃, 변환 비용 없음       | 불필요            |
| `markdown`        | PDF 변환 전 단계의 원본 마크다운을 그대로 저장. 빠른 텍스트·토큰 절약  | 불필요            |

포맷을 명시하지 않고 "교재 만들어줘"라고만 요청하면, Claude가 임의로 기본값(PDF)을 선택하지 않고
먼저 어떤 포맷으로 만들지 되물어봅니다(예: "PDF, HTML, Markdown 중 어떤 형식으로 만들어 드릴까요?").
대답으로 포맷을 지정하면 그에 맞춰 이 도구가 호출됩니다.

**마크다운 작성 규칙**

챕터는 `# 01장. 챕터 제목` 형태로 시작하며, 각 챕터는 아래 11개 서브섹션으로 구성됩니다.

```
### 1. 들어가며
### 2. 학습 목표
### 3. 핵심 이론 비교표
### 4. 핵심 이론 설명
### 5. 핵심 코드 분석
### 6. 마주친 문제와 디버깅
### 7. 실무 연동 팁
### 8. 심화 학습
### 9. Q&A 표
### 10. 용어 사전
### 11. 공식 링크
```

**사용 예시:**

```
여기서 채팅한 내용을 토대로 HTML 교재로 만들어줘
```

**출력 예시 (포맷별):**

```
통교재 생성 완료(pdf) → output/프로젝트_기초.pdf (id=42, hash=a1b2c3d4)
통교재 생성 완료(html) → output/프로젝트_기초.html (id=43, hash=b2c3d4e5)
통교재 생성 완료(markdown) → output/프로젝트_기초.md (id=44, hash=c3d4e5f6)
```

---

#### Tool — `Search material`

생성된 교재를 제목 키워드로 검색합니다.

**사용 예시:**

```
제목이 파이썬이 들어간 파일목록 보여줘 
```

---

#### Resource — `vibetutor://materials`

저장된 모든 교재의 메타데이터 목록(JSON 배열)을 반환합니다.

#### Resource — `vibetutor://materials/{material_id}`

특정 교재의 상세 정보(JSON)를 반환합니다. 존재하지 않으면 `{}`를 반환합니다.

---

### 환경 변수

모든 경로 설정은 환경변수로 오버라이드할 수 있습니다. `.env` 파일도 지원합니다.

| 변수                       | 기본값                               | 설명                    |
|--------------------------|-----------------------------------|-----------------------|
| `VIBETUTOR_PROJECT_ROOT` | 패키지 루트                            | 코드 스캔 대상 프로젝트 경로      |
| `VIBETUTOR_OUTPUT_DIR`   | `<root>/output`                   | PDF 및 DB 저장 디렉터리      |
| `VIBETUTOR_TEMPLATE_DIR` | `<root>/templates`                | Jinja2 교재 템플릿 디렉터리    |
| `VIBETUTOR_FONT_DIR`     | `<root>/templates/fonts`          | WeasyPrint 한글 폰트 디렉터리 |
| `VIBETUTOR_DB_PATH`      | `<root>/output/vibetutor.sqlite3` | SQLite DB 파일 경로       |

---

## 프로젝트 구조

```
vibetutor-mcp/
├── src/vibetutor_mcp/
│   ├── main.py                  # FastMCP 서버 엔트리포인트 (Composition Root)
│   ├── core/
│   │   ├── config.py            # 환경변수 기반 설정 (VIBETUTOR_*)
│   │   ├── exceptions.py        # 도메인 예외 (PipelineError 등)
│   │   └── security.py          # 경로 안전 검증 · 민감 파일 차단
│   ├── domain/material/         # 순수 Python 도메인 (프레임워크 의존 없음)
│   │   ├── model.py             # StudySection · MaterialRequest · StudyMaterial
│   │   ├── ports.py             # 인터페이스 (PracticalMaterialRenderer / MaterialExporter / Clock)
│   │   ├── repository.py        # Repository 인터페이스
│   │   ├── usecase.py           # GenerateTutorMaterialUseCase
│   │   ├── query.py             # Search · List · Get UseCase
│   │   └── hashing.py           # SHA-256 콘텐츠 해시
│   ├── data/material/           # 인터페이스 구현체
│   │   ├── renderer.py          # JinjaMaterialRenderer
│   │   ├── markdown_parser.py   # 마크다운 → PracticalMaterialRequest 파서
│   │   ├── exporter.py          # FormatRouterExporter (PDF/HTML/Markdown 라우팅)
│   │   ├── repository_impl.py   # SqliteMaterialRepository
│   │   └── db.py                # SQLAlchemy 엔티티
│   └── presentation/
│       ├── prompts/template.py  # @mcp.prompt study_material_template
│       ├── tools/               # @mcp.tool (generate · search · markdown)
│       └── resources/           # @mcp.resource vibetutor://materials
├── templates/
│   ├── practical_material.html.j2  # 10단계 실전 교재 Jinja2 템플릿
│   ├── styles/                  # tokens.css · components.css
│   └── fonts/                   # Pretendard TTF/OTF (SIL OFL 1.1)
├── tests/
│   ├── test_scaffolding.py      # 아키텍처 규칙 검증
│   ├── test_pipeline.py         # 단위 · 통합 테스트
│   ├── test_e2e.py              # 전구간 E2E + 재현성
│   ├── test_export_formats.py   # 포맷별(PDF/HTML/Markdown) 내보내기 테스트
│   ├── test_practical.py        # 10단계 실전 교재 파이프라인 테스트
│   ├── test_search_material.py  # 검색 테스트
│   └── test_resources.py        # Resource 테스트
├── scripts/
│   ├── smoke_generate.py        # MCP 없이 PDF 1장 실생성 확인 스크립트
│   └── smoke_practical.py       # 실전 교재 생성 확인 스크립트
├── Dockerfile
└── pyproject.toml
```

**아키텍처:** Clean Architecture — `Presentation → Domain ← Data`


## 알려진 제약 사항

- **Windows 로컬에서 PDF 변환 불가:** VibeTutor는 PDF 생성을 위해 WeasyPrint를 사용하는데, Dockerfile에는 이 의존성이 미리 설치되어 있으므로, Windows 사용자는 PDF 생성 시 Docker를 사용하세요.
- **검색 범위:** 현재 제목 LIKE 부분일치만 지원합니다.

---

## 라이선스

이 프로젝트의 소스 코드는 **MIT License**를 따릅니다. 자세한 내용은 [`LICENSE`](LICENSE)를 참고하세요.

### 서드파티 폰트

`templates/fonts/`의 Pretendard 글꼴은 **SIL Open Font License 1.1**로 배포되며, PDF 교재의 한글 임베딩 폰트로 동봉됩니다.

- Pretendard © 2021 Kil Hyung-jin — <https://github.com/orioncactus/pretendard>
- 라이선스 전문: `templates/fonts/LICENSE.txt`

TDQS

A3.8/5.0

Scored across 2 tools

Disambiguation5/5

Both tools have entirely distinct purposes: one generates a book from markdown, the other searches materials. There is no overlap or ambiguity between them.

Naming Consistency5/5

Both tool names follow a consistent verb_noun (or verb_noun_preposition) pattern using snake_case, making them predictable and readable.

Tool Count2/5

With only 2 tools, the server feels under-scoped for a tutor. Expected tools like listing books, deleting, or retrieving specific books are missing, making the surface thin.

Completeness2/5

The tool set covers generation and search but lacks basic CRUD operations like listing, updating, or deleting materials. Important operations for managing a book collection are absent.

Maintenance

ActivityStale
ResponsivenessUnresponsive