Skip to content

MCP tools ​

anymd exposes four tools.

ToolUse it to
outlineNavigate a heading tree, without a model or API key
readTurn a file, URL, or folder into Markdown
searchFind text across files, folders, and URLs
inspectGo deeper on a PDF: render pages, crop regions, OCR, JSON structure, compare

Only source is required for read and outline; only query is required for search; inspect requires operation and sources, with further arguments needed for the chosen operation as described below. Other options can be omitted to use their defaults. Nullable options do not need an explicit null, including read's transcript, download_asr_model, images and revisions, and search's case_sensitive and whole_word. The MCP input schemas reflect this distinction so clients can validate minimal calls before sending them.

outline ​

Get the document tree before reading a long document. PDF uses bookmarks when present, otherwise the headings detected by the layout engine. Word uses headings, PowerPoint uses slides, EPUB uses its EPUB 3 TOC or EPUB 2 NCX (chapters and headings when neither is present), and HTML and Markdown use headings. A document with no headings gets unit nodes. No model, vector database, or API key is needed.

ArgumentTypeDefaultDescription
sourcestringrequiredFile path or http(s) URL
format"json" | "tree""json"Machine-readable preorder nodes or an indented tree
ocrboolean or "auto" | "vlm" | "tesseract"falseOCR image-only pages; use the same option in node reads. true inherits ANYMD_OCR; a named engine overrides it.
images"none" | "refs""none"Embedded images; use the same option in node reads
revisionsstring"markup"Word revision mode; use the same option in node reads
json
{ "source": "report.pdf", "format": "tree" }

Each node has id, title, level, from, to, start, end, children, and path. from and to are inclusive 1-based units: pages, slides, sheets or chapters. start and end are a half-open UTF-8 byte range in the canonical Markdown body (not front matter): each unit's trimmed Markdown followed by two newlines, with <!-- unit label --> and two newlines before it for PDF or multi-unit files. The canonical body uses these extraction options: no OCR or embedded images by default, and Word revision markup. Node reads use these same defaults; regular reads without node keep automatic OCR and image refs. Pass matching ocr, images, and revisions options to outline and read when changing them. Search uses the default outline extraction options. children counts immediate children; nodes are in preorder and level gives heading depth. n1 is the document root; children are n1.1, n1.1.1, and so on. IDs are deterministic for an unchanged document and extraction options, not durable identifiers across edits. A PDF bookmark resolves to its page, so bookmarks sharing a page can overlap. TOCs may omit sections; text outside a section belongs to the nearest containing node, including the root.

Read a node with { "source": "report.pdf", "node": "n1.2" }. If it stops, repeat both source and node with the returned cursor. pages intersects the node's unit range. Search hits include a node id and title path for this same navigation.

read ​

Any file, URL, or directory → Markdown.

ArgumentTypeDefaultDescription
sourcestringrequiredFile path, http(s) URL, or directory. A directory returns the list of readable files.
nodestring–Read the section id from outline; includes child sections. Unknown ids return an error.
pagesstringallPages (PDF), slides, sheets, or chapters, e.g. "1-5,8"
max_tokensnumber ≥ 50020000Token budget. Longer documents stop at a page/slide/chapter boundary and end with a cursor.
cursorstring–Continue a previous read with the cursor from its last line
ocr"auto" | "vlm" | "tesseract" | booleanautomaticLocal OCR for images and scanned PDF pages. Auto uses explicitly installed models, otherwise tesseract. No automatic downloads. false disables; true enables the default runtime (ANYMD_OCR when set). See local OCR.
revisions"markup" | "accept" | "reject""markup"Word tracked changes and comments. markup writes them as CriticMarkup with each change's author and date; accept or reject gives the text with every change accepted or rejected, without comments (see Word). A document with no tracked changes and no comments reads the same either way.
images"refs" | "none""refs"Images embedded in PDFs, DOCX, PPTX and EPUB files. refs saves each meaningful raster image to the anymd cache and marks it in the Markdown (see Embedded images); none leaves images out.
transcriptbooleanfalseTranscribe audio/video with bundled Qwen3-ASR
download_asr_modelbooleanfalseImplies transcript; downloads Qwen3-ASR-1.7B Q8 weights (2.19 GB, SHA-256 verified) into the anymd cache when none is installed
json
{ "source": "papers/attention.pdf" }
markdown
---
source: papers/attention.pdf
title: Attention Is All You Need
pages: 15
showing: pages 1-9
---

<!-- page 1 -->

# Attention Is All You Need
…

<!-- page 8 -->

|Model|BLEU EN-DE|BLEU EN-FR|
|-|-|-|
|Transformer (big)|28.4|41.8|
…

<!-- Stopped at the 20000-token budget. Continue with cursor: "10", or pick pages, or raise max_tokens. -->

Scanned pages ​

A PDF page with no text layer that images cover is a scan. When OCR does not read it (not configured, or ocr: false), read says so instead of returning an empty page. The page marker explains how to enable local OCR: run anymd setup ocr to opt into downloading the OCR engine and ~2 GB of model weights, then retry with ocr: true. Documents stay on your machine; setting ocr: true alone does not download models. The front matter lists scanned_pages: [3, 5] (page numbers shown in this response), and when every page shown is a scan the body opens with the same guidance. Pages with text are unchanged, and a page that OCR reads gets no marker.

Cursor and pagination ​

When a document is larger than max_tokens, read stops at a unit boundary (a page, slide, sheet, or chapter) and its last line names the cursor to continue from. Pass it back unchanged:

json
{ "source": "papers/attention.pdf", "cursor": "10" }

A cursor is "<page>" or, when a single page was larger than the whole budget and had to be split, "<page>:<offset>". You can also skip the cursor and ask for exactly what you need with pages, or raise max_tokens.

Folders and URLs ​

read on a directory lists the readable files in it, so the agent can pick one or search them all. read on a web URL returns the main article only; see Formats.

Find text across files, directories, and URLs, one line per hit.

ArgumentTypeDefaultDescription
querystringrequiredText to find
sourcesstring[]current directoryFiles, directories (searched recursively, .gitignore respected), or URLs. Up to 256.
modestringautoauto: exact phrase, falling back to ranked passages when nothing matches. literal: exact phrase only. ranked: BM25 over the query words.
globstring–Only files matching this glob inside directories, e.g. "*.pdf" or "reports/**"
case_sensitivebooleanfalseMatch case
whole_wordbooleanfalseMatch whole words
max_resultsnumber 1–50020Maximum hits
context_charsnumber 0–100080Snippet context on each side
json
{ "query": "masked language model", "sources": ["papers/"] }
markdown
5 matches for "masked language model" (2 files, 31 sections searched)

### papers/bert.pdf (5)
- p.1: …by using a “**masked language model**” (MLM) pre-training objective, inspired by the Cloze task…
- p.2: …In addition to the **masked language model**, we also use a “next sentence prediction” task…

In auto mode, a question like "how does bidirectional pretraining work" that matches nothing exactly still finds the right page through BM25-ranked passages.

inspect ​

Go deeper on a PDF. inspect returns JSON, for the cases where an agent needs geometry, images, or a diff rather than prose.

operationWhat it does
cite_check(anymd Pro) Check a quoted passage at a page and bounding box, without a model or truth claim
inspectPage count, metadata, and per-page facts
render_pageRender pages to PNG images
extract_regionsCrop regions (bounding boxes) out of rendered pages
ocr_pagesOCR pages with the local OCR provider
analyze_regionsSend regions to a configured vision/region provider
structureStructured JSON read: document map, elements, geometry, tables, and reports
comparePage-level text diff between two local PDFs (sources[0] = before, sources[1] = after)
ArgumentTypeDescription
operationstringOne of the operations above (required)
sourcesobject[]{ path | url, pages?, regions? } per PDF. A region is { page, bounding_box: { left, bottom, right, top }, padding? }.
profilestringstructure only: fast (default), quality, or research (adds safety, trust, and accessibility reports)
scalenumber 0.25–4Render scale for render_page / extract_regions
max_pagesnumber 1–20Page cap for rendering and OCR
max_regionsnumber 1–100Region cap
max_pixels_per_pagenumberPixel cap per rendered page
include_imagebooleanInclude the rendered PNG in the response
ocr"auto" | "vlm" | "tesseract"Engine for ocr_pages; omit to use the configured command provider.
languagesstring[]Tesseract OCR languages, e.g. ["eng", "chi_tra"]; doc-VLM detects the language.
timeout_msnumberTime limit for external tools (1,000–300,000)
max_output_charsnumberOutput cap (1,000–1,000,000)

Render page 3 at 2×:

json
{ "operation": "render_page", "sources": [{ "path": "report.pdf", "pages": [3] }], "scale": 2 }

Get the structured JSON (elements with bounding boxes, tables, outline):

json
{ "operation": "structure", "sources": [{ "path": "report.pdf" }], "profile": "quality" }

Diff two versions:

json
{ "operation": "compare", "sources": [{ "path": "contract-v1.pdf" }, { "path": "contract-v2.pdf" }] }