Skip to main content

Docfold

PyPI version Python 3.10+ License: MIT CI Tests

Turn any document into structured data. Unified Python toolkit for document structuring — one interface, 20+ engines, built-in benchmarks, CLI, and an MCP server for AI agents.

Docfold is the open-source extraction engine from Datatera.ai — extracted from our commercial enterprise AI data platform and battle-tested in production with enterprise clients across finance, insurance, and mining.

Read the announcement: Docfold - open-source document processing toolkit

Engine Comparison

Research-based estimates from public benchmarks, documentation, and community reports. See detailed methodology. Run your own: docfold compare your_doc.pdf

Engine docfold Type License Text PDF Scan/OCR Tables BBox Conf Speed Cost
Docling ✅ Local MIT ★★★ ★★☆ ★★★ ✅ — Medium Free
MinerU ✅ Local AGPL ★★★ ★★★ ★★★ — — Slow Free
Marker ✅ SaaS Paid ★★★ ★★★ ★★★ ✅ — Fast $$
PyMuPDF ✅ Local AGPL ★★★ ☆☆☆ ★☆☆ — — Ultra Free
OpenDataLoader ✅ Local Apache ★★★ ☆☆☆ ★★☆ ✅ — Fast Free
PaddleOCR ✅ Local Apache ★☆☆ ★★★ ★★☆ — ✅ Medium Free
Tesseract ✅ Local Apache ★☆☆ ★★☆ ★☆☆ — — Medium Free
EasyOCR ✅ Local Apache ★☆☆ ★★★ ☆☆☆ — ✅ Medium Free
Unstructured ✅ Local Apache ★★☆ ★★☆ ★★☆ — — Medium Free
LlamaParse ✅ SaaS Paid ★★★ ★★★ ★★★ — — Fast $$
Mistral OCR ✅ SaaS Paid ★★★ ★★★ ★★★ — — Fast $$
Zerox ✅ VLM MIT ★★★ ★★★ ★★☆ — — Slow $$$
AWS Textract ✅ SaaS Paid ★★★ ★★★ ★★★ ✅ ✅ Fast $$
Google Doc AI ✅ SaaS Paid ★★★ ★★★ ★★★ ✅ ✅ Fast $$
Azure Doc Intel ✅ SaaS Paid ★★★ ★★★ ★★★ ✅ ✅ Fast $$
Nougat ✅ Local MIT ★★★ ★★☆ ★★☆ — — Slow Free
Surya ✅ Local GPL ★★☆ ★★★ ★★☆ ✅ ✅ Medium Free
Unlimited-OCR ✅ Local/VLM MIT ★★★ ★★★ ★★★ — — Slow Free
MarkItDown ✅ Local MIT ★★☆ ★☆☆ ★★☆ — — Fast Free

★★★ Excellent ★★☆ Good ★☆☆ Basic ☆☆☆ Not supported — $$ ~$1-3/1K pages $$$ ~$5-15/1K pages — BBox Bounding boxes — Conf Confidence scores

Full engine profiles, format matrix, hardware requirements, and cost breakdown →

How to Choose

Your situation Recommended engine
Digital PDF, speed is critical PyMuPDF — zero deps, ~1000 pages/sec
Scanned documents, need OCR PaddleOCR (80+ langs), EasyOCR (PyTorch), or Tesseract (100+ langs)
Complex layouts + tables Docling or MinerU (free), LlamaParse (paid)
Academic papers + math formulas MinerU or Nougat (free), Mistral OCR (paid)
Best quality, budget available Mistral OCR or LlamaParse
Use any Vision LLM (GPT-4o, Claude, etc.) Zerox — model-agnostic
Self-hosted, all-in-one ETL Unstructured with hi_res strategy
Diverse file types (not just PDF) Docling or Unstructured
Need bounding boxes + confidence Textract, Google DocAI, or Azure DocInt
Office files (DOCX/PPTX/XLSX) Docling, Marker, Unstructured, or Azure DocInt
AWS/GCP/Azure native pipeline Textract / Google DocAI / Azure DocInt

Why Docfold?

Every engine has trade-offs. Docfold lets you switch between them with one line:

Challenge Without Docfold With Docfold
Try a new engine Rewrite your pipeline Change one string: engine_hint="docling"
Compare quality Manual side-by-side router.compare("doc.pdf") — one line
Batch 1000 files Build your own concurrency router.process_batch(files, concurrency=5)
Measure accuracy Write custom metrics Built-in CER, WER, Table F1, Reading Order
Switch engines later Major refactor Zero code changes — same EngineResult
from docfold import EngineRouter
from docfold.engines.docling_engine import DoclingEngine
from docfold.engines.pymupdf_engine import PyMuPDFEngine

router = EngineRouter([DoclingEngine(), PyMuPDFEngine()])

# Auto-select the best available engine
result = await router.process("invoice.pdf")
print(result.content)       # Markdown output
print(result.engine_name)   # Which engine was used
print(result.processing_time_ms)

# Compare all engines on the same document
results = await router.compare("invoice.pdf")
for name, res in results.items():
    print(f"{name}: {len(res.content)} chars in {res.processing_time_ms}ms")

Supported Engines

Engine Type License Formats GPU Install
Docling Local MIT PDF, DOCX, PPTX, XLSX, HTML, images No pip install docfold[docling]
MinerU Local AGPL-3.0 PDF Recommended pip install docfold[mineru]
Marker API SaaS Paid PDF, Office, images N/A pip install docfold[marker]
PyMuPDF Local AGPL-3.0 PDF No pip install docfold[pymupdf]
OpenDataLoader Local Apache-2.0 PDF No (needs Java 11+) pip install docfold[opendataloader]
PaddleOCR Local Apache-2.0 Images, scanned PDFs Optional pip install docfold[paddleocr]
Tesseract Local Apache-2.0 Images, scanned PDFs No pip install docfold[tesseract]
EasyOCR Local Apache-2.0 Images, scanned PDFs Optional pip install docfold[easyocr]
Unstructured Local Apache-2.0 PDF, Office, HTML, email, ePub Optional pip install docfold[unstructured]
LlamaParse SaaS Paid PDF, Office, images N/A pip install docfold[llamaparse]
Mistral OCR SaaS Paid PDF, images N/A pip install docfold[mistral-ocr]
Zerox VLM MIT PDF, images Depends pip install docfold[zerox]
AWS Textract SaaS Paid PDF, images N/A pip install docfold[textract]
Google Doc AI SaaS Paid PDF, images N/A pip install docfold[google-docai]
Azure Doc Intel SaaS Paid PDF, Office, HTML, images N/A pip install docfold[azure-docint]
Nougat Local MIT (code) PDF Recommended pip install docfold[nougat]
Surya Local GPL-3.0 PDF, images Optional pip install docfold[surya]
Unlimited-OCR Local/VLM MIT PDF, images Required pip install docfold[unlimited-ocr]
MarkItDown Local MIT PDF, Office, HTML, images, CSV/JSON/XML, ePub, audio, ZIP No pip install docfold[markitdown]

Adding your own engine? Implement the DocumentEngine interface — see Adding a Custom Engine below.

Installation

# Core only (no engines — useful for writing custom adapters)
pip install docfold

# With specific engines
pip install docfold[docling]
pip install docfold[docling,pymupdf,tesseract]

# Everything
pip install docfold[all]

Requires Python 3.10+.

CLI

# Convert a document
docfold convert invoice.pdf
docfold convert report.pdf --engine docling --format html --output report.html

# List available engines
docfold engines

# Compare engines on a document
docfold compare invoice.pdf

# Run evaluation benchmark
docfold evaluate tests/evaluation/dataset/ --output report.json

# Health check: version, MCP extra, per-engine availability
docfold doctor
docfold doctor --json

# Register the MCP server in an AI client (see next section)
docfold install claude

# Self-update (or just check): pip upgrade via the running interpreter
docfold update --check
docfold update --extras mcp,docling

MCP Server (for Claude Code, Cursor, agents)

One-click install:

pip install "docfold[mcp]"
docfold install claude    # Claude Code
docfold install codex     # Codex CLI
docfold install cursor    # Cursor
docfold install vscode    # VS Code
docfold install generic   # print JSON config for any other client

Or drop into any client's MCP config manually:

{ "mcpServers": { "docfold": { "command": "docfold-mcp", "args": [] } } }

Exposes parse_document, extract_tables, list_engines, classify_document tools over stdio — all 4 tool definitions + instructions cost your agent under 1000 tokens (budget-tested). Failures come back structured ({"error", "failures"}), never garbage posing as content.

Setting up with an AI agent? Just tell it:

fetch https://mihailorama.github.io/docfold/install.md

— a complete, agent-readable setup instruction (install → verify CLI → register MCP). It's idempotent: safe to run on a machine where docfold is already set up.

How is this different from Docling / Unstructured / MarkItDown?

They're not competitors — they're engines inside docfold. Docling, Unstructured, MarkItDown, PyMuPDF, Marker, Tesseract, and 15+ others are all wrapped behind one DocumentEngine/EngineResult interface. docfold's job is the layer above any single parser:

  • Routing — classify the file (born-digital PDF? scan? office doc?) and pick the right engine per extension, falling back down the priority chain when an engine fails on a file.
  • Evaluation — built-in CER/WER/Table-F1 benchmarks so you pick the best engine for your corpus, not the one with the best marketing.
  • One interface — switching parsers is a one-string change, not a pipeline rewrite. The MCP server stays deliberately small: 4 tight tools, no bloat in your agent's context.

If you love one parser, pin it: engine_hint="docling". If you don't want to choose, don't: router.process(file) picks for you.

Batch Processing

Process hundreds of documents with bounded concurrency and progress tracking:

from docfold import EngineRouter
from docfold.engines.docling_engine import DoclingEngine

router = EngineRouter([DoclingEngine()])

# Simple batch
batch = await router.process_batch(
    ["invoice1.pdf", "invoice2.pdf", "report.docx"],
    concurrency=3,
)
print(f"{batch.succeeded}/{batch.total} succeeded in {batch.total_time_ms}ms")

# With progress callback
def on_progress(*, current, total, file_path, engine_name, status, **_):
    print(f"[{current}/{total}] {status}: {file_path} ({engine_name})")

batch = await router.process_batch(
    file_paths,
    concurrency=5,
    on_progress=on_progress,
)

# Access results
for path, result in batch.results.items():
    print(f"{path}: {len(result.content)} chars")

# Check errors
for path, error in batch.errors.items():
    print(f"FAILED {path}: {error}")

Unified Result Format

Every engine returns the same EngineResult dataclass:

@dataclass
class EngineResult:
    content: str              # The extracted text (markdown/html/json/text)
    format: OutputFormat      # markdown | html | json | text
    engine_name: str          # Which engine produced this
    metadata: dict            # Engine-specific metadata
    pages: int | None         # Number of pages processed
    images: dict | None       # Extracted images {filename: base64}
    tables: list | None       # Extracted tables
    bounding_boxes: list | None  # Layout element positions
    confidence: float | None  # Overall confidence [0-1]
    processing_time_ms: int   # Wall-clock time

Evaluation Framework

Docfold includes a built-in evaluation harness to objectively compare engines:

pip install docfold[evaluation]
docfold evaluate path/to/dataset/ --engines docling,pymupdf,marker

Metrics measured:

Metric What it measures Target
CER (Character Error Rate) Character-level text accuracy < 0.05
WER (Word Error Rate) Word-level text accuracy < 0.10
Table F1 Table detection and cell content accuracy > 0.85
Heading F1 Heading detection precision/recall > 0.90
Reading Order Score Correctness of reading order (Kendall's tau) > 0.90

See docs/evaluation.md for the ground truth JSON schema and detailed usage.

Architecture

                        ┌─────────────────────────────┐
                        │       Your Application      │
                        └──────────┬──────────────────┘
                                   │
                        ┌──────────▼──────────────────┐
                        │       EngineRouter          │
                        │  select() / process()       │
                        │  process_batch() / compare() │
                        └──────────┬──────────────────┘
                                   │
     ┌──────────┬───────┬──────────┴──────┬──────────┬──────────┐
     ▼          ▼       ▼                 ▼          ▼          ▼
┌────────┐ ┌────────┐ ┌──────────┐  ┌────────┐ ┌────────┐ ┌──────┐
│Docling │ │ MinerU │ │Unstructd │  │ Marker │ │PyMuPDF │ │ OCR  │
│(local) │ │(local) │ │ (local)  │  │ (SaaS) │ │(local) │ │Paddle│
└────────┘ └────────┘ └──────────┘  └────────┘ └────────┘ │Tess. │
     │          │           │            │          │      └──────┘
     │     ┌────────┐ ┌──────────┐ ┌────────┐      │          │
     │     │Llama   │ │ Mistral  │ │ Zerox  │      │          │
     │     │Parse   │ │  OCR     │ │ (VLM)  │      │          │
     │     │(SaaS)  │ │ (SaaS)  │ │        │      │          │
     │     └────────┘ └──────────┘ └────────┘      │          │
     │          │           │            │          │          │
     │     ┌────────┐ ┌──────────┐ ┌────────┐      │          │
     │     │Textract│ │Google    │ │ Azure  │      │          │
     │     │ (AWS)  │ │DocAI     │ │DocInt  │      │          │
     │     │        │ │ (GCP)    │ │        │      │          │
     │     └────────┘ └──────────┘ └────────┘      │          │
     └──────────┴───────┴─────────────┴─────────────┴──────────┘
                                   │
                          ┌────────▼───────┐
                          │  EngineResult  │
                          │  (unified)     │
                          └────────────────┘

Engine Selection Logic

When no engine is explicitly specified, the router selects one automatically:

  1. Explicit hint — engine_hint="docling" in the call
  2. Environment default — ENGINE_DEFAULT=docling env var
  3. Extension-aware priority — each file type has its own engine priority chain (e.g., .png prefers PaddleOCR, .pdf prefers Docling, .docx skips PDF-only engines)
  4. User-configurable — override with fallback_order or restrict with allowed_engines
# Restrict to specific engines
router = EngineRouter(engines, allowed_engines={"docling", "pymupdf"})

# Custom fallback order
router = EngineRouter(engines, fallback_order=["pymupdf", "docling", "marker"])

# CLI: --engines flag
# docfold convert invoice.pdf --engines docling,pymupdf

Adding a Custom Engine

Implement the DocumentEngine interface:

from docfold.engines.base import DocumentEngine, EngineResult, OutputFormat

class MyEngine(DocumentEngine):
    @property
    def name(self) -> str:
        return "my_engine"

    @property
    def supported_extensions(self) -> set[str]:
        return {"pdf", "docx"}

    def is_available(self) -> bool:
        try:
            import my_library
            return True
        except ImportError:
            return False

    async def process(self, file_path, output_format=OutputFormat.MARKDOWN, **kwargs):
        # Your extraction logic here
        content = extract(file_path)
        return EngineResult(
            content=content,
            format=output_format,
            engine_name=self.name,
        )

# Register it
router.register(MyEngine())

Related Projects

Docfold builds on and integrates with these excellent projects:

Project Description
Docling IBM's document conversion toolkit — PDF, DOCX, PPTX, and more
MinerU (2.x) End-to-end PDF structuring with layout analysis and formula recognition (pipeline + VLM backends)
Marker High-quality PDF to Markdown converter
PyMuPDF Fast PDF/XPS/EPUB processing library
PaddleOCR Multilingual OCR toolkit (80+ languages)
Tesseract Open-source OCR engine (100+ languages)
Unstructured ETL toolkit for diverse document types
LlamaParse LLM-powered document parsing
Mistral OCR Vision LLM document understanding
Zerox Model-agnostic Vision LLM OCR
Nougat Meta's academic PDF to Markdown model
Surya Multilingual OCR + layout analysis
Unlimited-OCR Baidu's one-shot long-horizon document-parsing VLM

Built by

Project Description
Datatera.ai AI-powered data transformation and document processing platform
Orquesta AI AI orchestration and agent management platform
AI Agent Labs AI agent services and location-based intelligence

Development

git clone https://github.com/mihailorama/docfold.git
cd docfold
pip install -e ".[dev]"

# Run tests
pytest

# Run linting
ruff check src/ tests/
mypy src/

See CONTRIBUTING.md for detailed guidelines.

License

MIT. See LICENSE.

Note: Some engine backends have their own licenses (AGPL-3.0 for PyMuPDF and MinerU, GPL-3.0 for Surya, SaaS terms for Marker/LlamaParse/Mistral). Docfold itself is MIT — the engine adapters are optional extras that you install separately.

Metadata

Release files for docfold 0.7.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for docfold 0.7.0
File Size Uploaded
docfold-0.7.0.tar.gz 426.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for docfold 0.7.0
File Interpreter ABI Platform
docfold-0.7.0-py3-none-any.whl Python 3 none any Details

Total release size: 514.9 kB

Release files / docfold-0.7.0.tar.gz

Download URL docfold-0.7.0.tar.gz
Size 426.0 kB
Tags Source
SHA-256 checksum
How to use checksums
2f832423c000849d72cf666ed161c708c5173775b6f856e7280227e36f272307
BLAKE2b-256 checksum
How to use checksums
62c5ac3fbaffe395462ae91bb4839fa08e8bdd031d215d0e8169238ab5d89be2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.

Transparency log

Release files / docfold-0.7.0-py3-none-any.whl

Download URL docfold-0.7.0-py3-none-any.whl
Size 88.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
10148665d1f770b5872a1f2f525860121ff1ea503ca812fd288ad477416b4167
BLAKE2b-256 checksum
How to use checksums
c9733d04286faccd0c12812ee09cbcaeaf666a0e8ed19f5850d225082e796734
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.7.0 This release

2 release files

0.6.13

2 release files

0.6.9

2 release files

0.6.8

2 release files

0.6.7

2 release files

0.6.6

2 release files

0.6.5

2 release files

0.6.4

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page