local-docs-mcp
# local-docs-mcp
로컬 PC의 문서를 읽어 **요약과 정리를 돕는** 개인용 MCP 서버입니다.
PDF·Word·엑셀·파워포인트·한글·마크다운·CSV 등을 텍스트로 뽑아 주고, 요약본 저장과
파일 정리를 승인 절차와 함께 처리합니다.
- 네트워크를 쓰지 않습니다. API 키가 필요 없습니다.
- **요약은 이 서버가 하지 않습니다.** 원문을 정확히 뽑아 주면 요약은 Claude가 씁니다.
(서버가 주는 `machine_keypoints`는 빈도 기반 기계 추출이며 요약이 아닙니다.)
- 허용한 폴더 밖은 읽지 못합니다. 파일을 옮기거나 저장할 때는 반드시 승인을 거칩니다.
## 지원 형식
| 종류 | 확장자 | 방식 |
|---|---|---|
| 문서 | `.docx` `.docm` | ZIP+XML 직접 파싱 (제목·문단·표) |
| 한글 | `.hwpx` / `.hwp` | hwpx는 기본 지원, `.hwp`는 `olefile` 설치 시 최선 추출 |
| PDF | `.pdf` | `pypdf` (페이지별 `p.N` 라벨) |
| 발표 | `.pptx` `.pptm` | 슬라이드 번호 순 + 발표자 노트 |
| 표 | `.xlsx` `.xlsm` | 시트별, 공유문자열 해석 |
| 데이터 | `.csv` `.tsv` `.json` | 열 이름·행 수 포함 |
| 웹·메일 | `.html` `.htm` `.xml` `.eml` | 태그 제거, 메일은 헤더+본문 |
| 텍스트·코드 | `.md` `.txt` `.log` `.yaml` `.py` `.js` 등 | UTF-8/CP949/EUC-KR 자동 판별 |
`.doc` `.xls` `.ppt`(옛 이진 형식)는 읽지 않고 "`x` 붙은 형식으로 저장하라"고 안내합니다.
## 설치
Python 3.11 이상이 필요합니다.
```bash
python -m venv .venv && .venv/Scripts/pip install -e ".[formats,dev]"
```
macOS · Linux는 `.venv/bin/pip`을 씁니다. `[formats]`는 PDF용 `pypdf`와
`.hwp`(이진)용 `olefile`을 함께 설치하며, 없어도 나머지 형식은 동작합니다.
## Claude Code에 등록
`<PROJECT_DIR>`는 이 저장소를 클론한 절대 경로, `<HOME>`은 사용자 홈 폴더입니다.
```bash
claude mcp add local-docs --scope user --env DOCS_MCP_ROOTS="<HOME>/Desktop;<HOME>/Documents" --env DOCS_MCP_OUTPUT="<HOME>/Desktop/docs-mcp-out" -- <PROJECT_DIR>/.venv/Scripts/python.exe -m docs_mcp.server
```
이 저장소 안에서만 쓰려면 [.mcp.json.example](.mcp.json.example)을 `.mcp.json`으로
복사한 뒤 `<PROJECT_DIR>`와 `<HOME>`을 실제 경로로 바꾸세요. `.mcp.json`은 머신마다
경로가 달라 저장소에 추적하지 않습니다.
### 환경 변수
| 변수 | 뜻 | 기본값 |
|---|---|---|
| `DOCS_MCP_ROOTS` | 읽기를 허용할 폴더 목록(`;`로 구분) | 바탕화면·문서·다운로드 |
| `DOCS_MCP_OUTPUT` | 요약본과 정리 기록을 쓸 폴더 | `<HOME>/Desktop/docs-mcp-out` |
| `DOCS_MCP_MAX_FILE_MB` | 한 파일 최대 크기 | `20` |
| `DOCS_MCP_ALLOW_MOVE` | `1`이면 정리 시 원본 이동 허용 | 미설정(복사만) |
## 도구 11개
읽기 전용(R)과 쓰기(W)를 구분해 등록하므로 호스트가 승인 UI를 다르게 띄웁니다.
| | 도구 | 하는 일 |
|---|---|---|
| R | `list_roots` | 읽을 수 있는 폴더·지원 형식·한도 확인 |
| R | `scan_documents` | 폴더를 훑어 문서 목록(종류·크기·수정일) |
| R | `outline_document` | 구조·제목·키워드·대표 문장. 전문을 읽기 전 판단용 |
| R | `read_document` | 본문 추출. 구역 라벨과 이어 읽기 커서 제공 |
| R | `search_documents` | 여러 문서 본문 검색 + 근거 스니펫 |
| R | `build_summary_bundle` | 여러 문서를 글자 예산 안에서 고르게 발췌 |
| R | `preview_save_summary` | 저장할 내용·경로 미리보기 + 승인 토큰 발급 |
| W | `save_summary` | 승인된 요약을 출력 폴더에 저장 |
| R | `preview_organize` | 정리 계획만 생성(파일 무변경) + 승인 토큰 |
| W | `apply_organize` | 승인된 계획 실행(기본 복사) |
| W | `undo_last_organize` | 저널 기록만 보고 되돌리기 |
## 권장 흐름
```text
list_roots
→ scan_documents 어떤 문서가 있는지
→ outline_document 긴 문서는 뼈대부터
→ read_document 원문을 근거로 확보 (필요하면 이어 읽기)
→ (Claude가 요약 작성)
→ preview_save_summary 저장 내용 확인
→ [사용자 승인]
→ save_summary
```
정리는 따로 진행합니다.
```text
preview_organize 계획만 생성 — 파일은 하나도 건드리지 않음
→ [사용자가 계획 확인·승인]
→ apply_organize (기본 copy)
→ 문제가 있으면 undo_last_organize
```
정리 기준은 네 가지입니다.
| 기준 | 결과 폴더 |
|---|---|
| `by_kind` | `01_문서` `02_PDF` `03_발표자료` `04_표계산` … |
| `by_month` | `202608` 같은 수정 월 |
| `by_kind_month` | `02_PDF/202608` |
| `by_keyword` | 규칙에 지정한 이름. 예: `{"계약서": ["계약","contract"]}` |
## 안전 장치
1. **경로 봉쇄** — 모든 입력 경로를 `resolve()`한 뒤 허용 루트 안인지 확인합니다.
`..`, 심볼릭 링크, 드라이브 이동 모두 여기서 막힙니다.
2. **쓰기 봉쇄** — 저장은 출력 폴더 안에서만 가능합니다. 읽기 루트에는 쓰지 않습니다.
3. **제외 폴더** — `.git` `node_modules` `.venv` `AppData` 등은 훑지도 읽지도 않습니다.
4. **승인 토큰** — 미리보기 내용의 해시입니다. 내용이 한 글자라도 달라지면 토큰이
깨져 저장·정리가 거부됩니다. 단, 토큰은 기술적 무결성만 보장하며 **사용자 승인을
대신하지 않습니다.**
5. **기본은 복사** — 원본 이동은 `DOCS_MCP_ALLOW_MOVE=1`이 있어야만 가능합니다.
6. **삭제하지 않음** — 되돌리기도 파일을 지우지 않고 `_trash` 폴더로 옮깁니다.
## 검증
```bash
.venv/Scripts/python.exe -m pytest -q
```
```bash
.venv/Scripts/python.exe scripts/smoke.py
```
```bash
.venv/Scripts/python.exe scripts/simulate.py
```
- `pytest` — 형식별 추출·경계 검사·승인 흐름 (단위)
- `smoke.py` — 실제 stdio로 `initialize → tools/list → tools/call` 확인
- `simulate.py` — **가상 문서 세트를 만들어 전체 흐름을 실제 MCP 연결로 재현**합니다.
회의록·계약서·견적·발표자료·PDF·CP949 메모 등 가상 문서 12개를 만들고,
훑기 → 요약 저장 → 정리 → 되돌리기까지 진행하며 막혀야 할 일(루트 밖 읽기,
토큰 위조, 원본 이동)이 실제로 막히는지 확인합니다. 임시 폴더에서 돌고 끝나면
스스로 지웁니다. 결과를 남겨 보려면 폴더를 인자로 넘기세요.
## 한계
- 스캔 이미지 PDF는 텍스트가 없습니다. OCR은 하지 않고 경고만 남깁니다.
- 엑셀 날짜 셀은 내부 일련번호로 보일 수 있습니다.
- `.hwp`(이진)는 최선 추출입니다. 표·각주 순서가 원문과 다를 수 있습니다.
- 이미지 안의 글자는 어떤 형식에서도 읽지 않습니다.
## 라이선스
MIT — [LICENSE](LICENSE)
TDQS
Scored across 11 tools
Each tool has a clearly distinct purpose: listing roots, scanning, outlining, reading, searching, bundling summaries, preview/save summaries, preview/apply organize, and undo. No two tools appear to overlap in functionality.
All tool names follow a consistent verb_noun pattern in snake_case (e.g., list_roots, scan_documents, preview_organize). Even compound verbs like preview_save_summary maintain the pattern.
11 tools is well-scoped for a local docs management server, covering read, search, summarize, save, and organize workflows without bloat. Each tool earns its place in the workflow.
The tool surface covers the full lifecycle for reading and managing documents: listing, scanning, outlining, reading, searching, bundling, saving summaries with preview, organizing with preview and apply, and undo for corrections. No obvious dead ends or missing operations for the stated purpose.