Skip to main content
Glama
yazkyChristianNicolas

pdf-to-md-mcp-server

pdf-to-md-mcp-server

MCP server local (stdio) para convertir PDFs a Markdown.

  • Extrae texto y estructura (headers, listas, tablas simples) pagina por pagina con pymupdf4llm.

  • Las imagenes/diagramas incrustados se guardan en una carpeta <nombre>_images/ junto al .md y se referencian desde ahi.

  • Las paginas sin texto seleccionable (PDFs escaneados) se procesan automaticamente con OCR (Tesseract, invocado por PyMuPDF internamente — no hace falta ningun paquete Python de OCR aparte) pagina por pagina, sin intervencion manual — sirve para manuales mixtos (algunas paginas con texto real, otras escaneadas).

  • Cada pagina queda delimitada por un comentario <!-- pdf-page: N --> (N 1-indexado) para poder ubicar cualquier parte del .md en su pagina de origen del PDF.

  • El .md arranca con un frontmatter YAML que resume de que trata: title (el que trae el PDF, o si no tiene, el primer H1 detectado en el contenido), author/subject/keywords si el PDF los trae, pages, ocr_pages y converted_at. Es metadata estructural (sin LLM) — no un resumen generado del contenido.

Requisitos

  • Python >= 3.10

  • Tesseract instalado en el sistema (el binario, no solo el paquete de Python), con los idiomas que necesites:

    brew install tesseract tesseract-lang

Related MCP server: MCP-PDF2MD

Instalacion

cd pdf-to-md-mcp-server
/opt/homebrew/opt/python@3.12/bin/python3.12 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

Tests

source .venv/bin/activate
pytest

Los tests generan PDFs sinteticos (uno con texto real, otro con una pagina "escaneada") con PyMuPDF y validan que la conversion produzca el .md esperado y dispare el fallback de OCR donde corresponde. Requieren Tesseract instalado.

Configuracion (variables de entorno, opcionales)

Variable

Default

Descripcion

PDF2MD_OCR_LANG

spa+eng

Idiomas para Tesseract (codigos ISO 639-2 separados por +)

PDF2MD_MIN_CHARS_PER_PAGE

20

Umbral de caracteres extraibles por debajo del cual una pagina se reporta como escaneada en ocr_pages (informativo — no activa ni evita el OCR en si, que corre pymupdf4llm automaticamente donde haga falta)

PDF2MD_OCR_DPI

200

DPI al renderizar una pagina para pasarla por OCR

Ejemplo de .md generado

---
source_pdf: "manual.pdf"
title: "Manual de usuario"
author: "Acme Corp"
pages: 2
ocr_pages: [2]
converted_at: 2026-09-05T01:18:23+00:00
---

<!-- pdf-page: 1 -->

# Manual de usuario

Seccion 1: Introduccion...

---

<!-- pdf-page: 2 -->

Seccion 2: Instalacion (pagina escaneada, procesada con OCR)...

Tools expuestas

convert_pdf_to_markdown(pdf_path, output_dir=None, ocr_lang=None)

Convierte un PDF puntual. Devuelve {markdown_path, images_dir, page_count, ocr_pages}.

convert_pdf_directory(input_dir, output_dir=None, recursive=True, ocr_lang=None)

Convierte todos los PDF de una carpeta (recursivo por default). Devuelve {converted: [...], errors: [...], total_found} — si un PDF puntual falla, queda registrado en errors y se sigue con el resto.

Registrar el server en Claude Code

claude mcp add pdf-to-md -- /ruta/a/pdf-to-md-mcp-server/.venv/bin/python -m src.server

(ajusta la ruta al .venv real de tu instalacion)

Registrar el server en Claude Desktop

Agregar en claude_desktop_config.json:

{
  "mcpServers": {
    "pdf-to-md": {
      "command": "/ruta/a/pdf-to-md-mcp-server/.venv/bin/python",
      "args": ["-m", "src.server"]
    }
  }
}

Available Tools

2 tools
convert_pdf_directoryA

Convierte todos los PDF de una carpeta a archivos Markdown.

Aplica la misma logica que convert_pdf_to_markdown a cada PDF encontrado. Si un archivo puntual falla, se registra en errors y se sigue con el resto (no corta el lote entero).

Args: input_dir: Carpeta con los PDF a convertir output_dir: Carpeta base de salida (default: junto a cada PDF de origen). Si recursive=True, se replica la subcarpeta relativa de cada PDF dentro de output_dir recursive: Si busca PDFs en subcarpetas tambien (default: True) ocr_lang: Idioma(s) para Tesseract (ver convert_pdf_to_markdown)

Returns: dict con converted (lista de resultados por PDF, mismo shape que convert_pdf_to_markdown), errors (lista de {pdf, error}) y total_found (cantidad de PDFs encontrados)

ParametersJSON Schema
NameRequiredDescriptionDefault
ocr_langNo
input_dirYes
recursiveNo
output_dirNo

TDQS

A4.8/5.0
Behavior5/5

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

With no annotations, the description carries the full burden, and it does so well. It discloses partial-failure handling (errors are logged and processing continues), the default output location, recursive behavior, and the return dictionary shape. This gives an agent a clear picture of non-obvious behavior.

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

Conciseness5/5

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

The description is well-structured with Args and Returns sections, front-loaded with the main purpose, and every sentence adds useful information. No fluff or repetition of schema metadata.

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

Completeness5/5

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

The tool has no output schema, so documenting the return value is essential, and the description provides the full dict shape including converted, errors, and total_found. Combined with clear parameter semantics, recursion behavior, and failure handling, 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.

Parameters5/5

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

Schema description coverage is 0%, so the description must compensate, and it fully does. Every parameter gets a meaningful explanation: input_dir, output_dir with default and recursion subfolder replication, recursive default True, and ocr_lang with a pointer to the sibling tool for Tesseract language details.

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 description clearly states a specific action ('Convierte todos los PDF de una carpeta a archivos Markdown') and distinct resource scope: all PDFs in a directory, versus a single PDF. It also explicitly references the sibling convert_pdf_to_markdown, making the batch-vs-single distinction obvious.

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?

The description implies the appropriate use case: batch conversion of directories, applying the same logic as convert_pdf_to_markdown per PDF. It gives defaults and behavior for recursion and output paths, though it does not explicitly state when NOT to use this tool in favor of the single-file sibling.

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

convert_pdf_to_markdownA

Convierte un PDF a un archivo Markdown (.md).

Extrae texto y estructura (headers, listas, tablas simples) pagina por pagina. Las imagenes/diagramas incrustados se guardan en una carpeta aparte y se referencian desde el .md. Las paginas sin texto seleccionable (escaneos) se procesan con OCR (Tesseract) como fallback automatico.

El .md generado arranca con un frontmatter YAML (title, author/ subject/keywords si el PDF los trae, pages, ocr_pages, converted_at) que resume de que trata el documento, y cada pagina queda delimitada por un comentario <!-- pdf-page: N --> (N 1-indexado) para poder ubicar cualquier seccion en su pagina de origen del PDF.

Args: pdf_path: Ruta al archivo .pdf a convertir output_dir: Carpeta donde escribir el .md y las imagenes (default: la misma carpeta del PDF de entrada) ocr_lang: Idioma(s) para Tesseract, formato ISO 639-2 separados por '+' (ej: "spa+eng"). Default: configurado en el server (PDF2MD_OCR_LANG, "spa+eng" si no esta seteado)

Returns: dict con markdown_path (ruta del .md generado), images_dir (carpeta de imagenes extraidas, o None si no hubo ninguna), page_count y ocr_pages (numeros de pagina, 1-indexados, que se procesaron con OCR por no tener texto extraible)

ParametersJSON Schema
NameRequiredDescriptionDefault
ocr_langNo
pdf_pathYes
output_dirNo

TDQS

A4.6/5.0
Behavior5/5

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

Sin anotaciones, la descripción asume toda la carga y lo hace muy bien: describe el fallback OCR, el guardado de imágines en carpeta aparte, el frontmatter YAML, los comentarios de página y el formato del retorno. No hay contradicción con anotaciones porque no las hay.

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

Conciseness5/5

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

La descripción es detallada pero bien organizada: comienza con el propósto, luego el comportamient específico, y termina con Args/Returns. Cada oración añade valor sin redundancia.

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

Completeness5/5

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

Pese a no tener esquea de salida ni descripciones de parámetors, la descripción cubre entradas, valores por defecto, salida, formato del .md, manejo de imágens y OCR. Es suficientemente complea para que un ageente invoque la herramienta correctamente.

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

Parameters5/5

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

Con 0% de cobertura en el esquea, la descripción compensa completament: documenta pdf_ath, output_dir (con su valor por defecto), y ocr_lang (con formato y default). Aporta signifcado que el esquea no tiene.

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?

La descripción establece claramente el verbo 'Convierte' y el recurso 'PDF a Markdown', con detalle sobre extracción de texto y estructura. Se distingue del hermano convert_pdf_directory al especificar 'un PDF' en lugar de un directorio compleo.

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?

El uso se infiere: se debe usar para convertir un único PDF a Markdown. Sin embargo, no se mencionan exclusions ni se nombra la alternativa convert_pdf_directory, por lo que no se proporiona orientación explecita sobre cuándo no usar esta herramienta.

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. Dates show when Glama detected each change.

  1. 2 tool updatesv0.1.0
    • First observedconvert_pdf_directory
    • First observedconvert_pdf_to_markdown

TDQS

A4.6/5.0
Disambiguation5/5

The two tools are clearly distinct: one converts a single PDF, the other batch-converts all PDFs in a directory. Descriptions reinforce the boundary with separate parameters and return shapes, so there is no realistic confusion.

Naming Consistency4/5

Both tools share the convert_pdf_ prefix and are readable. The second name is slightly less parallel because it omits the explicit _to_markdown target, but the pattern is still predictable and clear.

Tool Count4/5

With only two tools, the server is minimal but justified for a single-purpose PDF-to-Markdown converter. Each tool earns its place by covering both single-file and batch workflows, so the count is reasonable if slightly on the thin side.

Completeness5/5

The tool surface fully covers the server's stated purpose: individual conversion, directory batch conversion, recursive traversal, OCR fallback, and error handling. There are no obvious dead ends or missing operations that would block the intended workflow.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/yazkyChristianNicolas/pdf-to-md-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server