MarkItDown

MarkItDown

Fichiers convertis en Markdown pour un LLM, pas pour un humain

MarkItDown est une bibliothèque Python de Microsoft, avec sa ligne de commande, qui convertit des fichiers en Markdown pour un LLM ou un pipeline d'analyse de texte. Le README la compare à textract : elle cherche à garder titres, listes, tableaux et liens, et n'est pas forcément le bon outil pour une conversion fidèle destinée à un lecteur humain.

Markdownify MCP installe MarkItDown et appelle son exécutable pour convertir les fichiers que lui confie un agent.

Le comparatif des outils d'OCR open source confronte MarkItDown aux moteurs OCR et aux modèles de vision.

Magika reconnaît le format, chaque parseur s'installe à part

  • Un appel pour beaucoup de formats : .docx, .pptx, .xlsx et .xls, PDF, messages Outlook (.msg), EPUB, notebooks Jupyter, HTML, CSV, JSON, RSS et Atom. Une archive ZIP est parcourue fichier par fichier, et une URL YouTube rend la transcription de la vidéo.
  • Type de fichier lu dans le contenu : sans extension, MarkItDown devine le format en analysant les octets avec Magika.
  • Parseurs à la carte : le paquet de base n'embarque ni les parseurs Office ni ceux du PDF. Chaque format s'ajoute par un extra (pip install 'markitdown[pdf, docx]'), et [all] prend tout.
  • Tableaux et équations : les pages PDF qui portent un tableau ou un formulaire ressortent en tableaux Markdown via pdfplumber, et les équations Word deviennent du LaTeX.
  • Serveur MCP officiel : markitdown-mcp expose un seul outil, convert_to_markdown(uri), pour des URI http:, https:, file: ou data:.

OCR confié à un LLM, formats Office anciens exclus

Un PDF de prose sort en texte brut. Le convertisseur PDF lit la couche texte avec pdfminer, sans OCR, et ne reconstruit ni titres ni listes hors des pages à tableaux.

Une image ne devient du texte que par un LLM. Le README annonce de l'OCR pour les images, mais le convertisseur (JPEG et PNG) n'en fait aucun en local. Il reprend les métadonnées EXIF si exiftool est installé, position GPS comprise. Avec un client compatible OpenAI, il envoie l'image entière au modèle avec la consigne « Write a detailed caption for this image » : on obtient une légende, pas une transcription. Les images des fichiers PowerPoint suivent le même chemin.

Les PDF scannés passent eux aussi par un LLM. Le plugin officiel markitdown-ocr envoie au modèle chaque image d'un PDF, d'un .docx, d'un .pptx ou d'un .xlsx, et chaque page scannée rendue à 300 DPI. Sans client LLM, il s'efface sans erreur. Il dépend de PyMuPDF, publié sous AGPL-3.0 ou sous licence commerciale d'Artifex : ce maillon échappe à la licence MIT de MarkItDown.

Le LLM se branche par l'API Python seulement. La ligne de commande n'a aucune option pour un client LLM : elle ne branche que les plugins et deux services Azure facturés à l'appel, Document Intelligence et Content Understanding. Le README du plugin OCR montre pourtant des options --llm-client et --llm-model que le code de la CLI ne définit pas. Content Understanding est la seule voie pour la vidéo et pour extraire des champs, comme le montant d'une facture. Unstract fait cette extraction en auto-hébergé et rend du JSON.

La transcription audio part chez Google. L'extra [audio-transcription] appelle recognize_google de SpeechRecognition sans clé : la bibliothèque prend alors une clé générique que sa documentation réserve aux usages personnels ou de test, et que Google peut révoquer. La langue par défaut est en-US.

Les anciens formats Office, l'OpenDocument et le RTF ne passent pas. Aucun convertisseur n'accepte les .doc et .ppt, les .odt, .ods et .odp, ou le RTF. anydoc les lit.

Les entrées doivent être filtrées. convert() ouvre fichiers locaux et URL distantes avec les droits du processus : sur un serveur, le README demande de valider les entrées et d'appeler convert_local() ou convert_stream(). markitdown-mcp n'a pas d'authentification.

Le projet reste en 0.1.x. La v0.1.0 date du 22 mars 2025 et la v0.1.8 du 21 septembre 2026, quatrième version stable de l'année. PyPI classe le paquet en « 4 - Beta », et Python 3.10 à 3.14 est requis.