Skip to main content

doc2md

Turn any document into clean Markdown — built for AI agents.

doc2md is an MCP server that converts PDF, DOCX, PPTX, XLSX, EPUB, HTML, CSV/JSON/XML and scanned files (OCR) into agent-ready Markdown. Pass a public URL or base64 content; no API key, no account, no local dependencies for the agent side.

Most document-conversion MCP servers only run locally over stdio. doc2md is designed to be deployed remotely (Streamable HTTP) so any agent — Claude, ChatGPT, Cursor, Glama Chat, your own pipelines — can hand it a URL and get Markdown back in one call.

Why agents love it

  • URL-first — {"url": "https://…/report.pdf"} is all it takes; base64 supported for local files
  • Tables survive — PDF tables are extracted as Markdown/CSV/JSON, not flattened into noise
  • Pagination built in — large documents return in chunks with a offset continuation hint, so context windows stay healthy
  • Scanned? No problem — automatic detection, with a dedicated OCR tool (RapidOCR, offline, no cloud OCR API)
  • Cheap inspection first — get_document_info and search_document let agents find the right pages before converting anything
  • Safe to expose — SSRF protection (private/loopback/link-local IPs rejected on every redirect hop), 30 MB download cap, password-PDF support

Tools

Tool What it does
convert_pdf_to_markdown PDF → Markdown with headings, tables, lists and reading order preserved. pages selection + offset/max_chars pagination.
convert_document_to_markdown Universal one-call converter: auto-detects DOCX/PPTX/XLSX/EPUB/HTML/CSV/PDF and returns Markdown. Falls back to OCR for scanned PDFs and images.
extract_pdf_tables Structural table extraction → markdown, csv or json rows, with page numbers and dimensions.
read_pdf_pages Plain text of specific pages — the cheapest way to read a known location.
get_document_info Format, page count, metadata, table of contents, scanned/encrypted flags.
search_document Full-text keyword search with page numbers + snippets.
ocr_document OCR for scanned PDFs and images (PNG/JPEG/WebP/BMP/TIFF), up to 30 pages per call.
split_pdf Cut a PDF into parts by page range ('1-3,5,8-10'); each part returned as base64 (≤5 MB).
merge_pdfs Merge 2–10 PDFs (URLs or base64) into one document, returned as base64 (≤10 MB).
extract_pdf_images List/export embedded images (figures, charts, scans) with page, dimensions, format; optional base64 (≤2 MB each).

Plus a summarize_document prompt template for clients that surface MCP prompts.

Quickstart

Hosted (zero install)

One-click deploy your own instance from the doc2md page on Glama ("Deploy Server"), or run the Docker image below, then point any MCP client at the Streamable HTTP endpoint:

{
  "mcpServers": {
    "doc2md": {
      "type": "streamable-http",
      "url": "https://glama.ai/endpoints/<your-profile>/mcp"
    }
  }
}

Claude Desktop / Cursor (local)

{
  "mcpServers": {
    "doc2md": {
      "command": "uvx",
      "args": ["--from", "doc2md-mcp[ocr]", "doc2md"]
    }
  }
}

Docker

docker build -t doc2md .
docker run --rm -i doc2md                      # stdio
docker run --rm -p 8000:8000 \
  -e DOC2MD_TRANSPORT=streamable-http doc2md   # HTTP endpoint

From source

pip install "doc2md-mcp[ocr]"   # or: uvx --from "doc2md-mcp[ocr]" doc2md
doc2md                          # stdio server

# or from source
git clone https://github.com/skyzhao1223/doc2md && cd doc2md
uv sync --extra ocr --extra dev
uv run doc2md          # stdio server
uv run pytest          # test suite

Example session

agent → get_document_info {"url": "https://arxiv.org/pdf/1706.03762"}
      ← {kind: "pdf", page_count: 15, is_scanned: false, toc: [...]}

agent → search_document {"url": "...", "query": "BLEU"}
      ← matches on pages 8, 9, 10 with snippets

agent → read_pdf_pages {"url": "...", "pages": "8-9"}
      ← plain text of exactly those pages

Limits

Limit Value
Download / base64 size 30 MB
Default response size 40,000 chars (max 200,000), with offset continuation
OCR pages per call 30 (renders at 200 dpi)
Table scan depth first 100 pages per call, 50 tables max
Split ≤20 parts per call, base64 included for parts ≤5 MB
Merge ≤10 inputs, merged output ≤10 MB
Image export ≤50 images per call, base64 for images ≤2 MB
URL fetch public http(s) only, ≤5 redirects, SSRF-filtered

Self-hosting notes

  • Transport: DOC2MD_TRANSPORT=stdio (default) or streamable-http / sse with DOC2MD_HOST / DOC2MD_PORT. Glama hosting wraps stdio automatically.
  • OCR is optional: install the ocr extra (or use the Docker image, which includes it). Without OCR, all other tools still work and OCR calls return an actionable error.
  • Conversion results are cached in memory (content-hash keyed, 30 min TTL) so paginated reads of the same document don't re-convert. Nothing is written to disk persistently; documents are processed in memory and dropped.

Development

uv sync --extra dev --extra ocr
uv run pytest            # 40+ tests: detection, conversion, tables, split/merge, SSRF, in-process MCP smoke tests

Layout: src/doc2md/{server,convert,tables,pdfops,ocr,fetch,detect,cache}.py.

Security

  • SSRF protection: every URL (including each redirect hop) must resolve to public unicast IPs only; file:, ftp: and other schemes are rejected.
  • Size caps on downloads, base64 payloads and OCR page counts.
  • No persistence: documents live in memory for the duration of a call.
  • Runs as a non-root user in the official Docker image.

License

AGPL-3.0-or-later — see LICENSE. The AGPL choice is driven by PyMuPDF (used via PyMuPDF4LLM for high-quality PDF → Markdown), which is AGPL itself. If you operate a modified version of this server over a network, you must offer your users its source.

Roadmap

  • Formula / LaTeX extraction quality pass
  • split_pdf, merge_pdfs utility tools (v0.2.0)
  • Image extraction via extract_pdf_images with base64 export (v0.2.0)
  • PyPI release: doc2md-mcp (v0.2.0)
  • Batch/webhook conversion jobs for very large documents

Release files for doc2md-mcp 0.2.1

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

Source distribution (sdist)

Source distribution for doc2md-mcp 0.2.1
File Size Uploaded
doc2md_mcp-0.2.1.tar.gz 203.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for doc2md-mcp 0.2.1
File Interpreter ABI Platform
doc2md_mcp-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 239.8 kB

Release files / doc2md_mcp-0.2.1.tar.gz

Download URL doc2md_mcp-0.2.1.tar.gz
Size 203.5 kB
Tags Source
SHA-256 checksum
How to use checksums
ef8f16c41e3dcda2814b8af95bc7de46140a0ad6cb93d2e2441ba2c3e8e2be73
BLAKE2b-256 checksum
How to use checksums
e02e9ee7977a93045887a6968e0cfe36f61ffb0ec3038d7567824bba75c538cc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.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 Sep 22, 2026.

Transparency log

Release files / doc2md_mcp-0.2.1-py3-none-any.whl

Download URL doc2md_mcp-0.2.1-py3-none-any.whl
Size 36.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
128689509695d6528dcdca01cb821529972fa9b1f50c66d25c2fa0133d21f217
BLAKE2b-256 checksum
How to use checksums
ac1ca47f6888d67b9931f00444cf7fe6978643452d1f5f638169c4b8e2180478
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.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 Sep 22, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 release files

0.2.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