doc2md
This server turns documents (PDF, DOCX, PPTX, XLSX, EPUB, HTML, CSV/JSON/XML, images/scans) into clean Markdown or structured data, and provides utilities for inspecting, searching, splitting, merging, and extracting content from PDFs.
Convert PDFs to Markdown with headings, tables, lists, and pagination (
offset/max_chars, page selection).Convert many formats in one call (DOCX, PPTX, XLSX, EPUB, HTML, CSV, PDF, etc.), including OCR fallback for scanned PDFs and images.
Extract PDF tables as Markdown, CSV, or JSON with page numbers and dimensions.
Read plain text from specific PDF pages cheaply.
Get document info: format, page count, metadata, table of contents, scanned/encrypted flags.
Full-text search PDFs with page numbers and snippets.
OCR scanned PDFs and images (PNG/JPEG/WebP/BMP/TIFF), up to 30 pages per call.
Split PDFs into parts by page ranges and return base64 parts.
Merge 2–10 PDFs (URLs or base64) into one PDF.
Extract embedded PDF images with metadata, optionally as base64.
Accept input via public URL or base64 content, with SSRF protection, size caps, and no persistence.
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 filesTables survive — PDF tables are extracted as Markdown/CSV/JSON, not flattened into noise
Pagination built in — large documents return in chunks with a
offsetcontinuation hint, so context windows stay healthyScanned? No problem — automatic detection, with a dedicated OCR tool (RapidOCR, offline, no cloud OCR API)
Cheap inspection first —
get_document_infoandsearch_documentlet agents find the right pages before converting anythingSafe to expose — SSRF protection (private/loopback/link-local IPs rejected on every redirect hop), 30 MB download cap, password-PDF support
Related MCP server: groupdocs-markdown-mcp
Tools
Tool | What it does |
| PDF → Markdown with headings, tables, lists and reading order preserved. |
| 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. |
| Structural table extraction → |
| Plain text of specific pages — the cheapest way to read a known location. |
| Format, page count, metadata, table of contents, scanned/encrypted flags. |
| Full-text keyword search with page numbers + snippets. |
| OCR for scanned PDFs and images (PNG/JPEG/WebP/BMP/TIFF), up to 30 pages per call. |
| Cut a PDF into parts by page range ( |
| Merge 2–10 PDFs (URLs or base64) into one document, returned as base64 (≤10 MB). |
| 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 run --rm -i ghcr.io/skyzhao1223/doc2md # stdio
docker run --rm -p 8000:8000 \
-e DOC2MD_TRANSPORT=streamable-http ghcr.io/skyzhao1223/doc2md # HTTP endpoint
# or build from source
docker build -t doc2md . && docker run --rm -i doc2mdFrom 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 suiteExample 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 pagesLimits
Limit | Value |
Download / base64 size | 30 MB |
Default response size | 40,000 chars (max 200,000), with |
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) orstreamable-http/ssewithDOC2MD_HOST/DOC2MD_PORT. Glama hosting wraps stdio automatically.OCR is optional: install the
ocrextra (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 testsLayout: 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_pdfsutility tools (v0.2.0)Image extraction via
extract_pdf_imageswith base64 export (v0.2.0)PyPI release:
doc2md-mcp(v0.2.0)Batch/webhook conversion jobs for very large documents
Available Tools
10 toolsconvert_document_to_markdownARead-onlyIdempotent
Convert almost any document to Markdown in one call: DOCX, PPTX, XLSX, EPUB, HTML, CSV/JSON/XML/TXT and PDF are auto-detected from the URL or base64 content. This is the universal 'just give me the text' tool — use it when the file format is unknown or mixed.
Images and scanned PDFs are routed to OCR automatically when the server
has OCR installed. Legacy .doc/.xls/.ppt binaries are not supported.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | Public http(s) URL of the document to fetch and convert. Leave empty when passing file_base64 instead. | |
| pages | No | 1-based page selection like '1,3-5'. Empty means all pages. | |
| offset | No | Character offset to resume a truncated conversion. | |
| filename | No | Original filename with extension (e.g. 'report.docx'). Used as a format hint when content type cannot be detected automatically. | |
| password | No | Password for encrypted PDFs. Empty for normal files. | |
| max_chars | No | Maximum characters to return (default 40000, max 200000). | |
| file_base64 | No | Base64-encoded file content (for documents not reachable by URL). Decoded size limit: 30 MB. Leave empty when passing url instead. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already signal read-only, idempotent, non-destructive behavior, so the description adds useful extra context without contradiction. It discloses auto-detection from URL or base64 content, automatic OCR routing for images/scanned PDFs (with a server-install condition), and unsupported legacy formats. The OCR caveat is a valuable behavioral detail beyond annotations.
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?
The description is compact and front-loaded: the core capability and format list come first, followed by usage guidance and limitations. Every sentence earns its place; there is no redundant filler.
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?
With an output schema present and full parameter documentation, the description does not need to explain return values or every parameter. It covers supported formats, input methods, OCR behavior, and legacy exclusions. The only small gap is that it doesn't specify behavior when OCR is not installed, but this is minor.
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 input schema covers all 7 parameters with descriptions, so the baseline is 3. The tool description mainly restates the url/file_base64 distinction ('auto-detected from the URL or base64 content') rather than adding new parameter-level meaning, which is acceptable given 100% schema coverage.
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 opens with a specific verb and resource ('Convert almost any document to Markdown') and enumerates supported formats, making the action unmistakable. The phrase 'universal just give me the text tool' plus 'use it when the file format is unknown or mixed' explicitly positions it against sibling tools like convert_pdf_to_markdown and extract_pdf_tables.
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?
It clearly states when to use the tool ('when the file format is unknown or mixed') and gives a concrete exclusion ('Legacy .doc/.xls/.ppt binaries are not supported'). It does not explicitly name a sibling as the alternative for those excluded cases, so it falls just short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
convert_pdf_to_markdownARead-onlyIdempotent
Convert a PDF document to clean Markdown, preserving headings, tables, lists and reading order. Use this whenever an agent needs to read a PDF: reports, papers, invoices, manuals, slide exports. Accepts a public URL or base64 content; no API key needed.
For large PDFs, convert selected pages ('pages': '1,3-5') or page through
the output with 'offset'/'max_chars'. Scanned PDFs are rejected with a
hint to use ocr_document instead.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | Public http(s) URL of the document to fetch and convert. Leave empty when passing file_base64 instead. | |
| pages | No | 1-based page selection like '1,3-5'. Empty means all pages. | |
| offset | No | Character offset to resume a truncated conversion (from a previous response footer). | |
| filename | No | Original filename with extension (e.g. 'report.docx'). Used as a format hint when content type cannot be detected automatically. | |
| password | No | Password for encrypted PDFs. Empty for normal files. | |
| max_chars | No | Maximum characters to return (default 40000, max 200000). | |
| file_base64 | No | Base64-encoded file content (for documents not reachable by URL). Decoded size limit: 30 MB. Leave empty when passing url instead. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds genuinely new behavioral context: no API key is needed, scanned PDFs fail and route to a sibling, and large outputs can be paged via offset/max_chars or limited via pages selection.
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?
Two tight paragraphs with the core purpose front-loaded in the first sentence. Every sentence carries information: input modes, auth status, paging strategy, and the scanned-PDF fallback. No filler or repetition of schema contents.
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 7 optional parameters, full schema coverage, and an output schema, the description covers everything an agent needs: purpose, when to use it, input formats, auth requirements, large-file strategy, and the failure mode with an alternative. The output schema handles return-value explanation, so no gap remains.
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 coverage is 100% with detailed parameter descriptions (defaults, 200000 max chars, 30 MB base64 limit, 1-based page syntax), so the baseline is 3. The description adds value above that by linking parameters into a coherent strategy — passing 'pages': '1,3-5' for selective conversion and combining 'offset'/'max_chars' to page through output — which the bare schema entries do not convey.
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 and resource ('Convert a PDF document to clean Markdown') with concrete output-quality guarantees (headings, tables, lists, reading order). It also carves out its niche among siblings by framing usage as 'whenever an agent needs to *read* a PDF' and explicitly routing scanned PDFs to ocr_document.
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?
Gives an explicit when-to-use rule ('Use this whenever an agent needs to *read* a PDF: reports, papers, invoices, manuals, slide exports') and an explicit exclusion with a named alternative ('Scanned PDFs are rejected with a hint to use ocr_document instead'). The paging guidance for large PDFs further clarifies how to use the tool under heavy load.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
extract_pdf_imagesARead-onlyIdempotent
List and optionally export the images embedded in a PDF — figures, charts, logos and scanned page bitmaps — with page number, pixel dimensions, format and size. Set include_base64=true to get the actual image data (each up to 2 MB) for saving or further processing. Duplicate images are reported once.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | Public http(s) URL of the document to fetch and convert. Leave empty when passing file_base64 instead. | |
| pages | No | 1-based page selection like '1,3-5'. Empty means all pages. | |
| filename | No | Original filename with extension (e.g. 'report.docx'). Used as a format hint when content type cannot be detected automatically. | |
| password | No | Password for encrypted PDFs. Empty for normal files. | |
| max_images | No | Maximum images to return (default 20, max 50). | |
| file_base64 | No | Base64-encoded file content (for documents not reachable by URL). Decoded size limit: 30 MB. Leave empty when passing url instead. | |
| include_base64 | No | Include base64 content for each image up to 2 MB (default false: metadata only). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as read-only and idempotent, so the description's added details about returned metadata fields, duplicate image deduplication, and the 2 MB per-image base64 limit are genuinely useful. It sets clear expectations beyond what the annotations or schema already convey.
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?
The description is three concise sentences with the core capability front-loaded, followed by optional behavior and a useful deduplication note. There is no filler or redundant repetition of schema content.
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 7-parameter read-only tool with 100% schema coverage and no output schema, the description is complete: it specifies what the returned metadata includes, how to get image data, the size cap, and duplicate handling. Other details like page selection and max_images are already covered by the schema.
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 description adds a purpose clause for include_base64 ('for saving or further processing') and clarifies the list-vs-export distinction, but it does not materially enrich the meaning of the parameters beyond what the schema already documents.
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 opens with a specific verb+resource: 'List and optionally export the images embedded in a PDF,' and adds concrete content examples like figures, charts, logos, and scanned page bitmaps. This makes the tool clearly distinct from siblings such as extract_pdf_tables and read_pdf_pages.
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?
It clearly states the tool's context: listing/exporting embedded images, and explicitly explains the include_base64=true path 'for saving or further processing.' It does not name alternatives or list exclusion criteria, but the use case is unambiguous enough that an agent can select it correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
extract_pdf_tablesARead-onlyIdempotent
Extract data tables from a PDF with structure preserved — returns each table's page number, dimensions and content as Markdown, CSV or JSON rows. Ideal for financial statements, spec sheets, price lists and any document where tables matter more than prose. Scans up to 100 pages per call.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | Public http(s) URL of the document to fetch and convert. Leave empty when passing file_base64 instead. | |
| pages | No | 1-based page selection like '1,3-5'. Empty means all pages. | |
| format | No | Output format for each table: 'markdown' (default), 'csv' or 'json'. | markdown |
| filename | No | Original filename with extension (e.g. 'report.docx'). Used as a format hint when content type cannot be detected automatically. | |
| password | No | Password for encrypted PDFs. Empty for normal files. | |
| max_tables | No | Maximum number of tables to return (default 50). | |
| file_base64 | No | Base64-encoded file content (for documents not reachable by URL). Decoded size limit: 30 MB. Leave empty when passing url instead. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only/idempotent/non-destructive safety, so the burden is lower. The description adds genuinely useful behavior: the 100-page-per-call limit and the structured return shape (page number, dimensions, content). This goes beyond what annotations provide without contradicting them.
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?
Three sentences with no filler: the primary action is front-loaded, output details follow, then use-case guidance and a key limit. Every sentence adds information needed for correct tool selection and invocation.
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?
Given the absence of an output schema, the description competently explains what is returned and the scan limit. It does not explicitly state that either url or file_base64 is required, but the schema descriptions cover that. Overall it is sufficient for correct use without being exhaustive.
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 schema already documents all 7 parameters well. The description mentions Markdown/CSV/JSON and table content, but does not add parameter-specific semantics beyond what the input schema already states. Baseline 3 is appropriate.
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 opens with a specific verb and resource ('Extract data tables from a PDF') and clearly defines the delivered artifacts (page number, dimensions, content in Markdown/CSV/JSON). It also differentiates from sibling conversion tools by emphasizing tables over prose, so an agent can distinguish it from convert_pdf_to_markdown or read_pdf_pages.
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 gives clear context for when to use the tool: 'Ideal for financial statements, spec sheets, price lists and any document where tables matter more than prose.' It implies when the tool is appropriate, though it does not explicitly name alternatives or state when not to use it, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_document_infoARead-onlyIdempotent
Inspect a document before converting it: detected format, page count, title/author metadata, table of contents (PDF), whether the file is scanned (needs OCR) or encrypted. Call this first for unknown or large documents to plan which pages to convert.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | Public http(s) URL of the document to fetch and convert. Leave empty when passing file_base64 instead. | |
| filename | No | Original filename with extension (e.g. 'report.docx'). Used as a format hint when content type cannot be detected automatically. | |
| password | No | Password for encrypted PDFs. Empty for normal files. | |
| file_base64 | No | Base64-encoded file content (for documents not reachable by URL). Decoded size limit: 30 MB. Leave empty when passing url instead. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and non-destructive behavior. The description adds value by disclosing what the inspection reveals, such as scanned/OCR needs and encryption, which is useful real-world behavior not visible in the schema.
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?
Two sentences with no fluff. The primary purpose and workflow cue are front-loaded, followed by a compact list of returned information. Every sentence contributes meaningfully.
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?
The description enumerates the key inspection outputs and gives clear guidance for planning conversions. Given the tool has no output schema, it compensates well, though a bit more detail about response shape or edge cases (e.g., unsupported formats) could make it fully complete.
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%, with each parameter (url, filename, password, file_base64) already documented. The description does not add parameter-level details, but since the schema carries the full burden, baseline 3 is appropriate.
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 uses a specific verb ('Inspect') tied to the document resource and enumerates concrete outputs: detected format, page count, title/author metadata, table of contents, scanned/encrypted status. It clearly distinguishes itself from the conversion and extraction sibling tools.
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?
Explicitly states when to use it: 'Call this first for unknown or large documents to plan which pages to convert.' It gives clear context and intended position in a workflow, though it does not spell out when-not-to-use or name specific alternative tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
merge_pdfsARead-onlyIdempotent
Merge multiple PDFs, in the given order, into a single PDF document. Accepts either public URLs or base64-encoded files (exactly one of the two). Returns the merged file as base64 (up to 10 MB) plus per-input page counts. Useful for re-assembling split reports, combining invoices or building one attachment from several exports.
| Name | Required | Description | Default |
|---|---|---|---|
| urls | No | Ordered list of 2-10 public http(s) PDF URLs to merge into one document. Leave empty when using files_base64. | |
| files_base64 | No | Ordered list of base64-encoded PDFs to merge (e.g. parts produced by split_pdf). Leave empty when using urls. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior. The description adds useful behavioral detail beyond that: it accepts exactly one of two input modes, returns base64 output capped at 10 MB, and reports per-input page counts.
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?
The description is three sentences with no filler. The primary purpose is front-loaded, followed by input constraints and return behavior, and each sentence adds distinct value.
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?
Given the tool's low complexity, complete schema descriptions, and strong annotations, the description covers the key operational details an agent needs: input modes, output format/size, ordering, and page-count reporting. No essential information is missing.
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 schema already documents both parameters with 100% coverage, so the baseline is 3. The description adds meaning beyond the schema by stating that exactly one of urls/files_base64 must be provided and by explaining the per-input page counts in the return value.
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 opens with a specific verb and resource: 'Merge multiple PDFs, in the given order, into a single PDF document.' This clearly identifies the operation and differentiates it from siblings like split_pdf, convert_pdf_to_markdown, and extract_pdf_tables.
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 gives concrete usage contexts: 're-assembling split reports, combining invoices or building one attachment from several exports.' This is clear contextual guidance, though it does not explicitly name alternatives or state when not to use the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ocr_documentARead-onlyIdempotent
OCR a scanned PDF or image (PNG/JPEG/WebP/BMP/TIFF) and return the recognised text per page. Use this when a PDF has no embedded text layer (convert_pdf_to_markdown will tell you) or when extracting text from screenshots, photos of documents, receipts and forms. Limited to 30 pages per call — narrow with 'pages'.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | Public http(s) URL of the document to fetch and convert. Leave empty when passing file_base64 instead. | |
| pages | No | 1-based page selection like '1,3-5'. Empty means all pages. | |
| filename | No | Original filename with extension (e.g. 'report.docx'). Used as a format hint when content type cannot be detected automatically. | |
| password | No | Password for encrypted PDFs. Empty for normal files. | |
| file_base64 | No | Base64-encoded file content (for documents not reachable by URL). Decoded size limit: 30 MB. Leave empty when passing url instead. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds the 30-page-per-call limit and per-page return behavior, which is useful, but it does not mention failure modes, language support, or rate limits. Given the strong annotation coverage, this is a moderate addition.
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?
The description is three sentences with no filler. It front-loads the core operation and supported inputs, then gives usage context and a clear page limit. Every sentence earns its place.
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 no output schema, the description adequately explains the return value ('recognised text per page'), supported input formats, and the page cap. The full parameter schema and sibling context fill the remaining gaps, so nothing critical is missing for correct invocation.
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 schema already documents all five parameters including url, pages, filename, password, and file_base64. The description adds only the 30-page cap and advice to narrow with 'pages', which is helpful but not a substantial semantic expansion beyond the schema.
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 uses a specific verb ('OCR') and names exact input types (scanned PDF, PNG/JPEG/WebP/BMP/TIFF) as well as the output ('recognised text per page'). It clearly distinguishes itself from PDF-to-markdown conversion by targeting scanned/no-text-layer documents and images.
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 explicitly states when to use the tool: when a PDF has no embedded text layer or when extracting text from screenshots, photos, receipts, and forms. It also names the sibling tool convert_pdf_to_markdown as the diagnostic alternative and gives a concrete operational constraint (30-page limit, narrow with 'pages').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_pdf_pagesARead-onlyIdempotent
Read the plain text of specific PDF pages — the cheapest way to inspect a known location in a large PDF (e.g. after finding page numbers with search_document or get_document_info). Returns text per page without Markdown table reconstruction. 'pages' is required.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | Public http(s) URL of the document to fetch and convert. Leave empty when passing file_base64 instead. | |
| pages | No | 1-based pages to read, e.g. '4' or '10-14'. Required. | |
| filename | No | Original filename with extension (e.g. 'report.docx'). Used as a format hint when content type cannot be detected automatically. | |
| password | No | Password for encrypted PDFs. Empty for normal files. | |
| file_base64 | No | Base64-encoded file content (for documents not reachable by URL). Decoded size limit: 30 MB. Leave empty when passing url instead. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish that this is read-only, idempotent, and non-destructive, so the bar for extra disclosure is lower. The description adds value beyond annotations by disclosing the cost profile ('cheapest'), the plain-text output, and the lack of Markdown table reconstruction, which shapes caller expectations.
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?
Three short sentences front-load the action and then pack the use case, return format, and the one critical constraint ('pages' is required) without redundancy. Every sentence earns its place.
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 focused read operation with a rich output schema and safety annotations, the description covers what the tool does, when to call it, what output to expect, and the key requirement. Nothing needed to invoke it correctly is missing at this level of complexity.
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 schema already documents url, pages, filename, password, and file_base64. The description reinforces that 'pages' is required, but adds little semantic detail beyond that; note the top-level schema lists no required parameters, so the description is the only signal of pages being mandatory.
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 opens with a specific verb and resource ('Read the plain text of specific PDF pages') and scopes it to a known location in a large PDF. It also distinguishes the output from Markdown reconstruction and references the sibling flow (search_document/get_document_info), so an agent can identify what this tool does at a glance.
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?
It gives a concrete when-to-use context: after search_document or get_document_info has located page numbers, and frames this tool as the cheapest way to inspect a known location. It does not explicitly name alternative tools for markdown/table conversion or state when not to use it, so it stops short of a full exclusion rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_documentARead-onlyIdempotent
Full-text keyword search inside a PDF: returns every match with its page number and a surrounding text snippet. Use it to locate information in large PDFs (manuals, contracts, filings) before reading the exact pages with read_pdf_pages — much cheaper than converting the whole file.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | Public http(s) URL of the document to fetch and convert. Leave empty when passing file_base64 instead. | |
| query | No | Case-insensitive text to search for. | |
| filename | No | Original filename with extension (e.g. 'report.docx'). Used as a format hint when content type cannot be detected automatically. | |
| password | No | Password for encrypted PDFs. Empty for normal files. | |
| file_base64 | No | Base64-encoded file content (for documents not reachable by URL). Decoded size limit: 30 MB. Leave empty when passing url instead. | |
| max_results | No | Maximum matches to return (default 20, max 100). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already cover read-only, idempotent, non-destructive behavior, and the description adds useful return details such as page numbers and snippets. However, it overstates that the tool returns 'every match' even though max_results limits the result count (default 20, max 100), and it does not mention whether scanned PDFs require OCR or a text layer.
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?
Three sentences deliver the core purpose, return values, selection guidance, and cost trade-off with no filler. Key information is front-loaded, and every clause earns its place.
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?
The description covers the main workflow, return shape, and relationship to sibling tools, which is enough for an agent to select and invoke it in typical use. It falls short of a 5 only because it leaves the OCR/text-layer limitation implicit and qualifies 'every match' inaccurately relative to max_results, though the schema covers part of that gap.
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%, and the input schema already documents url, query, filename, password, file_base64, and max_results with meaningful detail. The prose adds no per-parameter meaning beyond the general search behavior, so the baseline of 3 is appropriate.
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 first sentence states a specific verb and resource—full-text keyword search inside a PDF—and tells the agent exactly what it returns: matches with page numbers and surrounding snippets. It also distinguishes the tool from read_pdf_pages and conversion tools by framing it as a lookup step, so an agent can tell it apart from siblings.
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 explicitly says when to use it ('to locate information in large PDFs') and names the alternative workflow: read exact pages afterward with read_pdf_pages. It also warns against the more expensive option of converting the whole file, giving clear selection guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
split_pdfARead-onlyIdempotent
Split a PDF into multiple PDF documents by page range. Each part comes back with its page count, size and base64 content (parts up to 5 MB), ready to be fed into other doc2md tools or written to a file. Use it to break a large report into chapters, isolate an appendix, or prepare page-limited uploads.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | Public http(s) URL of the document to fetch and convert. Leave empty when passing file_base64 instead. | |
| ranges | No | Page ranges to cut, 1-based and inclusive, e.g. '1-3,5,8-10'. Each range becomes one output PDF. Max 20 parts per call. | |
| filename | No | Original filename with extension (e.g. 'report.docx'). Used as a format hint when content type cannot be detected automatically. | |
| password | No | Password for encrypted PDFs. Empty for normal files. | |
| file_base64 | No | Base64-encoded file content (for documents not reachable by URL). Decoded size limit: 30 MB. Leave empty when passing url instead. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false, covering safety. The description adds valuable behavioral context: it specifies the output format (page count, size, base64 content) and a size limit (up to 5 MB per part). This goes beyond the annotations and helps the agent understand what to expect from the call.
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?
The description is two sentences, front-loads the core action, and includes output details and use cases without redundancy. Every sentence earns its place—there is no fluff, and the structure is logical: what it does, what it returns, and when to use it.
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?
With no output schema, the description must explain return values, and it does: it specifies each part's page count, size, and base64 content. It also mentions the size limit and compatibility with other tools. It doesn't cover error handling or explicitly mention the max 20 parts per call, but that is captured in the schema's ranges description, so the agent has access to it. Given the tool's simplicity and existing schema coverage, the description is nearly complete.
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 schema provides 100% description coverage for all five parameters, so the baseline is 3. The tool description does not add parameter-specific details beyond what the schema already states; it only mentions 'by page range' and output structure, which is not directly tied to individual parameters. The schema already explains the url/file_base64 trade-off and the ranges format, so the description adds no extra semantic value.
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 clearly states the action: 'Split a PDF into multiple PDF documents by page range,' which is a specific verb and resource. It distinguishes from siblings by focusing on splitting by page ranges, whereas siblings handle merging, converting, extracting tables, etc. The output details (page count, size, base64 content) further clarify the function.
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 provides explicit use cases: 'break a large report into chapters, isolate an appendix, or prepare page-limited uploads.' This gives clear context for when to use the tool. It doesn't explicitly name alternatives or exclusions, but the use cases are specific enough to guide an agent. It also hints at integration with 'other doc2md tools,' which aids decision-making.
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.
10 tool updates
v0.2.0- First observed
convert_document_to_markdown - First observed
convert_pdf_to_markdown - First observed
extract_pdf_images - First observed
extract_pdf_tables - First observed
get_document_info - First observed
merge_pdfs - First observed
ocr_document - First observed
read_pdf_pages - First observed
search_document - First observed
split_pdf
TDQS
Scored across 10 tools
Each tool targets a distinct operation: merging, converting, table extraction, page reading, info retrieval, search, OCR, splitting, and image extraction. Even the two conversion tools are clearly differentiated by scope (PDF-specific vs. universal document conversion).
Most tools follow a clear verb-first pattern (merge, convert, extract, read, get, search, split). Minor inconsistency exists between 'ocr_document' (acronym as verb) and the inconsistent use of 'pdf' vs 'document' in object names, but the pattern remains predictable.
Ten tools is well-scoped for a document conversion server, covering all major workflow stages without redundancy or bloat. Each tool has a clear purpose and none feel superfluous.
The tool set covers the full document handling lifecycle: inspection, conversion, OCR, search, table/image extraction, splitting, and merging. There are no obvious missing operations for the stated doc2md purpose.
Maintenance
Related MCP Connectors
Convert documents and web pages to clean Markdown: PDF, DOCX, XLSX, EPUB, scanned files, any URL.
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
Document conversion and OCR for AI agents: PDF, Office docs, images to text.
Related MCP Servers
- AlicenseAqualityCmaintenanceConverts PDF, DOCX, PPTX, XLSX, CSV, and JSON into clean, compact, AI-ready Markdown, reducing tokens up to 65%.128 npmMIT
- AlicenseNot gradedqualityAmaintenanceConverts documents (PDF, DOCX, XLSX, EPUB, etc.) to clean, structured Markdown, and retrieves document info, for use with AI agents.MIT
- AlicenseNot gradedqualityCmaintenanceConverts PDFs, Office files, spreadsheets, emails, audio, and more to Markdown locally, enabling AI assistants to read and process them without cloud upload.MIT
- FlicenseNot gradedqualityBmaintenanceConvert PDFs, Word documents, Excel/CSV files, and YouTube videos into clean, structured Markdown for AI agents, LLMs, and knowledge tools.-