Skip to main content
Glama

from opendockit import convert_file

result = convert_file("quarterly-report.hwp")

result.text        # Markdown: headings, tables, lists, footnotes, LaTeX equations
result.sections    # per page / slide / sheet — for chunking and citations ("page 3")
result.warnings    # what was skipped or approximated, in plain sentences

Why OpenDocKit

Most converters handle the happy path. OpenDocKit is built for the files people actually upload.

  • Structure, not just text. Merged table cells, multi-column PDFs, borderless tables, nested lists, footnotes, speaker notes, native charts as data tables, SmartArt as nested lists, Word / PowerPoint / Hancom equations as LaTeX, links and bold / italic as Markdown.

  • First-class Korean documents. A from-scratch HWP 5.x parser, HWPX, CP949 detection, NFC normalization, and the form-heavy tables Korean offices produce. Most general-purpose converters cannot read these at all.

  • Detects by content, not extension. An HTML table saved as .xls, a CSV with a title block, an MHTML page named .doc — each is read as what it really is, and a warning tells you.

  • Safe on untrusted uploads. Zip bombs, runaway merged-cell counts, recursive PDF objects and multi-gigabyte images are bounded. IsolatedConverter runs every file in a disposable worker process with memory and time limits.

  • Images in place. Pictures, charts and scanned pages are extracted, filtered, and — if you plug in a vision model — described right where they appeared in the document.

  • A hard character budget. max_chars stops work instead of truncating afterwards, so a file that will be rejected anyway costs neither parsing time nor vision-model calls.

  • Permissive by default. MIT licensed; everything a plain pip install opendockit brings in is MIT / BSD / Apache-style (no PyMuPDF, no pyhwp), with no ML models and no GPU. The only copyleft code is behind the opt-in heic extra.

Related MCP server: Knowledge Assistant MCP

Installation

pip install opendockit                # conversion only — never touches the network
pip install "opendockit[openai]"      # + image description with a vision model
pip install "opendockit[heic]"        # + HEIC/HEIF images (pulls in GPL/LGPL-licensed codec libraries)
pip install "opendockit[langchain]"   # + LangChain loader
pip install "opendockit[llamaindex]"  # + LlamaIndex reader
pip install "opendockit[mcp]"         # + MCP server for agents

Requires Python 3.12 or newer on Linux or macOS. Windows is not supported yet for HTML, email and EPUB (why).

Optional: install LibreOffice (brew install --cask libreoffice, apt install libreoffice) to read legacy .doc and .ppt files. Every other format is read by OpenDocKit itself.

Quick start

Convert

from opendockit import convert, convert_file

result = convert_file("report.pdf")              # from a path
result = convert(data, "report.pdf")             # from bytes (the filename is only a hint)

print(result.text)
print(result.char_count, result.exceeded)        # size of the output, and whether the limit stopped it

convert is synchronous, offline and deterministic (the one exception: .doc and .ppt start a local LibreOffice process). Pictures are collected in result.images and the text keeps an [Image] placeholder where each one was.

Describe images with a vision model

from opendockit import OpenAIImageDescriber, aconvert

result = await aconvert(data, "report.pdf", describer=OpenAIImageDescriber())   # reads OPENAI_API_KEY

Charts become data tables, diagrams become lists, scanned pages are transcribed, and decorative images are dropped. OpenAIImageDescriber(model) accepts any LangChain chat model, and anything with an async describe(image) -> str method works as a describer. See docs/images.md.

Serve it

from opendockit import ConversionError, IsolatedConverter

async with IsolatedConverter(workers=2) as converter:      # 2 GB and 2 minutes per file by default
    try:
        result = await converter.convert(data, filename)
    except ConversionError as exc:
        print(exc.code, exc)                               # stable code + a message safe to show users

One bad file ends one worker; your server and the next upload carry on. In a script, run this under if __name__ == "__main__": — the workers import the main module again. See docs/server.md.

Command line

opendockit report.pdf                 # Markdown on stdout, warnings on stderr
opendockit report.pdf --json          # sections, metadata, warnings, images
opendockit report.pdf --count         # just the character count
opendockit scan.pdf --describe        # describe images with a vision model (uses OPENAI_API_KEY)

LangChain, LlamaIndex and MCP

from opendockit.integrations.langchain import OpenDocKitLoader
from opendockit.integrations.llama_index import OpenDocKitReader

docs = OpenDocKitLoader("report.pdf", mode="sections").load()       # one Document per page / slide / sheet
docs = OpenDocKitReader(mode="sections").load_data("report.pdf")
opendockit-mcp --root ~/Documents     # MCP server: Claude, Cursor and other agents read your documents as Markdown

With mode="sections" each page, slide or sheet is its own Document, with its number in the metadata for citations. See docs/integrations.md.

Supported formats

Format

Sections

Highlights

PDF

page

reading order across columns, ruled and borderless tables, form field values, headings from font size, repeated header/footer removal, scanned pages via vision model

DOCX

document

heading styles, list numbering, merged cells, charts → tables, SmartArt, footnotes/endnotes, equations → LaTeX, comments

PPTX

slide

on-screen order, bullet levels, tables, charts → tables, SmartArt, equations, speaker notes

XLSX · XLS · Excel 2003 XML · CSV

sheet

several tables per sheet, merged cells, number and date formats, charts, cell comments

HWP · HWPX

document

outline headings, numbering, merged cells, captions, footnotes, equations → LaTeX

ODT · ODS · ODP

document / sheet / slide

read directly from the package: headings, lists, merged cells, charts, formulas → LaTeX, speaker notes

RTF

document

built-in parser: legacy code pages (CP949), tables with merged cells, lists, footnotes, pictures

EPUB

document

chapters in reading order, pictures stored in the book, metadata

DOC · PPT

document / slide

converted through LibreOffice when it is installed, then read like DOCX / PPTX

HTML · MHTML

document

tables with rowspan/colspan, layout tables unwrapped, MathML → LaTeX, hidden elements removed

Email (.eml, mbox)

document

headers, HTML or plain body, forwarded messages, calendar invites

TXT · Markdown

document

encoding detection (UTF-8, CP949, UTF-16, Windows-1252)

Images

document / page

JPEG, PNG, WebP, GIF, BMP, TIFF, AVIF, and HEIC with the heic extra — described by a vision model

Legacy .doc and .ppt need LibreOffice installed; everything else is read by OpenDocKit itself. The full list of what each format restores is in docs/formats.md; the honest list of what it cannot do is in docs/limitations.md.

How it compares

We ran OpenDocKit, MarkItDown, Kreuzberg, Unstructured and Docling on the same files on a standard GitHub runner (method, raw results and how to rerun it):

  • Structure — OpenDocKit keeps the most: 49 of 49 checks such as "is the merged cell still attached to its row", against 36 for the next tool. The checks are ours, and 0.2.0 was written with them known; the report says what that means.

  • Formats — it reads 26 of the 31 formats tested without any model or service, the most of the five, and is the only one that reads HWP and HWPX.

  • Not the fastest, and no OCR — scans and images are read only through a vision model, where Docling and Unstructured read them offline. Kreuzberg is about thirty times faster, and legacy .doc / .ppt cost about a second each because they go through LibreOffice.

Examples

examples/ has one sample document per format and the Markdown OpenDocKit produces from each — with and without a vision model — so you can judge the output before installing anything.

Documentation

Formats

What is extracted from each format and how it is rendered

Options

ConvertOptions, exceptions and error codes

Images

Extraction, filtering, vision models, custom describers

Running on a server

IsolatedConverter, resource limits, the character budget

Integrations

LangChain, LlamaIndex and the MCP server

Integration guide

What an upload UI should tell its users

Design

Why it is built this way, and how it was verified

Limitations

Known gaps, stated plainly

Decision records

Every deliberate trade-off, with the test that pins it

Contributing

Contributions are welcome — bug reports with a minimal reproducing document are especially valuable. Start with CONTRIBUTING.md.

git clone https://github.com/hyeonsang010716/OpenDocKit.git && cd OpenDocKit
uv sync
uv run pytest -n auto -m "not timing"   # the bulk of the suite, in parallel
uv run pytest -m timing                  # tests that measure time, one at a time
uv run ruff check

License

MIT

Available Tools

2 tools
convert_documentA
Read-onlyIdempotent

Convert a local document to Markdown.

path: the file to read (absolute, or relative to where the server was started). sections: which pages, slides or sheets to return, by their numbers in document_outline: "3" or "2-5". Leave out for the whole document. max_chars: the most characters of the document to return (default 100,000). A longer text is cut there, and a note after it says so.

Inputs: path (required), sections, max_chars.

document_outlineA
Read-onlyIdempotent

Describe a local document without returning its text: format, title, size, and its pages, slides or sheets with their numbers, titles and lengths. Use it to decide which sections to ask convert_document for.

path: the file to read (absolute, or relative to where the server was started).

Inputs: path (required).

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.4/5.0

    Scored across 2 tools

    Disambiguation5/5

    The two tools have clearly separate purposes: `document_outline` returns metadata and structural information, while `convert_document` returns extracted text. Their descriptions explicitly explain how they work together, leaving no realistic chance of confusion.

    Naming Consistency4/5

    Both names use snake_case and are descriptive, but the pattern is not fully uniform: `convert_document` is verb-first while `document_outline` is noun-first. This is a minor deviation and remains readable and predictable.

    Tool Count3/5

    The server is very tightly scoped with only two tools. Both earn their place, but the surface is thin for a document-handling server and leaves little room for adjacent operations.

    Completeness4/5

    The core workflow is covered: inspect a document's structure, then convert selected sections to Markdown. Minor gaps exist, such as discovering supported formats or handling batch operations, but agents can reasonably work around them.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      C
      maintenance
      Converts PDFs, Office files, spreadsheets, emails, audio, and more to Markdown locally, enabling AI assistants to read and process them without cloud upload.
      MIT
    • F
      license
      Not graded
      quality
      D
      maintenance
      Enables AI assistants to interact with local documents (PDF, Markdown, TXT) through tools for discovery, reading, extraction, summarization, comparison, keyword extraction, search, and analysis, ensuring privacy and offline capability.
      -
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables AI agents to inspect and convert PDF, PowerPoint, Excel, and many other file formats into clean, structured Markdown, with chunking support for long documents.
      Apache 2.0
    • A
      license
      A
      quality
      C
      maintenance
      Enables AI agents and MCP-capable platforms to convert documents such as docx, pptx, xlsx, pdf, odt, rtf, epub, and csv into clean GitHub-Flavored Markdown through a single tool call. Runs fully locally with no API key, no network access, and no OCR, returning structured errors for scanned, encrypted, or unsupported files.
      1
      13 npm
      MIT