Skip to main content
Glama
samsung10-gif

local-docs-mcp

README.md
# 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

A4.1/5.0

Scored across 11 tools

Disambiguation5/5

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.

Naming Consistency5/5

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.

Tool Count5/5

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.

Completeness5/5

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.

Maintenance

ActivityMaintained
ResponsivenessNo issues