Skip to main content
Glama

pdfmux

CI PyPI Python 3.11+ License: MIT Downloads

Universeller Orchestrator für PDF-Extraktion. Leitet jede Seite an das beste Backend weiter, prüft die Ausgabe und extrahiert Fehler erneut. 5 regelbasierte Extraktoren + BYOK-LLM-Fallback. Ein CLI. Eine API. Null Konfiguration.

PDF ──> pdfmux router ──> best extractor per page ──> audit ──> re-extract failures ──> Markdown / JSON / chunks
            |
            ├─ PyMuPDF         (digital text, 0.01s/page)
            ├─ OpenDataLoader  (complex layouts, 0.05s/page)
            ├─ RapidOCR        (scanned pages, CPU-only)
            ├─ Docling          (tables, 97.9% TEDS)
            ├─ Surya            (heavy OCR fallback)
            └─ YOUR LLM        (Gemini / Claude / GPT-4o / Ollama — BYOK via 5-line YAML)

Installation

pip install pdfmux

Das ist alles. Verarbeitet digitale PDFs direkt nach der Installation. Fügen Sie Backends für schwierigere Dokumente hinzu:

pip install "pdfmux[ocr]"             # RapidOCR — scanned/image pages (~200MB, CPU-only)
pip install "pdfmux[tables]"          # Docling — table-heavy docs (~500MB)
pip install "pdfmux[opendataloader]"  # OpenDataLoader — complex layouts (Java 11+)
pip install "pdfmux[llm]"            # LLM fallback — Gemini, Claude, GPT-4o, Ollama
pip install "pdfmux[all]"            # everything

Erfordert Python 3.11+.

Schnellstart

CLI

# zero config — just works
pdfmux convert invoice.pdf
# invoice.pdf -> invoice.md (2 pages, 95% confidence, via pymupdf4llm)

# RAG-ready chunks with token limits
pdfmux convert report.pdf --chunk --max-tokens 500

# cost-aware extraction with budget cap
pdfmux convert report.pdf --mode economy --budget 0.50

# schema-guided structured extraction (5 built-in presets)
pdfmux convert invoice.pdf --schema invoice

# BYOK any LLM for hardest pages
pdfmux convert scan.pdf --llm-provider claude

# batch a directory
pdfmux convert ./docs/ -o ./output/

Python

import pdfmux

# text -> markdown
text = pdfmux.extract_text("report.pdf")

# structured data -> dict with tables, key-values, metadata
data = pdfmux.extract_json("report.pdf")

# RAG chunks -> list of dicts with token estimates
chunks = pdfmux.chunk("report.pdf", max_tokens=500)

Architektur

                           ┌─────────────────────────────┐
                           │     Segment Detector         │
                           │  text / tables / images /    │
                           │  formulas / headers per page │
                           └─────────────┬───────────────┘
                                         │
                    ┌────────────────────────────────────────┐
                    │            Router Engine                │
                    │                                        │
                    │   economy ── balanced ── premium        │
                    │   (minimize $)  (default)  (max quality)│
                    │   budget caps: --budget 0.50            │
                    └────────────────────┬───────────────────┘
                                         │
          ┌──────────┬──────────┬────────┴────────┬──────────┐
          │          │          │                  │          │
     PyMuPDF   OpenData    RapidOCR           Docling     LLM
     digital   Loader      scanned            tables    (BYOK)
     0.01s/pg  complex     CPU-only           97.9%    any provider
               layouts                        TEDS
          │          │          │                  │          │
          └──────────┴──────────┴────────┬────────┴──────────┘
                                         │
                    ┌────────────────────────────────────────┐
                    │           Quality Auditor               │
                    │                                        │
                    │   4-signal dynamic confidence scoring   │
                    │   per-page: good / bad / empty          │
                    │   if bad -> re-extract with next backend│
                    └────────────────────┬───────────────────┘
                                         │
                    ┌────────────────────────────────────────┐
                    │           Output Pipeline               │
                    │                                        │
                    │   heading injection (font-size analysis)│
                    │   table extraction + normalization      │
                    │   text cleanup + merge                  │
                    │   confidence score (honest, not inflated)│
                    └────────────────────────────────────────┘

Wichtige Designentscheidungen

  • Router, kein Extraktor. pdfmux konkurriert nicht mit PyMuPDF oder Docling. Es wählt das beste Tool pro Seite aus.

  • Agentischer Multi-Pass. Extrahieren, Konfidenz prüfen, Fehler mit einem stärkeren Backend erneut extrahieren. Fehlerhafte Seiten werden automatisch wiederholt.

  • Segment-basierte Erkennung. Jede Seite wird vor dem Routing nach Inhaltstyp (Text, Tabellen, Bilder, Formeln, Überschriften) klassifiziert.

  • 4-Signal-Konfidenz. Dynamische Qualitätsbewertung basierend auf Zeichendichte, OCR-Rauschverhältnis, Tabellenintegrität und Überschriftenstruktur. Keine fest codierten Schwellenwerte.

  • Dokumenten-Cache. Jedes PDF wird nur einmal geöffnet, nicht einmal pro Extraktor. Gemeinsame Nutzung über die gesamte Pipeline hinweg.

  • Daten-Flywheel. Lokale Telemetrie verfolgt, welche Extraktoren bei welchem Dokumenttyp am besten abschneiden. Das Routing verbessert sich mit der Nutzung.

Funktionen

Funktion

Was es tut

Befehl

Zero-Config-Extraktion

Leitet automatisch an das beste Backend weiter

pdfmux convert file.pdf

RAG-Chunking

Abschnittsbewusste Chunks mit Token-Schätzungen

pdfmux convert file.pdf --chunk --max-tokens 500

Kostenmodi

economy / balanced / premium mit Budgetobergrenzen

pdfmux convert file.pdf --mode economy --budget 0.50

Schema-Extraktion

5 integrierte Voreinstellungen (Rechnung, Quittung, Vertrag, Lebenslauf, Dokument)

pdfmux convert file.pdf --schema invoice

BYOK LLM

Gemini, Claude, GPT-4o, Ollama, jede OpenAI-kompatible API

pdfmux convert file.pdf --llm-provider claude

Benchmark

Evaluiert alle installierten Extraktoren gegen Ground Truth

pdfmux benchmark

Doctor

Zeigt installierte Backends, Abdeckungslücken und Empfehlungen

pdfmux doctor

MCP-Server

KI-Agenten lesen PDFs via stdio oder HTTP

pdfmux serve

Batch-Verarbeitung

Konvertiert ganze Verzeichnisse

pdfmux convert ./docs/

Streaming

Speicheroptimierte Seiteniteration für große Dateien

for page in ext.extract("500pg.pdf")

CLI-Referenz

pdfmux convert

pdfmux convert <file-or-dir> [options]

Options:
  -o, --output PATH          Output file or directory
  -f, --format FORMAT        markdown | json | csv | llm (default: markdown)
  -q, --quality QUALITY      fast | standard | high (default: standard)
  -s, --schema SCHEMA        JSON schema file or preset (invoice, receipt, contract, resume, paper)
  --chunk                    Output RAG-ready chunks
  --max-tokens N             Max tokens per chunk (default: 500)
  --mode MODE                economy | balanced | premium (default: balanced)
  --budget AMOUNT            Max spend per document in USD
  --llm-provider PROVIDER    LLM backend: gemini | claude | openai | ollama
  --confidence               Include confidence score in output
  --stdout                   Print to stdout instead of file

pdfmux serve

Startet den MCP-Server für die Integration von KI-Agenten.

pdfmux serve              # stdio mode (Claude Desktop, Cursor)
pdfmux serve --http 8080  # HTTP mode

pdfmux doctor

pdfmux doctor
# ┌──────────────────┬─────────────┬─────────┬──────────────────────────────────┐
# │ Extractor        │ Status      │ Version │ Install                          │
# ├──────────────────┼─────────────┼─────────┼──────────────────────────────────┤
# │ PyMuPDF          │ installed   │ 1.25.3  │                                  │
# │ OpenDataLoader   │ installed   │ 0.3.1   │                                  │
# │ RapidOCR         │ installed   │ 3.0.6   │                                  │
# │ Docling          │ missing     │ --      │ pip install pdfmux[tables]       │
# │ Surya            │ missing     │ --      │ pip install pdfmux[ocr-heavy]    │
# │ LLM (Gemini)     │ configured  │ --      │ GEMINI_API_KEY set               │
# └──────────────────┴─────────────┴─────────┴──────────────────────────────────┘

pdfmux benchmark

pdfmux benchmark report.pdf
# ┌──────────────────┬────────┬────────────┬─────────────┬──────────────────────┐
# │ Extractor        │   Time │ Confidence │      Output │ Status               │
# ├──────────────────┼────────┼────────────┼─────────────┼──────────────────────┤
# │ PyMuPDF          │  0.02s │        95% │ 3,241 chars │ all pages good       │
# │ Multi-pass       │  0.03s │        95% │ 3,241 chars │ all pages good       │
# │ RapidOCR         │  4.20s │        88% │ 2,891 chars │ ok                   │
# │ OpenDataLoader   │  0.12s │        97% │ 3,310 chars │ best                 │
# └──────────────────┴────────┴────────────┴─────────────┴──────────────────────┘

Python-API

Textextraktion

import pdfmux

text = pdfmux.extract_text("report.pdf")                    # -> str (markdown)
text = pdfmux.extract_text("report.pdf", quality="fast")    # PyMuPDF only, instant
text = pdfmux.extract_text("report.pdf", quality="high")    # LLM-assisted

Strukturierte Extraktion

data = pdfmux.extract_json("report.pdf")
# data["page_count"]   -> 12
# data["confidence"]   -> 0.91
# data["ocr_pages"]    -> [2, 5, 8]
# data["pages"][0]["key_values"]  -> [{"key": "Date", "value": "2026-02-28"}]
# data["pages"][0]["tables"]      -> [{"headers": [...], "rows": [...]}]

RAG-Chunking

chunks = pdfmux.chunk("report.pdf", max_tokens=500)
for c in chunks:
    print(f"{c['title']}: {c['tokens']} tokens (pages {c['page_start']}-{c['page_end']})")

Schema-gesteuerte Extraktion

data = pdfmux.extract_json("invoice.pdf", schema="invoice")
# Uses built-in invoice preset: extracts date, vendor, line items, totals
# Also accepts a path to a custom JSON Schema file

Streaming (begrenzter Speicher)

from pdfmux.extractors import get_extractor

ext = get_extractor("fast")
for page in ext.extract("large-500-pages.pdf"):  # Iterator[PageResult]
    process(page.text)  # constant memory, even on 500-page PDFs

Typen und Fehler

from pdfmux import (
    # Enums
    Quality,              # FAST, STANDARD, HIGH
    OutputFormat,         # MARKDOWN, JSON, CSV, LLM
    PageQuality,          # GOOD, BAD, EMPTY

    # Data objects (frozen dataclasses)
    PageResult,           # page: text, page_num, confidence, quality, extractor
    DocumentResult,       # document: pages, source, confidence, extractor_used
    Chunk,                # chunk: title, text, page_start, page_end, tokens

    # Errors
    PdfmuxError,          # base -- catch this for all pdfmux errors
    FileError,            # file not found, unreadable, not a PDF
    ExtractionError,      # extraction failed
    ExtractorNotAvailable,# requested backend not installed
    FormatError,          # invalid output format
    AuditError,           # audit could not complete
)

Framework-Integrationen

LangChain

pip install langchain-pdfmux
from langchain_pdfmux import PDFMuxLoader

loader = PDFMuxLoader("report.pdf", quality="standard")
docs = loader.load()  # -> list[Document] with confidence metadata

LlamaIndex

pip install llama-index-readers-pdfmux
from llama_index.readers.pdfmux import PDFMuxReader

reader = PDFMuxReader(quality="standard")
docs = reader.load_data("report.pdf")  # -> list[Document]

MCP-Server (KI-Agenten)

Gelistet auf mcpservers.org. Einzeilige Einrichtung:

{
  "mcpServers": {
    "pdfmux": {
      "command": "npx",
      "args": ["-y", "pdfmux-mcp"]
    }
  }
}

Oder via Claude Code:

claude mcp add pdfmux -- npx -y pdfmux-mcp

Verfügbare Tools: convert_pdf, analyze_pdf, extract_structured, get_pdf_metadata, batch_convert.

BYOK LLM-Konfiguration

pdfmux unterstützt jedes LLM über 5 Zeilen YAML. Bringen Sie Ihre eigenen Schlüssel mit – nichts verlässt Ihren Rechner, es sei denn, Sie konfigurieren es so.

# ~/.pdfmux/llm.yaml
provider: claude          # gemini | claude | openai | ollama | any OpenAI-compatible
model: claude-sonnet-4-20250514
api_key: ${ANTHROPIC_API_KEY}
base_url: https://api.anthropic.com  # optional, for custom endpoints
max_cost_per_page: 0.02   # budget cap

Unterstützte Anbieter:

Anbieter

Modelle

Lokal?

Kosten

Gemini

2.5 Flash, 2.5 Pro

Nein

~$0.01/Seite

Claude

Sonnet, Opus

Nein

~$0.015/Seite

GPT-4o

GPT-4o, GPT-4o-mini

Nein

~$0.01/Seite

Ollama

Jedes lokale Modell

Ja

Kostenlos

Custom

Jede OpenAI-kompatible API

Konfigurierbar

Variabel

Benchmark

Getestet auf opendataloader-bench – 200 reale PDFs aus Finanzberichten, juristischen Unterlagen, wissenschaftlichen Arbeiten und gescannten Dokumenten.

Engine

Gesamt

Lesereihenfolge

Tabellen (TEDS)

Überschriften

Erfordert

opendataloader hybrid

0.909

0.935

0.928

0.828

API-Aufrufe ($)

pdfmux

0.905

0.920

0.911

0.852

Nur CPU, $0

docling

0.877

0.900

0.887

0.802

~500MB Modelle

marker

0.861

0.890

0.808

0.796

GPU empfohlen

opendataloader local

0.844

0.913

0.494

0.761

Nur CPU

mineru

0.831

0.857

0.873

0.743

GPU + ~2GB Modelle

Platz 2 insgesamt, Platz 1 unter den kostenlosen Tools. 99,5 % der Punktzahl des kostenpflichtigen Spitzenreiters bei null Kosten pro Seite. Beste Überschriftenerkennung aller getesteten Engines. Bild-Tabellen-OCR extrahiert Tabellen, die als Bilder eingebettet sind.

Konfidenzbewertung

Jedes Ergebnis enthält einen 4-Signal-Konfidenzwert:

  • 95-100 % -- sauberer digitaler Text, vollständig extrahierbar

  • 80-95 % -- gute Extraktion, geringfügiges OCR-Rauschen auf einigen Seiten

  • 50-80 % -- teilweise Extraktion, einige Seiten nicht wiederherstellbar

  • <50 % -- erheblicher Inhaltsverlust, Warnungen enthalten

Wenn die Konfidenz unter 80 % fällt, sagt Ihnen pdfmux genau, was schiefgelaufen ist und wie Sie es beheben können:

Page 4: 32% confidence. 0 chars extracted from image-heavy page.
  -> Install pdfmux[ocr] for RapidOCR support on 6 image-heavy pages.

Kostenmodi

Modus

Verhalten

Typische Kosten

economy

Nur regelbasierte Backends. Keine LLM-Aufrufe.

$0/Seite

balanced

LLM nur für Seiten, bei denen die regelbasierte Extraktion fehlschlägt.

~$0.002/Seite im Schnitt

premium

LLM auf jeder Seite für maximale Qualität.

~$0.01/Seite

Legen Sie eine harte Budgetobergrenze fest: --budget 0.50 stoppt LLM-Aufrufe, wenn die Ausgaben $0,50 pro Dokument erreichen.

Warum pdfmux?

pdfmux ist kein weiterer PDF-Extraktor. Es ist die Orchestrierungsschicht, die den richtigen Extraktor pro Seite auswählt, das Ergebnis verifiziert und Fehler erneut versucht.

Tool

Gut in

Einschränkung

PyMuPDF

Schneller digitaler Text

Kann keine Scans oder Bildlayouts verarbeiten

Docling

Tabellen (97,9 % Genauigkeit)

Langsam bei Nicht-Tabellen-Dokumenten

Marker

GPU-ML-Extraktion

Benötigt GPU, Overkill für digitale PDFs

Unstructured

Enterprise-Plattform

Komplexe Einrichtung, kostenpflichtige Stufen

LlamaParse

Cloud-nativ

Erfordert API-Schlüssel, nicht lokal

Reducto

Hohe Genauigkeit

$0.015/Seite, Closed Source

pdfmux

Orchestriert alle oben genannten

Routet pro Seite, prüft, extrahiert erneut

Open-Source-Alternative zu Reducto: Was anderswo $0,015/Seite kostet, ist mit den regelbasierten Backends von pdfmux kostenlos oder kostet im Schnitt ~$0,002/Seite mit BYOK-LLM-Fallback.

Entwicklung

git clone https://github.com/NameetP/pdfmux.git
cd pdfmux
python3.12 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"

pytest              # 151 tests
ruff check src/ tests/
ruff format src/ tests/

Mitwirken

  1. Forken Sie das Repo

  2. Erstellen Sie einen Branch (git checkout -b feature/your-feature)

  3. Schreiben Sie Tests für neue Funktionen

  4. Stellen Sie sicher, dass pytest und ruff check bestehen

  5. Öffnen Sie einen PR

Lizenz

MIT

Install Server
A
security – no known vulnerabilities
A
license - permissive license
A
quality - A tier

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/NameetP/pdfmux'

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