doc-extract-mcp
以下摘录自该仓库的 README(片段) · 在 GitHub 读完整 README →
An MCP (Model Context Protocol) server that gives an LLM deterministic document
tooling for structured-data extraction workflows. The LLM does the reading and
extraction reasoning; this server provides the parts that should never be left
to a language model: reliable file access, parsing, chunking, JSON Schema
validation, and guarded file output.
Built by Koray Nar as a portfolio project for the AI document-automation
workflows he is building — the target use case is turning messy PDFs (purchase
orders, invoices, reports) into schema-validated JSON. Published as part of a
public portfolio. Pairs with Claude Code and Claude Desktop, and with any
other MCP client.
Why
An extraction agent fails in predictable places: it hallucinates file contents,
loses track of long documents, silently produces JSON that almost matches the
target schema, and writes output wherever it likes. This server removes those
failure modes:
- File access is confined to one allowed root (DOC_EXTRACT_ROOT).
- PDF text arrives with explicit --- page N --- markers, so citations of
"page 3" mean page 3.
- Long documents are chunked deterministically with overlap and page hints.
- Extracted JSON is checked against a JSON Schema (Draft 2020-12) and **every**
error is reported with a JSON Pointer path — not just the first — so the
model can fix all mistakes in one pass.
- Output is written by the server (JSON or CSV), inside the same root, with a
verifiable row/byte count.
Tools
| Tool | Arguments | What it does |
|---|---|---|
| list_documents | directory, glob_pattern='*' | List files under a directory inside the allowed root, with size and modified time. Supports recursive globs like **/*.pdf. Patterns must be relative and free of ..; matches resolving outside the root are dropped. |
| read_document | path, pages='' | Return a document's text. .pdf via pypdf with --- page N --- markers and optional 1-indexed page selection ('3', '1-5', '1-3,7'); .txt/.md/.json read directly; .csv rendered as an aligned text table. Clear error for unsupported types. |
| document_info | path | Metadata without full content: type, size, modified time; page count and PDF metadata for PDFs; line count for text files. |
| chunk_document | path, max_chars=4000, overlap=200 | Split a document into ordered overlapping chunks, each with an index, start offset, and (for PDFs) a page hint. |
| validate_json | data, json_schema | Validate a JSON string against a JSON Schema (Draft 2020-12). Returns every validation error with a JSON Pointer path via Draft202012Validator.iter_errors. |
| save_structured | path, data, format='json'\|'csv' | Write extracted data inside the allowed root. CSV expects a JSON array of flat objects. Returns written path, row count, and byte count. |
All path arguments are resolved and refused if they escape the allowed root
(path traversal guard). The glob_pattern argument is confined the same way:
absolute patterns and patterns containing .. are rejected, and any match
that resolves outside the root (for example through a symlink) is silently