Skip to main content
Glama

all2md

Read, convert, search, and chunk PDFs, Office files, e-books, emails, and 40+ other formats, as Markdown and back again. From Python, from your terminal, or from your AI assistant.

PyPI version Python Versions CI codecov Documentation License uv Ruff Checked with mypy Downloads MCP server GitHub Action

Try it in ten seconds

With uv there is nothing to install first:

uvx --from "all2md[all]" rcat report.pdf          # read any document in the terminal
uvx --from "all2md[all]" all2md report.docx       # print it as Markdown

Keep it around as a tool, with all2md, rcat and the all2md-mcp server on your PATH:

uv tool install "all2md[all]"

Or use it as a library:

uv add "all2md[pdf,docx]"      # or: pip install "all2md[pdf,docx]"
from all2md import to_markdown

markdown = to_markdown("report.pdf")

Related MCP server: document-converter-mcp

Pick your path

I want to…

Start with

Read

Read documents without leaving the terminal

rcat report.docx, all2md read docs/

Read in the terminal

Convert files, one or a thousand, in either direction

all2md ./inbox -r --output-dir ./md

Convert

Parse documents in my Python code

to_markdown("report.pdf")

Python API

Find text inside PDFs, Word files and slide decks

all2md grep "deadline" contracts/ -r

Search

Feed documents to a RAG pipeline

all2md chunk handbook.pdf

RAG and chunking

Let Claude or another assistant work with my files

the one-click Claude Desktop extension

AI assistants (MCP)

Know how far to trust the output

all2md report scan.pdf

Measured fidelity

Read documents in your terminal

rcat is cat for documents. It renders PDFs, Word and PowerPoint files (the 97-2003 .doc and .ppt too), spreadsheets, e-books, emails, notebooks, man pages and every other format all2md reads, with headings, tables, syntax-highlighted code, links with their targets, footnotes, math and admonitions. No browser, no office suite, and it works over SSH. If you reach for glow to read Markdown or doxx to read Word files, rcat is the same idea for every format.

rcat report.docx                              # read a Word document
rcat deck.pptx --outline                      # just the slide titles
rcat handbook.pdf --extract "Installation"    # one section, by heading
rcat contract.pdf --pager                     # page through it
curl -sL https://example.com/spec.pdf | rcat -

For anything longer, all2md read (or rcat -i) opens the interactive viewer shown above: an outline beside the text, jumps between headings, the links on screen, and, given a folder, a tree of the documents in it.

all2md read handbook.pdf
all2md read docs/            # choose from the documents in a folder

When you would rather have a browser, all2md view report.docx opens a styled HTML preview, all2md view ./docs -r browses a whole folder with on-demand conversion, and all2md edit notes.md opens a browser editor that saves back to the file.

Styling needs the cli_extras extra and the viewer needs tui; all2md[all] includes both. More in the viewer documentation.

Convert documents from the command line

Any supported format to Markdown, and Markdown back to DOCX, PDF, PPTX, HTML, EPUB and more:

all2md report.pdf > report.md                     # to Markdown on stdout
all2md answer.md --out answer.docx                # Markdown (an LLM's output, say) to Word
all2md ./inbox -r --output-dir ./markdown -p 4    # a whole tree, four at a time
all2md ./inbox -r --output-dir ./markdown --watch # keep converting as files arrive
all2md scan.pdf --pdf-ocr-enabled                 # scanned pages, through OCR

Every option of every converter is a CLI flag (all2md --help) or a key in a config file (all2md config generate). Every file command reads stdin and writes stdout with -, so all2md slots into pipelines. Word documents come out as Word shows them: tracked changes resolved by policy, comments with their anchors, footnotes, field results, merged cells, and the list numbers Word actually prints.

See the CLI reference and the cheat sheet.

Python API

to_markdown() handles the common case; convert() goes between any two formats; to_ast() gives you the parsed document to work with.

from all2md import to_markdown, convert, to_ast, from_ast

markdown = to_markdown("report.pdf", pages="1-3", flavor="gfm")
convert("notes.md", "notes.docx", target_format="docx")

doc = to_ast("report.docx")          # a typed document tree
html = from_ast(doc, target_format="html")

The core has no dependencies; each format's extra pulls in only what that format needs. Options are typed dataclasses (PdfOptions, DocxOptions, …) or plain keyword arguments, and AST transforms (remove-images, heading-offset, your own) slot in between parsing and rendering. New formats and transforms plug in through entry points.

If you are an LLM with a coding environment, all2md llm-help prints usage guidance written for you, and all2md install-skills installs it as a skill for Claude Code, Cursor and others.

See the Python API guide, the AST guide, and examples/python.

Search inside any document

grep doesn't look inside a PDF or a .docx. all2md grep does, across any mix of formats, with the usual flags:

all2md grep -i "termination" contracts/ -r            # every format in the tree
all2md grep -C 2 "deadline" contracts/ -r --rich      # with context, highlighted
all2md search "renewal terms" ./contracts --keyword   # ranked BM25 search
all2md search "who approved the budget" ./minutes --hybrid
all2md diff draft-v1.docx draft-v2.pdf                # a colored diff, across formats

Vector and hybrid search need the search extra. Add --cache (or ALL2MD_CACHE=1) to reuse parsed documents across repeated runs.

RAG and chunking

all2md chunk converts and splits in one step. Each chunk carries its section heading and source page span, so answers can cite where they came from.

all2md chunk handbook.pdf --strategy semantic --max-tokens 512 --overlap 64 > chunks.jsonl
import all2md

for c in all2md.chunk("handbook.pdf", strategy="semantic", max_tokens=512, overlap=64):
    print(c.chunk_id, c.section_heading, c.page, c.token_count)

There are 11 strategies (semantic, heading, section, token, sentence, paragraph, code, …). Tables and code blocks are kept whole, and the output is JSONL ready for any vector store. Real token counts use tiktoken from the chunk extra. See the chunk command.

Give your AI assistant your documents

all2md ships a Model Context Protocol server, so an assistant like Claude can read your PDFs and Office files, write Word documents, edit them in place, search a folder, and compare two versions. You don't need to write any code.

In Claude Desktop (no Python or terminal needed):

  1. Download all2md.mcpb from the latest release.

  2. Open Claude Desktop → Settings → Extensions and drag the file onto the page.

  3. Choose the folder all2md may work in, and whether it may write files.

  4. Ask Claude about the documents in that folder.

The server is in the MCP Registry as io.github.thomas-villani/all2md. To run it yourself, use uvx (nothing to install):

{
  "mcpServers": {
    "all2md": {
      "command": "uvx",
      "args": ["--from", "all2md[all]", "all2md-mcp", "--temp", "--enable-from-md"]
    }
  }
}

or install it with uv tool install "all2md[mcp]" and use "command": "all2md-mcp". The [mcp] extra covers PDF, Word, PowerPoint, Excel, HTML, EPUB, ODF and reStructuredText; use [all] for everything.

Tools: read_document_as_markdown, save_document_from_markdown, edit_document, plus the read-only search_documents, diff_documents and get_document_outline.

See the MCP documentation for the options and the security model.

Measured fidelity

all2md's conversion quality is measured against independent ground truth, not asserted. Each benchmark lane is published with a control that shows what the measurement looks like when it should fail:

  • Born-digital PDFs: publisher PDFs from PubMed Central, scored against the JATS XML deposited beside them.

  • Scanned pages: 981 OmniDocBench pages against human annotation, for the OCR path.

  • Round trips: Markdown → format → Markdown must hold fidelity 100 for this repository's own docs, on every pull request.

Against other converters, on a sealed holdout of 103 PubMed Central articles scored with the same instruments (reading of 2026-08-29):

all2md

pymupdf4llm 1.28.2

Docling 2.120.3

Recall of attainable text

97.3%

97.1%

96.2%

Invented text (lower is better)

0.55%

6.26%

2.05%

Table text preserved

73.1%

60.7%

79.3%

Docling's learned table model still leads on tables. The comparison lane has the full results, the ground rules, and the caveats that bound them. Conversion Fidelity has the rest.

You can measure your own documents the same way:

all2md report scan.pdf                        # a reference-free "quality card"
all2md roundtrip notes.md --via docx          # convert, parse back, score what survived
all2md optimize hard.pdf --sample-pages 5     # auto-tune the settings for a difficult file

CI quality gate

The same scores run as a GitHub Action, which fails the build when your documents stop converting cleanly:

- uses: thomas-villani/all2md@v1.19.0
  with:
    paths: docs/**/*.md
    roundtrip-fail-under: 97

It fails rather than passing quietly when no files match, no threshold is set, or a document cannot be converted at all, and it warns when a threshold sits so far below your real floor that it could never fire. See the action's documentation.

Supported formats

  • Documents: PDF, DOCX, DOC, PPTX, PPT, ODT, ODP, RTF, EPUB, FB2, CHM

  • Web & markup: HTML, MHTML, Markdown, reStructuredText, AsciiDoc, Org-Mode, LaTeX, MediaWiki, Textile, DokuWiki, BBCode, man pages

  • Data & spreadsheets: XLSX, ODS, CSV/TSV, JSON, YAML, TOML, INI, OpenAPI/Swagger

  • Email: EML, MBOX, Outlook (MSG/PST/OST), Evernote (ENEX)

  • Notebooks & code: Jupyter, plus nearly 200 source-code and config file types

  • Archives: ZIP, TAR, 7Z, RAR and more; .gz, .bz2 and .xz convert as the file they hold

  • Custom output: any text format through Jinja2 templates

Format

File Extensions

Input (Parse)

Output (Render)

Dependencies Extra

PDF

.pdf

✅

✅

pdf, pdf_render

Word Document

.docx

✅

✅

docx

Word 97-2003 Document

.doc, .dot

✅

(N/A)

(built-in)

PowerPoint Presentation

.pptx

✅

✅

pptx

PowerPoint 97-2003

.ppt, .pps, .pot

✅

(N/A)

(built-in)

HTML

.html, .htm

✅

✅

html

MHTML Web Archive

.mhtml, .mht

✅

(N/A)

html

Email Message

.eml

✅

(N/A)

(built-in)

MBOX Mailbox Archive

.mbox, .mbx

✅

(N/A)

(built-in)

Outlook Message/Archive

.msg, .pst, .ost

✅

(N/A)

outlook

Jupyter Notebook

.ipynb

✅

✅

(built-in)

EPUB E-book

.epub

✅

✅

epub

FictionBook 2.0 (FB2)

.fb2

✅

(N/A)

fb2

CHM (Compiled HTML Help)

.chm

✅

(N/A)

chm

OpenDocument Text

.odt

✅

✅

odf

OpenDocument Presentation

.odp

✅

✅

odf

OpenDocument Spreadsheet

.ods

✅

(N/A)

odf

Excel Spreadsheet

.xlsx

✅

(N/A)

xlsx

CSV / TSV

.csv, .tsv

✅

✅

(built-in)

Rich Text Format

.rtf

✅

✅

rtf

LaTeX

.tex, .latex

✅

✅

latex

AsciiDoc

.adoc, .asciidoc, .asc

✅

✅

(built-in)

reStructuredText

.rst

✅

✅

rst

Org-Mode

.org

✅

✅

org

MediaWiki

.wiki, .mw

✅

✅

wiki

Textile

.textile

✅

✅

(built-in)

BBCode

.bbcode, .bb

✅

(N/A)

(built-in)

DokuWiki

.doku, .dokuwiki

✅

✅

(built-in)

Man Page (man(7))

.1 to .9, .man

✅

✅

(built-in)

Evernote Export

.enex

✅

(N/A)

enex

Safari Web Archive

.webarchive

✅

(N/A)

html

JSON

.json

✅

✅

(built-in)

YAML

.yaml, .yml

✅

✅

(built-in)

TOML

.toml

✅

✅

(built-in)

INI / Config

.ini, .cfg, .conf

✅

✅

(built-in)

OpenAPI/Swagger

.yaml, .yml, .json

✅

(N/A)

openapi

Plain Text

.txt, .text

✅

✅

(built-in)

Source Code

nearly 200 extensions (.py, .js, etc.)

✅

(N/A)

(built-in)

Archive Formats

.tar, .tgz, .7z, .rar, etc.

✅

(N/A)

(built-in)

Single Compressed File

.gz, .bz2, .xz (e.g. ls.1.gz)

✅

(N/A)

(built-in)

ZIP Archive

.zip

✅

(N/A)

(built-in)

Jinja2 Templates (Custom)

User-defined (.jinja2, .j2)

❌

✅

jinja2

Run all2md list-formats to see what your install supports, or browse the formats documentation.

Installation

You are…

Install

Using the CLI and viewer

uv tool install "all2md[all]"

Trying it once

uvx --from "all2md[all]" rcat FILE

Building with the library

uv add "all2md[pdf,docx,html]" or pip install "all2md[pdf,docx,html]"

Running the MCP server

the Claude Desktop extension above, or uv tool install "all2md[mcp]"

all2md check-deps shows which formats your install can handle.

Install scripts. These set up uv (installing it if needed) and install the CLI globally with the all extra.

# macOS / Linux
curl -LsSf https://raw.githubusercontent.com/thomas-villani/all2md/main/scripts/install.sh | sh
# Windows (PowerShell)
powershell -ExecutionPolicy Bypass -c "irm https://raw.githubusercontent.com/thomas-villani/all2md/main/scripts/install.ps1 | iex"

To slim it down, download the script and pass the extras you want: sh install.sh pdf,docx,html or .\install.ps1 -Extras pdf,docx,html.

Extras for specific needs:

uv add "all2md[cli_extras]"     # terminal styling for --rich / rcat, progress bars, watch mode
uv add "all2md[tui]"            # the interactive viewer, all2md read
uv add "all2md[pdf,ocr]"        # OCR for scanned PDFs (Tesseract; needs the system binary)
uv add "all2md[pdf,ocr-easyocr]" # ...or binary-free EasyOCR (downloads models on first use)
uv add "all2md[pdf_layout]"     # ML layout analysis for difficult PDFs
uv add "all2md[search]"         # vector and hybrid search
uv add "all2md[chunk]"          # real token counts for chunking
uv add "all2md[outlook]"        # Outlook MSG (PST/OST also need: pip install libpff-python)

See the installation guide for the full list.

FAQ

How is all2md different from Pandoc? all2md is Python-native and built for programmatic use, LLM pipelines and reading documents in the terminal. Pandoc has more publishing breadth and scholarly features such as citations. They complement each other well.

Does it work with scanned PDFs? Yes. Install all2md[pdf,ocr] (or ocr-easyocr for no system binary) and pass --pdf-ocr-enabled. all2md report tells you when a PDF has no text layer.

Can I output something other than Markdown? Yes: DOCX, PDF, PPTX, HTML, EPUB, ODT, RST, LaTeX and more, or any text format through Jinja2 templates.

How do I add a format? Write a parser, describe it with ConverterMetadata, and register it under the all2md.converters entry point. See examples/plugins.

Contributing

Bug reports, feature requests, docs and code are all welcome. See CONTRIBUTING.md for the development setup. Parser changes are judged against the benchmark lanes; see Conversion Fidelity.

Questions and bugs go to GitHub Issues. Full documentation is on Read the Docs.

License

MIT. See LICENSE.

Available Tools

5 tools
diff_documentsA

Compare two documents and return their differences.

Each input is auto-detected (file path, data URI, base64, or inline content), so documents in any supported format can be compared — even across formats (e.g. a DOCX against its PDF export).

Returns a dictionary with:

  • diff: the rendered diff (unified text or JSON string)

  • has_changes: whether any differences were found

NameRequiredDescriptionDefault
newYesUpdated document: file path (within read allowlist), data URI, base64, or inline content. REQUIRED.
oldYesOriginal document: file path (within read allowlist), data URI, base64, or inline content. REQUIRED.
formatNoOutput format: 'unified' (default, plain text) or 'json' (structured).unified
granularityNoComparison granularity: 'block' (default), 'sentence', or 'word'.block
context_linesNoContext lines around changes in unified output (default: 3).
ignore_whitespaceNoNormalize whitespace before comparing. Default: false.

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are supplied, so the description carries the disclosure burden. It does add real context — inputs are auto-detected from path, data URI, base64, or inline content, and the comparison works across formats — but it says nothing about error behavior for unsupported formats, read-allowlist failures, size limits, or cost of large comparisons.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action in one sentence, then a compact bullet list for the return value. The 'Returns a dictionary with' block partly duplicates the existing output schema, which costs some space, but nothing is padded or verbose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given a six-parameter tool with an output schema, the description covers input flexibility, cross-format support, and the shape of the result. Remaining gaps (failure modes for unsupported or oversized documents) are modest for a read-only comparison operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every parameter is already documented in the schema; baseline 3 applies. The description adds only the input auto-detection idea and does not elaborate on format, granularity, context_lines, or ignore_whitespace beyond what the schema states.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Compare two documents and return their differences') plus a notable capability: cross-format comparison such as DOCX vs its PDF export. It is clearly distinct from the siblings (read_document_as_markdown, search_documents, get_document_outline, list_workspace_files), though it never explicitly names an alternative.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied by the purpose — an agent infers that this is the tool for 'are these two documents different' questions. There is no explicit when-to-use/when-not guidance, no statement about prerequisites, and no routing advice versus the read/search/outline siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_document_outlineA

Return the heading structure (table of contents) of a document.

Use this to navigate a large document before extracting specific sections: the returned indices line up with edit_document's '#N' target notation.

Returns a dictionary with:

  • sections: list of {index, level, heading}

  • total: number of headings returned

NameRequiredDescriptionDefault
docYesDocument to outline: file path (within read allowlist), data URI, base64, or inline content. REQUIRED.
max_levelNoDeepest heading level to include, 1-6 (default: 6 = all levels).
format_hintNoOptional format hint for ambiguous/extensionless sources (e.g. 'pdf', 'docx', 'html').

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are supplied, so the description carries the burden and does disclose one non-obvious behavioral trait: returned indices line up with edit_document's '#N' addressing, which is not inferable from the schema. It is silent on failure behavior for unsupported formats or size limits, and the return-value section partly duplicates the existing output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, then usage, then return shape in a scannable list; no filler sentences. The 'Returns a dictionary with' block is somewhat redundant against the declared output schema, costing a point on tightness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 3-parameter read tool with full schema coverage and an output schema, the description covers purpose, navigation use case, and cross-tool index semantics. Remaining gaps are minor: no note on unsupported formats or how errors surface.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so doc, max_level, and format_hint are already well documented in the input schema. The description adds no parameter-level meaning (e.g., when to set format_hint or how max_level affects indices), so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a concrete verb and resource: 'Return the heading structure (table of contents) of a document.' The parenthetical clarifies the concept and the follow-up sentence scopes it to navigation of large documents, which separates it from read_document_as_markdown (full content) and search_documents (query match) without needing the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use: 'navigate a large document before extracting specific sections,' and it points at a downstream consumer (edit_document's '#N' notation). It stops short of naming an alternative sibling or a case where this tool is the wrong choice, so it is clear context without explicit exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_workspace_filesA

List files the server is allowed to read.

Use this to discover what is available before reading or editing. Results are confined to the read allowlist (the workspace folder plus any additional read-only folders). Paths returned here can be passed directly to the other tools.

Returns a dictionary with:

  • files: list of {path, size_bytes} (absolute paths, sorted)

  • total: number of files returned

  • truncated: true if more files exist than were returned (capped)

  • read_dirs: the read folders that were searched

NameRequiredDescriptionDefault
patternNoOptional glob filter on file names, e.g. '*.pdf' or '*.docx'. Default: all files.
recursiveNoRecurse into subdirectories. Default: true.
subdirectoryNoOptional workspace-relative subdirectory to list. If omitted, all read folders are listed.

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses the read-allowlist confinement, that results are absolute and sorted, and that output can be capped via a truncation flag. It omits whether hidden files are included and says nothing about permissions or performance on large trees, so it is strong but not exhaustive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the scope constraint, then a usage sentence, then a bulleted return shape — clean and skimmable with no filler. The return-value block is duplicated by the existing output schema, so a chunk of the text is redundant rather than earning its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-required-parameter listing tool this covers the essentials: scope, purpose, allowed follow-up use, and truncation behavior. Since an output schema already exists, the enumerated return fields are surplus, and the description never explains how narrowing by subdirectory or pattern changes the result set.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so pattern, recursive, and subdirectory are already fully documented with defaults and examples. The description adds no meaning beyond the schema for any of the three parameters, which is the baseline case rather than a value-add.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence states a specific verb and resource (list files) plus the governing scope (the read allowlist), and the follow-up frames it as the discovery step preceding reading/editing. That framing makes it immediately distinguishable from read_document_as_markdown and search_documents without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Use this to discover what is available before reading or editing" gives clear sequencing guidance, and "Paths returned here can be passed directly to the other tools" tells the agent how output feeds siblings. It does not explicitly say when to prefer search_documents over listing (e.g., known filename vs known content), so a small gap remains.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_document_as_markdownA

Read a document and convert it to Markdown format (simplified API).

Supports PDF, Word (DOCX), PowerPoint (PPTX), HTML, email (EML), EPUB, Jupyter Notebooks (IPYNB), Excel (XLSX/CSV), ODF formats, and 200+ text formats.

The source parameter is auto-detected as:

  • File path (if file exists in read allowlist)

  • Data URI (data:image/...)

  • Base64-encoded content (auto-detected)

  • Plain text content (HTML, Markdown, etc.)

Optionally extract a specific section by providing the section parameter with a heading name (case-insensitive match).

Image inclusion and markdown flavor are configured at server startup and cannot be changed per-call.

Returns the Markdown as a text content block, followed by an image content block for each image found (when include_images=true), so vision models can see the images alongside the text. When include_images=false, only the text, with image alt text in place of the images.

NameRequiredDescriptionDefault
sourceYesUnified source parameter. Auto-detected as: file path (if exists in read allowlist), data URI (data:...), base64 string, or plain text content. REQUIRED.
sectionNoOptional section name to extract (case-insensitive heading match). If provided, only that section is returned.
pdf_pagesNoPage specification for PDF sources only. Examples: '1-3' (pages 1-3), '1,3,5' (specific pages), '1-3,5,10-' (ranges and individual pages), '1-' (from page 1 to end).
format_hintNoOptional format hint for ambiguous cases (e.g., extensionless files). Options: auto (default), pdf, docx, pptx, html, eml, epub, ipynb, odt, odp, ods, xlsx, csv, rst, markdown, txt.

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations supplied, the description carries the full burden and does well: it discloses the read-allowlist constraint on file paths, that image inclusion and markdown flavor are fixed at server startup and cannot be changed per call, and that section matching is case-insensitive. It also describes the response shape (a text content block followed by one image block per image, or alt-text placeholders when include_images=false), which no output schema covers. Only error behavior and size/rate limits are unaddressed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose, then formats, then source detection, then optional behaviors, then return shape — a sensible ordering for an agent scanning it. The long format enumeration and the repeated source auto-detection list (already in the schema) are the main slack, but they remain short and skimmable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a four-parameter read tool with no annotations and no output schema, the definition covers input handling, configuration constraints, and return structure, which is enough to invoke it correctly. The only meaningful omission is what happens on failure (unreadable file, unsupported format, no matching section).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all four parameters are already documented, and the description largely restates the source auto-detection rules and the section heading match. It adds no meaning for pdf_pages or format_hint, which live entirely in the schema, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Read a document and convert it to Markdown format') plus the full set of supported input formats, so the agent knows exactly what the tool produces. It does not explicitly contrast itself with the closest sibling, get_document_outline, which returns structure rather than full content, so an agent must infer that boundary.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than stated: the description says you may 'optionally extract a specific section' and explains how the source is auto-detected, which guides parameter choice. It never says when to prefer this over search_documents, diff_documents, or get_document_outline, and gives no exclusions or prerequisites beyond the read-allowlist note.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_documentsA

Search a corpus of documents and return ranked snippets.

Instead of returning whole files, this tool returns the most relevant passages (with hit spans wrapped in << >> markers), so an agent can locate information across many documents cheaply.

Modes:

  • keyword: BM25 relevance ranking (requires the optional rank-bm25 dependency). Best for "find the most relevant passages" queries.

  • grep: literal/regex line matching. Best for "find every occurrence of X". Stateless, no extra dependencies.

Supports all formats the read tool supports (PDF, DOCX, HTML, etc.); files are converted to text before searching.

Returns a dictionary with:

  • results: list of {snippet, score, document_path, section_heading, chunk_id}

  • mode: the search mode used

  • total: number of results returned

NameRequiredDescriptionDefault
modeNoSearch mode: 'keyword' (default, BM25 relevance ranking) or 'grep' (literal/regex line matching).keyword
pathsNoFiles, directories, or globs to search (each must be within the read allowlist). If omitted, the server's read allowlist is searched.
queryYesSearch query. Natural language for keyword mode; a literal string (or regex) for grep mode. REQUIRED.
regexNoTreat the query as a regular expression (grep mode only). Default: false.
top_kNoMaximum number of results to return (default: 10).
recursiveNoRecurse into directories when collecting input files. Default: true.
ignore_caseNoCase-insensitive matching (grep mode only). Default: false.

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses that keyword mode needs the optional rank-bm25 dependency, that grep is stateless, that files are converted to text first, and that hit spans are marked with << >>. It omits permission/allowlist behavior (only in the schema) and any performance or size limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose then structured into modes and return shape; every section is scannable. The return dictionary listing is partly redundant given an output schema exists, which costs a bit of tightness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers purpose, mode tradeoffs, format support, and conversion behavior for a 7-parameter search tool. Because an output schema exists, the return-value enumeration is unnecessary, and allowlist scoping is left entirely to the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 description corroborates mode semantics and the format support, but adds little parameter meaning beyond what the schema already documents for paths, regex, top_k, and recursive.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('search a corpus of documents and return ranked snippets') and immediately contrasts it with the sibling read tool by explaining it returns passages rather than whole files. An agent can distinguish it from read_document_as_markdown without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use guidance for each mode: keyword for 'find the most relevant passages', grep for 'find every occurrence of X'. It does not explicitly say when to prefer this over list_workspace_files or when a direct read is better, but the mode routing is clear.

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. 5 tool updatesv1.19.0
    • First observeddiff_documents
    • First observedget_document_outline
    • First observedlist_workspace_files
    • First observedread_document_as_markdown
    • First observedsearch_documents

TDQS

A3.9/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: full/section conversion, corpus search, document diffing, heading outline extraction, and workspace listing. Overlap between read_document_as_markdown and get_document_outline is limited to section navigation, but their outputs and use cases are clearly differentiated.

Naming Consistency5/5

All tool names use snake_case and begin with a verb-like action, e.g. read_document_as_markdown, search_documents, diff_documents, get_document_outline, and list_workspace_files. The phrasing is predictable and easy to scan.

Tool Count5/5

Five tools is well-scoped for a document reading/search/diff/outline surface. Each tool covers a meaningful operation without excessive fragmentation.

Completeness3/5

The set covers reading, searching, diffing, outlining, and file discovery, but get_document_outline explicitly references an edit_document tool that is not present. This creates a notable dead end for editing/navigation workflows, and there is no write/save or edit operation on the surface.

Maintenance

ActivityActive
ResponsivenessLimited data

Related MCP Connectors

Related MCP Servers