Skip to main content
Glama
saewookkangboy

file-analyzer-mcp

README.md
# file-analyzer-mcp

![Python](https://img.shields.io/badge/python-3.10%2B-blue)
![Protocol](https://img.shields.io/badge/protocol-MCP-6f42c1)
![Scope](https://img.shields.io/badge/scope-local%20only-lightgrey)
![Tests](https://img.shields.io/badge/tests-pytest-0a7c3f)

로컬 폴더의 PDF·DOCX·PPTX·SVG·PNG에서 **텍스트/구조만 추출**해 주는 개인용 stdio MCP
서버입니다. 요약·해석은 하지 않습니다 — 추출된 결과를 읽고 요약하는 건 이 도구를 호출하는
호스트 LLM(Claude Code 등)의 몫입니다.

## 하는 일 / 하지 않는 일

| 하는 일 | 하지 않는 일 |
|---|---|
| 지정 루트 폴더 하위 문서의 텍스트/구조 추출 | 요약·해석 (호스트 LLM이 담당) |
| 폴더 트리 · 확장자별 파일 수/용량 집계 | 파일 쓰기·삭제·이동 (읽기 전용) |
| PNG의 OCR 텍스트 추출 | 이미지의 시각적 의미(그림·차트) 파악 |
| 대용량/손상 파일에 대한 타임아웃 처리 | 서버 실행 중 분석 대상 폴더 변경 |

## 실행 예시

```text
> read_document("quarterly-report.pdf")
{
  "type": "pdf",
  "num_pages": 12,
  "text": "Q3 Revenue Summary\n..."
}

> read_document("../../etc/passwd")
{ "error": "'../../etc/passwd' resolves outside the allowed root folder" }
```

## 빠른 시작

```bash
git clone https://github.com/saewookkangboy/fileanalyzer_mcp_testmonial.git
cd fileanalyzer_mcp_testmonial
python3 -m venv .venv && source .venv/bin/activate
pip install -e .
brew install tesseract   # PNG OCR용 (한국어는 brew install tesseract-lang 추가)
```

Claude Code에 등록:

```bash
claude mcp add file-analyzer --env FILE_ANALYZER_ROOT=/분석할/폴더 -- \
  "$(pwd)/.venv/bin/python" "$(pwd)/server.py"
claude mcp list   # ✔ Connected 확인
```

등록 후 새 세션에서 "이 폴더 문서들 요약해줘"라고 요청하면 아래 3개 도구를 Claude가
직접 호출합니다.

## 도구 (Tools)

| 도구 | 설명 |
|---|---|
| `list_directory(subpath=".", recursive=True)` | 폴더 트리, 확장자별 파일 수/용량 |
| `read_document(relative_path)` | 텍스트/구조 추출 — `.pdf` `.docx` `.pptx` `.svg` `.png` |
| `get_file_metadata(relative_path)` | 크기, 수정시각, 페이지/슬라이드 수, 이미지 해상도 등 |

## 프로젝트 구조

```
server.py                    # FastMCP 앱 진입점, 툴 등록, 루트 폴더 검증
file_analyzer/
  security.py                #  경로 격리(resolve_safe_path), 크기 제한
  timeout.py                 #  추출 작업 하드 타임아웃
  audit.py                   #  로컬 감사 로그(logs/audit.jsonl)
  tree.py, metadata.py       #  list_directory / get_file_metadata 로직
  extractors/                #  pdf · docx · pptx · svg · image(OCR) 추출기
tests/                       # pytest 회귀 스위트
AGENTS.md                    # 호출 에이전트(Claude Code)를 위한 운영 지침
```

## 보안 & 제약

| 항목 | 정책 |
|---|---|
| 경로 격리 | `FILE_ANALYZER_ROOT` 하위만 접근 가능 — `../`, 절대경로 주입, symlink 이탈 전부 차단 |
| 파일 크기 | 50MB 초과 시 읽지 않고 에러 반환 |
| 타임아웃 | 추출/메타데이터 파싱이 30초를 넘으면 에러로 중단 반환 |
| 지원 확장자 | `.pdf` `.docx` `.pptx` `.svg` `.png` — `.ppt`(구형 포맷), `.jpg` 등은 미지원 |
| 이미지 해석 | OCR 텍스트만 추출, 그림/차트의 시각적 의미는 파악하지 못함 |
| 분석 대상 폴더 | 서버 시작 시 1회 고정, 실행 중 변경 불가 |

## 관찰성 — 감사 로그

모든 도구 호출은 `logs/audit.jsonl`에 로컬로만 한 줄씩 기록됩니다(외부 전송 없음).

```json
{"timestamp": "2026-08-26T06:03:35Z", "tool": "read_document", "params": {"relative_path": "report.pdf"}, "status": "ok", "duration_ms": 251.3}
```

로그를 비우려면 `logs/audit.jsonl`을 삭제하면 됩니다.

## 개발

```bash
pip install -e ".[dev]"
pytest -q
```

`tests/`는 경로 이탈·절대경로 주입 차단, 5종 추출기, 타임아웃, 감사 로그, 서버 통합을
다룹니다. 이 프로젝트 규모에서는 CI 파이프라인 없이 로컬 `pytest` 실행만으로 회귀 검증이
충분하다고 보고 그렇게 유지했습니다.

## 왜 이렇게 설계했나

- **요약 기능이 없음** — 별도 LLM API 키 없이도 동작하도록, 추출은 서버가/요약은 호스트가
  나눠 맡는 최소 구조를 택했습니다.
- **PNG는 OCR, vision 전달 아님** — 호스트에 이미지를 base64로 넘기는 대신 텍스트만 뽑아
  반환량과 구현 복잡도를 낮췄습니다 (그림의 시각적 의미는 못 봄).
- **git/CI 없이 로컬 pytest만** — 1인 로컬 도구 규모에서 CI 인프라는 과하다고 판단했습니다.

## 알려진 한계

- 타임아웃은 스레드 기반이라, 초과된 호출 자체의 백그라운드 스레드는 반환 이후에도 끝까지
  실행될 수 있습니다.
- `.ppt`는 지원하지 않습니다 — `.pptx`로 변환 후 사용하세요.

## 라이선스

별도 라이선스 파일이 없는 개인 프로젝트입니다.