Docling-rs MCP
OfficialProvides a LangChain document loader via the docling-rs[langchain] extra, exposing langchain-docling's DoclingLoader backed by the Rust engine. Documents are converted into structured Markdown/JSON with layout, tables and OCR so they can be fed directly into LangChain pipelines, with a one-import swap from the Python implementation.
Serves as a drop-in replacement for the docling-serve HTTP conversion API, so n8n workflows (alongside other docling-serve clients) can convert PDFs, Office files and other documents to Markdown, JSON and more without changing their configuration.
docling.rs
docling.rs converts documents — PDF, Office, HTML, scans, audio — into Markdown, docling JSON and the other shapes an LLM or a RAG pipeline can read. It is a Rust port of IBM's docling: the same output, byte-for-byte, from one static binary. No Python, no PyTorch.
Pulling text out of a PDF is easy. Keeping its structure — headings in order, tables as tables, scanned pages read — takes layout analysis, table recognition and OCR. docling has the models for that, and a Python stack to match. docling.rs runs the same models from a single binary: PDF 4.3× faster than Python docling at under half the RAM, Office and HTML 20–60× faster, and tables that survive — cell recall 0.94 where MarkItDown gets 0.31 (numbers, method).
Install
# CLI + models (Linux x64/arm64 prebuilt; builds from source elsewhere)
curl -fsSL https://raw.githubusercontent.com/docling-project/docling.rs/master/scripts/install/install.sh | bash
docling-rs example.pdf # Markdown on stdout
# or from crates.io; --cli puts the models where the installed binary looks
cargo install docling-cli
curl -fsSL https://raw.githubusercontent.com/docling-project/docling.rs/master/scripts/install/download_dependencies.sh | sh -s -- --cli
pip install docling-rs # Python — drop-in for docling's and MarkItDown's APIs
npm install docling.rs # Node.js / Bun
cargo add docling # Rust library
# containers, models baked in (-cuda variants for NVIDIA)
docker run --rm -v "$PWD:/data" ghcr.io/docling-project/docling-rs paper.pdf
docker run -p 127.0.0.1:5001:5001 ghcr.io/docling-project/docling-rs-serveOffice, HTML, Markdown and e-mail need no models. PDF, images and audio need
the ONNX models (layout, OCR, TableFormer, Whisper; under 1 GB): install.sh,
--cli and the containers bring them along; with pip, run
python -c "import docling_rs; docling_rs.download_models()" once; with npm
or a checkout, run download_dependencies.sh where you convert
(details). Windows: docs/WINDOWS.md.
▶ Try it in your browser first — the converter as wasm, OCR included; nothing leaves your device.
Related MCP server: md-server
Use
docling-rs report.pdf > report.md # Markdown (streamed page by page)
docling-rs report.pdf --to json # docling JSON; also html, text, latex, dclx, chunks, images
docling-rs --input ./docs --output ./out # a directory tree; --jobs N in parallel
docling-rs https://example.com/paper.pdf # URLs, data: URIs and stdin (`-`) too
docling-rs --help # every flag: OCR, page ranges, images, enrichment, redaction …from docling_rs import DocumentConverter # was: from docling.document_converter import …
doc = DocumentConverter().convert("report.pdf").document
print(doc.export_to_markdown())import { convertFileAsync } from 'docling.rs'
const { content } = await convertFileAsync('report.pdf', { to: 'markdown' })use docling::{DocumentConverter, SourceDocument};
let result = DocumentConverter::new().convert(SourceDocument::from_file("report.pdf")?)?;
println!("{}", result.document.export_to_markdown());curl -F file=@report.pdf 'localhost:5001/v1/convert?to=md' # the server; OpenAPI at /openapi.yamlSame options, same outputs on every surface — every option in
docs/OPTIONS.md.
Highlights
From MarkItDown:
pip install docling-rs, swap one import —from docling_rs.markitdown import MarkItDown— and keep its API with real layout, tables and OCR behind it (guide).From Python docling:
from docling_rs import DocumentConverter;result.documentis a genuineDoclingDocument(migration notes).Every docling format, and a few it lacks — the table under Status, each validated against live docling (Conformance).
Every output docling has: Markdown (docling's, or a stricter dialect), docling JSON, HTML, plain text, DocLang, LaTeX, Pandoc AST (→ DOCX, EPUB, Typst… through pandoc), WebVTT subtitles, RAG chunks and page images (output formats).
From any language: Rust, Python, Node.js / Bun, the browser (wasm, fully client-side), C, C++, C#, Go, Java and Swift through one C header, any HTTP client, the shell (Integration).
A drop-in server for docling-serve: Open WebUI uses it as its Docling content-extraction engine — point Docling Server URL at
http://<host>:5001— and n8n, Dify and LangChain clients work unchanged (docling-rs serve, Open WebUI setup).AI agents (MCP):
docling-rs mcpgives Claude Desktop, Claude Code, Cursor or VS Code MarkItDown'sconvert_to_markdowntool, plusconvertfor JSON, chunks and the rest —uvx docling-rs-mcp, orclaude mcp add docling -- docling-rs mcp(MCP server).LangChain:
pip install "docling-rs[langchain]"— langchain-docling'sDoclingLoaderon the Rust engine, one import to swap (details).AutoGen:
pip install "docling-rs[autogen]"—DoclingIndexerfills any AutoGen memory with chunks that carry their pages,DoclingConvertToollets an agent read documents (details).RAG:
docling-rag— chunk, embed and search with a REST API and a web UI (RAG subsystem).Runs where you are: Linux x64 / arm64 / s390x and Windows prebuilt (CLI, wheels, npm), macOS from source, containers for amd64 and arm64; NVIDIA CUDA and TensorRT, DirectML, CoreML and WebGPU in the browser as opt-in accelerators (GPU, IBM Z).
Developed with Claude Code and TENET (minimalistic AI-driven development framework).
Status
Every format in docling's pipeline converts — plus a few docling lacks. A
file with no or an unknown extension, stdin, an upload or a data: URL is
typed by its content (InputFormat::detect, docling_rs.detect_format,
detectFormat: the packages, the OLE files, PDF, images, audio and video,
iWork, XML, JSON, notebooks, messages, …), and a file that fails under its
extension is checked by content and converted as what it really is, with a
warning.
Category | Formats |
Text & markup | Markdown, AsciiDoc, HTML, MHTML, LaTeX (multi-file arXiv projects, math, tables); plain text and source code ( |
Word processing | DOCX, Word 97–2004 |
Presentations | PPTX, PowerPoint 97–2003, ODP, OpenOffice / StarImpress |
Spreadsheets | XLSX, XLSB, Excel 97–2004, ODS, CSV / TSV, dBase, DIF, SYLK, Lotus 1-2-3, Quattro Pro, MS Works |
Diagrams · Apple iWork | Visio, SVG · Pages, Numbers, Keynote |
PDF & images | PDF (layout, TableFormer, OCR), PNG, JPEG, TIFF, BMP, WebP, GIF, HEIC (opt-in), METS/GBS scans, DjVu |
XML · docling native | JATS, USPTO, XBRL, DocLang · docling JSON, DocTags, DCLX |
Email · subtitles · mainframe |
|
Audio · video | WAV, MP3, M4A, AAC, OGG, FLAC; MP4, AVI, MOV, MKV, WebM, MPEG — local Whisper or Parakeet, plus scene frames from video |
Every extension, with what each backend does:
docs/MIGRATION.md.
Any ffmpeg ≥ 4.x on PATH works; docling.rs shells out to the binary and
parses its output, so no dev headers/libraries are needed.
Debian/Ubuntu:
sudo apt-get install ffmpegFedora:
sudo dnf install ffmpeg-free(orffmpegfrom RPM Fusion)Alpine:
apk add ffmpegmacOS:
brew install ffmpegWindows:
winget install ffmpeg(orchoco install ffmpeg, orscoop install ffmpeg). Installing from a downloaded zip (gyan.dev / BtbN) also works — either add the extractedbin\folder toPATH, or skipPATHentirely and pointDOCLING_FFMPEGat the exe:set DOCLING_FFMPEG=C:\tools\ffmpeg\bin\ffmpeg.exe
Check with ffmpeg -version. DOCLING_FFMPEG overrides the binary used on
any OS; the docling-rs-serve Docker image ships ffmpeg preinstalled.
Conformance with Microsoft MarkItDown
MarkItDown converts the same kinds
of documents to Markdown for LLMs. Measured side by side — MarkItDown 0.1.8
(markitdown[all]) and docling.rs 2.16.0 (release build), 4 vCPU, no GPU —
on this repository's test corpus and on MarkItDown's own OCR test set
(scripts/conformance/markitdown_compare.py):
Corpus (files) | MarkItDown, warm | docling.rs, warm | Cold CLI call, MarkItDown / docling.rs | Word F1 | Table-cell recall | Heading recall |
DOCX (38) | 5.04 s | 0.55 s | 1441 / 14 ms | 0.93 / 1.00 | 0.81 / 1.00 | 0.78 / 1.00 |
PPTX (8) | 0.15 s | 0.02 s | 1080 / 9 ms | 0.81 / 0.97 | 0.62 / 1.00 | 0.86 / 1.00 |
XLSX (14) | 1.08 s | 0.19 s | 1085 / 11 ms | 0.60 / 0.95 | 0.78 / 0.98 | — ¹ |
HTML (32) | 0.40 s | 0.06 s | 1226 / 7 ms | 0.98 / 1.00 | 0.89 / 1.00 | 0.96 / 1.00 |
CSV (9) | 0.04 s | 0.01 s | 1086 / 6 ms | 1.00 / 1.00 | 0.78 / 1.00 | — |
EPUB (1) | 0.06 s | 0.01 s | 1278 / 14 ms | 0.99 / 1.00 | — | 1.00 / 1.00 |
PDF (18), full layout + tables + OCR | 10.0 s | 49.3 s | 1237 / 1314 ms | 0.63 / 0.997 | 0.31 / 0.94 | 0.00 / 0.91 |
PDF (18), text layer only ( | 10.0 s | 0.7 s | — | 0.63 / 0.97 | 0.31 / 0.00 | 0.00 / 0.00 |
Accuracy is scored against Python docling's groundtruth, which favours
docling.rs by construction; the timings do not depend on it. Text drawn into
images (MarkItDown's own OCR test set) reads at 1.00 with docling.rs' local
OCR, against 0.00–0.33 for MarkItDown without an LLM. Method, caveats and the full
OCR comparison: docs/MARKITDOWN.md.
Conformance with Python docling
Every declarative format is compared against the live library — Markdown
byte for byte, JSON structurally (every key and value but origin/version
and re-encoded image bytes). Latest sweep, docling 2.129.0
(scripts/conformance/full_conformance.py; ✅ all = every file matches):
Format | Files | Markdown | JSON | Format | Files | Markdown | JSON |
DOCX | 38 | ✅ all | ✅ all | iWork Pages | 1 | ✅ all | ✅ all |
HTML | 32 | ✅ all | 31 | iWork Keynote | 5 | ✅ all | ✅ all |
PPTX | 8 | ✅ all | ✅ all | EBCDIC | 3 | ✅ all | ✅ all |
XLSX | 14 | 13 ² | 13 ² | JATS | 7 | ✅ all | ✅ all |
ODF | 7 | ✅ all | ✅ all | DocLang | 15 | ✅ all | ✅ all |
CSV | 9 | ✅ all | 6 | AsciiDoc | 5 | ✅ all | ✅ all |
Markdown | 11 | ✅ all | 6 | USPTO | 9 | ✅ all | ✅ all |
DeepSeek-OCR Markdown | 3 | ✅ all | n/a | EPUB | 1 | ✅ all | ✅ all |
WebVTT | 4 | ✅ all | ✅ all | LaTeX | 8 | ✅ all | 7 ¹ |
Email ( | 2 | ✅ all | ✅ all |
¹ 1706.03762: one tabular's cells carry consistent row_span/col_span where upstream writes the span into the offsets only; PDF figures carry no image payload (upstream renders them with pypdfium2).
² xlsx_02_sample_sales_data: 20 date cells print by docling PR #4628's number-format rules (#634), which the released docling does not apply yet.
The residuals, with the exact files: docs/MIGRATION.md.
The PDF/image pipeline is pinned by a deterministic snapshot baseline and
scored against docling's groundtruth in
docs/PDF_CONFORMANCE.md.
Performance
One fixture per format through published Python docling and the Rust release
binary (scripts/test/performance.sh); docling ÷ docling.rs, so bigger means
Rust wins by more.
File | Size | Peak-memory ratio | CPU ratio | Warm-conversion speedup |
| 208 KB | 6.5× less | 0.8× | 10.6× |
| 3.1 MB | 39× less | 1.2× | 19× |
| 240 KB | 57× less | 1.3× | 47× |
| 180 KB | 59× less | 1.2× | 10× |
| 168 KB | 51× less | 0.9× | 18× |
| 80 KB | 55× less | 1.2× | 3.1× |
| 8 KB | 57× less | 1.2× | 1.2× |
| 4 KB | 64× less | 1.2× | 0.6× † |
† A 4 KB CSV converts in microseconds, so Rust's own process startup dominates its number; end to end it is 870× faster.
Declarative formats hold a few MB against docling's ~750 MB (it imports torch
even for them) and finish 300–870× sooner end to end; the PDF peaks at
0.37 GB against 2.4 GB and converts 28.5× faster end to end. Where the time
goes, and what was measured not to help:
docs/PDF_CONFORMANCE.md.
Integration — using docling.rs from your language
One engine, several front doors, the same options and outputs everywhere.
You write… | Use | Install |
Rust | the |
|
a shell / CI job | the | release binaries · |
anything that speaks HTTP |
|
|
Node.js / Bun / Electron |
|
|
Python |
|
|
the browser / Tauri / a PWA |
|
|
C, C++, C#, Go, Java, Swift, Zig |
| release archives |
Rust when you're already in Cargo; the CLI for scripts and batch jobs; serve when several services share one warm pipeline; Node / Python in-process; wasm when the document must not leave the user's machine; FFI for anything that can call C.
Rust API
use docling::{DocumentConverter, SourceDocument};
let converter = DocumentConverter::new();
let result = converter.convert(SourceDocument::from_file("input.md")?)?;
println!("{}", result.document.export_to_markdown()); // Markdown
println!("{}", result.document.export_to_json()); // docling DoclingDocument JSONEvery conversion knob is one serializable struct, docling::ConvertOptions,
filled the same way by every surface (docs/OPTIONS.md).
The library guide covers the output formats,
error handling, chunking, image extraction, streaming, OCR, the PDF switches
and the remote VLM pipeline.
HTTP conversion API — docling-rs serve
docling-serve exposes the converter over
HTTP with one warm PDF/image pipeline shared across requests (repeat PDFs skip
the model load), streamed Markdown, batches, ZIP inputs, async jobs, an
interactive test form at GET / and an OpenAPI 3.1 description at
GET /openapi.yaml. It also serves Python docling-serve's routes, so Open
WebUI, n8n, Dify and LangChain clients work unchanged.
docker run -p 127.0.0.1:5001:5001 ghcr.io/docling-project/docling-rs-serve
curl -F file=@paper.pdf localhost:5001/v1/convert # Markdown
curl -F file=@report.docx 'localhost:5001/v1/convert?to=json' # docling JSON
curl -F file=@a.pdf -F file=@b.docx localhost:5001/v1/convert # a batchRequest options, server flags, async jobs, the docling-serve routes and the
Open WebUI setup: crates/docling-serve/README.md;
containers and sizing: docs/DEPLOYMENT.md.
MCP server — docling-rs mcp
docling-rs mcp is a Model Context Protocol
server in the default docling-rs binary and image. Agents get MarkItDown's
convert_to_markdown(uri) tool — same name and contract, so a
markitdown-mcp setup switches by changing the command — plus
convert(uri, to, options) and list_input_formats().
{
"mcpServers": {
"docling": { "command": "docling-rs", "args": ["mcp", "--root", "/Users/me/Documents"] }
}
}claude mcp add docling -- docling-rs mcp --root ~/Documents # Claude Code
uvx docling-rs-mcp --root ~/Documents # the same server from PyPILocal reads stay under --root; URLs need --allow-url-fetch. Listed in the
official MCP registry
and on Smithery. The PyPI
launcher, Docker, Streamable HTTP (--http), the security model and memory
behaviour:
crates/docling-cli/README.md.
RAG subsystem
crates/docling-rag turns documents into
chunks, embeds them (Ollama, Gemini or a local ONNX model), stores them
(SQLite + sqlite-vec or PostgreSQL + pgvector) and searches them — hybrid,
multi-query and HyDE retrieval, an evaluation harness, a REST API and a
built-in search UI.
In the browser — docling-wasm
The declarative converters and the PDF text layer compile to WebAssembly:
npm i docling.rs-wasm, then convert(bytes, filename, to) runs fully
client-side — no server, a ~3.4 MB gzipped module, optional in-browser OCR.
Details and the demo page: crates/docling-wasm.
Node.js, Python and C
Node.js / Bun —
docling.rson npm, a prebuilt N-API addon: sync and async conversion, streaming, chunking, ZIP batches, a warmPipeline.Python —
docling-rson PyPI (docling-rs-cudafor NVIDIA): docling'sDocumentConverterwith a genuine docling-coreDoclingDocument, MarkItDown's API, and the LangChain and AutoGen integrations.C ABI —
docling-ffi: one library and onedocling.hfor C, C++, C#/.NET, Go, Java, Swift and Zig, prebuilt in every published release.
Deploy in a container
Image | What it is |
the HTTP API, models baked in ( | |
the CLI, entrypoint | |
| the same on CUDA 13 + cuDNN 9 ( |
Compose files (standalone, Caddy TLS, CUDA), environment variables, sizing
and observability: docs/DEPLOYMENT.md.
Getting the ML models
The PDF/image pipeline needs ONNX models — RT-DETR layout, PP-OCR, and
TableFormer — and audio needs Whisper. download_dependencies.sh fetches
them from this repository's
releases into
./.models, where every surface looks (--cli: beside a cargo-installed
binary instead):
scripts/install/download_dependencies.sh # from a checkout
curl -fsSL https://raw.githubusercontent.com/docling-project/docling.rs/master/scripts/install/download_dependencies.sh | sh # anywhereEvery asset and option (ASR presets, enrichment models, NER for PII
redaction, INT8, fonts), GPU execution providers and the environment
overrides: docs/MODELS.md. IBM Z and other targets
without a prebuilt ONNX Runtime: docs/IBMZ.md.
Contributing
Bug reports and pull requests are welcome — see CONTRIBUTING.md for the build and test commands, the conformance workflow, and the conventions a change is expected to follow.
License
MIT, matching upstream docling.
Available Tools
3 toolsconvertBRead-only
Convert a document (URI or path, as convert_to_markdown) to Markdown, docling JSON, HTML, plain text, LaTeX, RAG chunks, WebVTT or Pandoc JSON, with docling.rs's conversion options (page ranges, OCR language and mode, text-layer-only PDFs, passwords, picture OCR, …).
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Output format: md (default), json (docling's DoclingDocument), html, text, latex, chunks (RAG chunk records as JSON), vtt, pandoc (Pandoc's JSON AST). | |
| uri | Yes | The document: an http: or https: URL, a file: URI, a data: URI, or a path (relative paths resolve against the server's root). | |
| images | No | Pictures in md/html/pandoc output: placeholder (default) or embedded (data: URIs). | |
| options | No | Conversion options, docling.rs's shared set (docs/OPTIONS.md), e.g. {"pages": "1-5"}, {"text_layer_only": true} (digital PDFs, fastest), {"ocr_lang": "ch"}, {"force_full_page_ocr": true}, {"do_picture_ocr": true} (OCR pictures inside Office files), {"password": "…"}, {"compact_tables": false}. A value may also be given as text ("true", "1.5"), as a form sends it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety/scope profile is covered. The description adds useful texture beyond that – OCR modes, password-protected input, text-layer-only fast paths – which signals this is a heavyweight, potentially slow conversion. It says nothing about size limits, where output is delivered, or error behavior for unsupported formats.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence, front-loaded with verb and resource, with the format and option lists as trailing parentheticals. It is dense but every clause is relevant; the main inefficiency is that the enumerated formats largely duplicate the `to` schema, making the sentence longer than it needs to be.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with an open-ended nested `options` object (additionalProperties: true) and no output schema, the description does point to docs/OPTIONS.md and gives representative option keys, which is helpful. However, it never characterizes the return value despite the wildly different shapes (plain text, DoclingDocument JSON, chunk records, VTT), nor does it cover how the open-ended options object relates to the server's supported set.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The format list in the description essentially restates the `to` parameter's schema description, and the option examples (pages, ocr_lang, text_layer_only, do_picture_ocr, password) duplicate what the `options` schema already documents, so it adds little meaning beyond structured fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a concrete verb (Convert) plus the resource (a document given by URI or path) and enumerates the eight supported output formats, so an agent immediately knows what it does. It references convert_to_markdown for input semantics but never contrasts itself with it or with list_input_formats, so sibling differentiation is only implied.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: the '(URI or path, as convert_to_markdown)' aside hints this shares input handling with the sibling, and listing conversion options suggests it is the richer variant. There is no explicit when-to-use / when-not-to-use guidance and the sibling convert_to_markdown is never ruled in or out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
convert_to_markdownBRead-only
Convert a resource described by an http:, https:, file: or data: URI (or a local path) to Markdown — PDFs with layout analysis, table structure and OCR; Word, PowerPoint, Excel, HTML, EPUB, e-mail, images, audio and more. MarkItDown's tool of the same name.
| Name | Required | Description | Default |
|---|---|---|---|
| uri | Yes | The document: an http: or https: URL, a file: URI, a data: URI, or a path (relative paths resolve against the server's root). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so safety and network reach are covered. The description adds genuine processing context (PDF layout analysis, table structure extraction, OCR, audio and image handling) that annotations don't convey, but it says nothing about size limits, fetch/auth behavior for remote URIs, or failure modes on unsupported inputs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core verb-resource-output statement in the first clause, then a compact parenthetical covering formats. The final sentence about MarkItDown is near-filler, but the overall shape is tight and skimmable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter tool with no output schema, the essentials (input forms, output format, supported file types) are present, but the description never characterizes the returned payload or how conversion failures surface. Adequate but with clear gaps given there is no output schema to fall back on.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With a single parameter and 100% schema description coverage, the schema already documents valid URI forms and relative-path resolution against the server root. The description adds the catalogue of supported file types but no new syntax, defaults, or constraints for the 'uri' argument itself, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (convert) and resource (a document addressed by http/https/file/data URI or local path) plus the output format (Markdown), so an agent knows exactly what the tool produces. It does not, however, differentiate itself from the sibling tool 'convert', and the trailing note that it mirrors MarkItDown's tool of the same name is provenance rather than differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description lists the input kinds supported but never says when to prefer this over the sibling 'convert' or when to consult 'list_input_formats'. There is no stated exclusion, precondition, or alternative-selection rule, leaving routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_input_formatsARead-only
The input file extensions this server converts, one per line, and whether URL inputs are enabled.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint=true already covering the safety profile, the description usefully adds what the response contains ('one per line', plus a URL-input support flag) — return-content context that no output schema provides. It stops short of stating the exact response encoding.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler; the 'one per line' format detail earns its place. The trailing 'and whether URL inputs are enabled' clause is slightly indirect but not wasteful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless, annotation-covered tool with no output schema, the description adequately conveys both what is returned and its shape. A note on how URL-enabled status is expressed would make it fully self-sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline of 4 applies; there is nothing for the description to disambiguate or compensate for.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states precisely what the tool returns: the server's accepted input file extensions plus whether URL inputs are enabled. It is far more specific than a tautology, but it never distinguishes this discovery tool from the convert_to_markdown/convert siblings that consume those formats.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no mention that this should be consulted before calling convert, and no conditions or exclusions. The agent must infer that this is a pre-flight discovery call.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v2.31.0- Changed
convert1 field changed- changed
Input schema / properties / options / descriptionPrevious value: -"Conversion options, docling.rs's shared set (docs/OPTIONS.md), e.g.\n{\"pages\": \"1-5\"}, {\"text_layer_only\": true} (digital PDFs, fastest),\n{\"ocr_lang\": \"ch\"}, {\"force_full_page_ocr\": true},\n{\"do_picture_ocr\": true} (OCR pictures inside Office files),\n{\"password\": \"…\"}, {\"compact_tables\": false}."New value: +"Conversion options, docling.rs's shared set (docs/OPTIONS.md), e.g.\n{\"pages\": \"1-5\"}, {\"text_layer_only\": true} (digital PDFs, fastest),\n{\"ocr_lang\": \"ch\"}, {\"force_full_page_ocr\": true},\n{\"do_picture_ocr\": true} (OCR pictures inside Office files),\n{\"password\": \"…\"}, {\"compact_tables\": false}. A value may also be\ngiven as text (\"true\", \"1.5\"), as a form sends it."
3 tool updates
v0.1.0- First observed
convert - First observed
convert_to_markdown - First observed
list_input_formats
TDQS
Scored across 3 tools
convert_to_markdown is essentially a subset of convert, which already lists Markdown among its output formats. An agent must guess whether to use the general tool or the specialized one, and the descriptions don't clarify when to prefer each.
Names mix conventions: list_input_formats follows verb_noun, convert is a bare verb, and convert_to_markdown uses verb_to_target. They are readable but do not form a predictable pattern.
Three tools is reasonable for a focused document-conversion server, covering format discovery and conversion without bloat. It is on the lean side but each tool has a plausible role.
Input format discovery plus flexible conversion covers the core domain well. Minor gaps exist (no output-format enumeration or batch/validation helpers), but agents can work around them.
Maintenance
Related MCP Connectors
Convert PDF, Word, Excel and scanned documents to Markdown, tables and RAG chunks. OCR.
Documents to Markdown: PDF, DOCX, PPTX, XLSX, HTML. Scanned PDF pages read by AI.
Parse PDF/Word/PPT/HTML to Markdown; tables as JSON, image extraction, RAG chunking, page ranges.
Convert PDF, DOCX, HTML, and URLs to clean, LLM-ready markdown with tables preserved
Related MCP Servers
- AlicenseAqualityAmaintenanceA Model Context Protocol server that converts over 29 file formats, including PDFs, Office documents, and audio, into structured Markdown using Microsoft's MarkItDown library. It enables AI assistants to process diverse document types through single file conversion and batch directory processing.380 PyPI40MIT
- AlicenseNot gradedqualityCmaintenanceConverts documents, webpages, and media files into markdown for AI assistants using Microsoft's MarkItDown and Crawl4AI. It enables tools to read PDFs, Office files, and JavaScript-rendered websites with support for OCR and image extraction.3MIT
- FlicenseNot gradedqualityDmaintenanceConverts documents (PDF, DOCX, images, etc.) to Markdown using Microsoft's Markitdown library, with no local setup required. Integrates with AI agents via MCP for seamless document conversion.1-

Docling MCPofficial
AlicenseAqualityAmaintenanceProvides tools for document conversion, processing, and generation, enabling PDF to structured JSON conversion, document creation, and caching for improved performance.204,937 PyPI772MIT