Skip to main content
Glama

doc-agent-mcp

CI PyPI Python License: MIT

문서에 대해 안정적이고 의미론적인 작업을 AI 에이전트에게 제공하는 Model Context Protocol 서버 — 원시 텍스트를 뒤적이는 대신에.

Human ─────┐
           ↓
        Document          ← Markdown (.md/.markdown) and DOCX today,
           ↑                 Tiptap / SuperDoc / Shimo / Google Docs tomorrow
AI Agent ──┘

LLM 에이전트가 문서를 하나의 큰 문자열로 편집하면 문제가 생깁니다: 보이지 않는 서식을 망가뜨리고, 이미지와 주석을 잃어버리며, "3절 뒤에 문단 삽입" 같은 요청을 표현할 수 없습니다. doc-agent-mcp는 문서를 정규화되고 주소 지정 가능한 구조(제목, 문단, 목록 항목, 안정적인 ID를 가진 표)로 노출하고, 에이전트가 안전한 루프에서 작업할 수 있게 합니다:

read  →  propose change  →  inspect diff  →  apply  →  export

apply_changes가 호출되기 전에는 파일이 전혀 변경되지 않습니다. 모든 읽기는 doc_hash를 받아들이므로, 작업 중에 파일이 변경되면 이후 편집은 파일을 손상시키는 대신 stale_document 오류로 명확히 실패합니다.


이 문제가 해결하는 것

원시 텍스트 편집 (오늘날의 일반적인 방식)

doc-agent-mcp

에이전트가 한 단어를 바꾸기 위해 전체 파일을 다시 씀

에이전트가 한 블록 내의 정확한 문자 범위를 교체함

DOCX가 텍스트 변환기를 거치면서 스타일/주석이 파괴됨

편집은 원본 OOXML 패키지 내부에서 적용됨; 건드리지 않은 내용은 그대로 통과함

변경 전에 무엇이 바뀔지 검토할 방법이 없음

모든 편집은 통합 diff로 스테이징됨; 적용은 명시적임

사람이 동시에 편집할 때 조용한 충돌 발생

콘텐츠 해시 낙관적 잠금; 오래된 편집은 거부됨

형식별 해킹이 프롬프트에 하드코딩됨

하나의 도구 표면, 모든 백엔드

Related MCP server: docx-mcp-server

아키텍처

MCP interface (13 tools)
        ↓
Document operation layer      ← staging, diffs, hashes, search, sessions
        ↓                          (doc_agent_mcp/service.py)
Normalized document model     ← Block(h-0, p-1, li-2, tbl-0), Comment,
        ↓                          ProposedChange   (core/model.py)
Backend adapters              ← parse() + serialize() per format
        ↓                          (adapters/*_adapter.py)
Markdown · DOCX · future editors (Tiptap, SuperDoc, Shimo, Google Docs)

핵심 속성: MCP 도구는 아래에 어떤 백엔드가 있는지 전혀 알지 못합니다. 새 편집기 백엔드를 추가하려면 두 메서드를 구현하면 됩니다 — ADAPTER_GUIDE.md 참조.

설치

PyPI에서 (사용자에게 권장):

pip install doc-agent-mcp

Python 3.10+ 필요.

소스에서 (개발):

git clone https://github.com/xyyyang97/doc-agent-mcp.git
cd doc-agent-mcp

python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"

확인:

doc-agent-mcp --version
# doc-agent-mcp 0.1.0

MCP 구성

서버는 stdio를 통해 표준 MCP를 사용합니다.

Claude Desktop

claude_desktop_config.json:

{
  "mcpServers": {
    "doc-agent": {
      "command": "/absolute/path/to/doc-agent-mcp/.venv/bin/doc-agent-mcp",
      "args": ["--roots", "/Users/you/Documents"]
    }
  }
}

Claude Code / Codex CLI

claude mcp add doc-agent -- /absolute/path/to/doc-agent-mcp/.venv/bin/doc-agent-mcp --roots ~/Documents

일반 MCP 클라이언트 (JSON)

{
  "mcpServers": {
    "doc-agent": {
      "command": "/absolute/path/to/doc-agent-mcp/.venv/bin/doc-agent-mcp",
      "args": [],
      "env": {}
    }
  }
}

--roots DIR [DIR ...]는 모든 읽기/쓰기를 해당 디렉토리로 제한합니다 (권장). 이 옵션이 없으면 서버는 프로세스가 도달할 수 있는 모든 경로에 접근할 수 있습니다 — 서버 구성을 파일 시스템 자격 증명처럼 취급하세요.

사용 가능한 도구

읽기 작업 (변경 없음)

도구

목적

read_document(path, section_id?, include_spans?, doc_hash?)

ID가 있는 구조화된 블록; 선택적 단일 섹션 보기; unmodeled_features 보고

get_outline(path, doc_hash?)

제목 평면 + 경로가 있는 중첩 트리

find_text(path, query, scope_element_id?, is_regex?, case_sensitive?, doc_hash?)

(element_id, start, end) 오프셋이 있는 정확한 발생 위치 — propose_replace_text에 바로 사용 가능; 표 히트는 editable: false로 표시됨

get_comments(path, doc_hash?)

기본 주석 (작성자, 본문, 앵커 요소, 인용 범위)

제안 작업 (변경 스테이징; 아직 아무것도 쓰지 않음)

도구

목적

propose_replace_text(path, element_id, start, end, text)

한 블록 내의 문자 범위 교체; diff 미리보기 반환

propose_insert_block(path, anchor_id, position, kind, text, level?)

문단/제목/목록 항목을 임의 요소 앞이나 뒤에 삽입 (앞/뒤/추가 삽입 포함)

propose_delete_block(path, element_id)

전체 블록 하나 삭제

propose_add_comment(path, anchor_id, body, quote?, author?)

기본 Word 주석 (DOCX); Markdown에서는 세션 전용 (제한 사항 참조)

커밋 및 검토

도구

목적

get_changes(path)

통합 diff가 있는 모든 스테이징된 변경

discard_changes(path, change_ids?)

스테이징된 변경 삭제 (전체 또는 선택)

apply_changes(path, change_ids?, doc_hash?)

원자적으로 디스크에 쓰기; 새 doc_hash + 경고 반환

export_document(path, target_format, output_path?, title?)

모델을 통해 변환: md↔docx 양방향

list_backends()

등록된 백엔드 및 지원되는 변환

모든 변경/읽기 호출은 이전 호출에서 얻은 doc_hash를 받아들입니다. 파일이 그 이후에 변경된 경우 (다른 프로세스에 의한 변경 포함), {"code": "stale_document", ...}를 받고 스테이징된 변경은 삭제됩니다 — 먼저 다시 읽으세요.

예제 워크플로

이것은 examples/demo_workflow.py가 실행하는 정확한 루프입니다 (실제 파일 대상):

from doc_agent_mcp.service import DocumentService

svc = DocumentService()                      # same facade the MCP tools wrap

# 1. Understand the document
outline = svc.get_outline("brief.md")
summary = next(h for h in outline["headings"] if h["title"] == "Executive Summary")
section = svc.read_document("brief.md", section_id=summary["id"])

# 2. Locate exact text
hit = svc.find_text("brief.md", "30 percent")["matches"][0]

# 3. Stage a change (file is untouched)
proposal = svc.propose_replace_text(
    "brief.md", hit["element_id"], hit["start"], hit["end"],
    "at least 30 percent (validated with finance)",
)

# 4. Review the diff
changes = svc.get_changes("brief.md")
print(changes["changes"][0]["diff"])

# 5. Commit, then export
svc.apply_changes("brief.md", doc_hash=proposal["doc_hash"])
svc.export_document("brief.md", "docx", output_path="brief.docx")

MCP를 통해서는 동일한 단계가 각각 하나의 도구 호출입니다 — 위 도구 표를 참조하세요.

전체 데모 실행 (Markdown + DOCX + 내보내기 + stale-guard, 모두 검증됨):

.venv/bin/python examples/demo_workflow.py

샘플 문서는 examples/documents/에 있습니다: sample.mdsample.docx (후자는 두 개의 기본 Word 주석 포함, scripts/make_sample_docx.py로 재생성 가능).

오류 처리

모든 오류는 구조화된 JSON입니다 — 와이어를 통한 traceback 없음:

{
  "code": "element_not_found",
  "message": "Element 'p-99' not found. Call get_outline ...",
  "details": {"element_id": "p-99"}
}

코드

의미

document_not_found

경로가 존재하지 않음

unsupported_format

이 확장자에 대한 백엔드 없음

element_not_found

오래되었거나 알 수 없는 요소 ID

match_not_found / ambiguous_match

검색 결과 없음 / 명확화를 위해 예약됨

validation_error

잘못된 범위, 잘못된 인용 앵커, 표 셀 교체, 루트 외부 경로...

stale_document

스냅샷 이후 파일 변경됨; 스테이징된 변경은 삭제됨

change_not_found

알 수 없거나 이미 삭제된 change_id

export_error

지원되지 않는 변환 쌍

테스트

.venv/bin/pip install -e ".[dev]"
.venv/bin/pytest                 # unit + integration + MCP protocol tests
.venv/bin/ruff check src tests   # lint
.venv/bin/ruff format --check .  # formatting
.venv/bin/mypy                   # strict type checking

테스트 스위트에는 DOCX 왕복 테스트 (저장된 파일을 python-docx 및 원시 OOXML 수준에서 다시 열어 편집 검증)와 stdio를 통해 서버를 실행하고 실제 프로토콜 메시지를 주고받는 종단 간 MCP 테스트가 포함됩니다.

제한 사항 (우연이 아닌 설계에 의한)

정규화된 모델은 Markdown과 DOCX가 모두 안정적으로 표현할 수 있는 것을 다룹니다. 그 외의 모든 것은 명시적으로 unmodeled_features로 표시됩니다 — 조용히 파괴되지 않습니다:

  • DOCX: 이미지/그림, 머리글 및 바닥글, 각주/미주, 콘텐츠 컨트롤, 소스에 존재하는 변경 추적은 그대로 보존되지만 모델에는 보이지 않습니다. 표는 일반 텍스트 셀입니다 (셀 서식은 모델링되지 않음). replace_text는 하이퍼링크가 포함된 문단을 거부합니다 (재작성 시 하이퍼링크가 파괴되기 때문).

  • Markdown: 직렬화는 모델 충실형이지 바이트 충실형이 아닙니다 — 콘텐츠는 왕복을 견디지만 원래 줄 바꿈/마커 스타일은 유지되지 않을 수 있습니다. 인용구는 해당 문단으로 평탄화됩니다 (표시됨). 참조 스타일 링크 정의는 해석되어 인라인으로 변환됩니다. 주석은 기본 위치가 없습니다: propose_add_comment는 세션 전용으로 저장하며 그렇게 명시합니다.

  • : 검색 가능 ( editable: false로 표시) 하지만 셀 수준 편집은 아직 구현되지 않음 — 대신 삭제/재삽입하세요.

  • 동시 에이전트: 파일당 마지막 쓰기 승리, 해시 검사로 보호됨; 병합 엔진은 없습니다.

로드맵 아이디어

  • 표 셀 작업 (update_table_cell)

  • Tiptap/SuperDoc 어댑터 (JSON 모델 기반)

  • Drive API를 통한 Google Docs 어댑터 (주석이 기본적으로 매핑됨)

  • Markdown용 앵커 제안 모드 (<!-- suggestion --> 블록)

  • 다중 파일 워크스페이스 및 이름 변경 안전 세션

라이선스

MIT

A
license - permissive license
A
quality
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Persistent docs and memory for AI agents — read, write, organize & search a shared workspace.

  • MCP-native collaborative markdown editor with real-time AI document editing

  • AI document editing for agents: draft, edit, export .docx/PDF. 37 MCP tools; agent self-signup.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/xyyyang97/doc-agent-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server