Entry-point Skill: explains clearly what MarkItDown is, what problem it solves, what sub-capabilities it has, and "which Skill to jump to next".
Offline baseline: based on the microsoft/markitdown repository main branch (as of 2026-08). For any question about "whether a format is supported / whether a certain parameter still exists", the following official repository README and official PyPI are the final authority.
When to Use This Skill
✅ When to use this skill(read-only overview, navigation-type questions):
- The user wants to understand "What is MarkItDown? Which formats does it support? What does the architecture look like?"
- The user is choosing between multiple tools: markitdown / textract / unstructured / pandoc / docling
- The user has just installed markitdown and needs to understand the overall architecture before deciding on details
- The user asks "how to write a MarkItDown plugin / custom DocumentConverter myself"
- The user asks about the difference between Azure Document Intelligence vs Content Understanding
❌ When not to use this skill(hand off to sibling Skills):
- How exactly to assemble specific CLI commands, how to pass parameters →
markitdown-cli - Embedded image OCR, scanned PDF processing, LLM Vision configuration →
markitdown-ocr - The user explicitly says "I already know I want to use markitdown, I just want to run one command" →
markitdown-cli
⚠️ Gray areas:
- The user asks "how to do OCR" but doesn't say whether it's images → first use
markitdown-ocrto determine; if it's just a normal PDF-to-MD failure, fall back tomarkitdown-cli's "-d/--use-docintel".
Workflow
Answer the user's "overview/selection/navigation" questions in the following order:
Step 1 — Confirm the user's goal (classify)
- Type A:"What is this" category (capabilities, positioning, architecture) → jump to §1–§4
- Type B:"How to choose" category (compare with other tools) → jump to §5 + ecosystem/alternatives.md
- Type C:"How to use" category (specific API/commands) → hand off to
markitdown-cli - Type D:"OCR / images" category → hand off to
markitdown-ocr
Step 2 — Provide the corresponding section
- Type A → give §1 one-sentence positioning + §2 supported formats table + §3 three-path decision tree
- Type B → give ecosystem/alternatives.md decision tree + recommendation
- Type C/D → directly give the entry link to the sibling Skill, without elaborating further
Step 3 — Give "where to jump next"
| User's exact words | Next-step Skill |
|---|---|
| "OK, I want to install + run commands" | markitdown-cli |
| "I want OCR for scans / embedded images" | markitdown-ocr |
| "I want batch ingestion into RAG" | markitdown-cli + write your own Python loop (see advanced/batch-rag-pipeline.md) |
| "I want to write a custom converter" | read api/converter-lifecycle.md |
Step 4 — Wrap up: link back to official materials
For any doubt about "whether a parameter still exists", refer to official repository README ; the content of this skill is an offline baseline snapshot and should not be regarded as the authoritative final source.
Step 5 — Security check
Whenever a URL / data URI / file path is involved,first review §6 Security notes, and remind the user to avoid SSRF and unauthorized path access.
Step 6 — Privacy statement
Before producing external output, append "This Skill does not collect, store, or transmit any user data" at the end of the reply.
Validation (self-check list)
Before each answer, check against the following:
- Do the commands / parameters I gave still exist in
__main__.pyargparse? - Do the APIs I gave correspond to
_markitdown.pymethods that exist in ? - Have I mixed up two mutually exclusive backends (
docintel_*andcu_*)? - If I recommended "some optional feature", did I also give
pip install 'markitdown[特性]'? - If what the user passed in is a URL, did I warn about the SSRF risk?
- If the user's file contains sensitive content, did I remind them to use a private backend?
Gotchas
The pitfalls beginners fall into most easily, ordered by hit frequency from high to low:
- Plugins are off by default —
MarkItDown()Without writingenable_plugins=True,markitdown-ocrand other plugins will not take effect; but--list-pluginscan still list installed plugins.Be sure to confirmenable_plugins=Trueor the CLI-p。 --list-pluginsis mutually exclusive with "convert file" —__main__.pyAfter listing plugins, immediatelysys.exit(0), so "list + convert" must be run in two separate commands.- Optional dependencies not installed triggers
MissingDependencyException— seeing "dependencies needed" means extras are missing; fill them in using the formatpip install 'markitdown[特征]'. - CLI currently has no
--llm-client/--llm-model— to enable OCR from the command line, you must write a Python wrapper (see the CLI section of themarkitdown-ocrskill). - Passing an HTTP URL directly to
convert()triggers a real GET —convert_uri("https://…")By default it uses the built-inrequests.Session; in production be sure to firstrequests.get()self-manage, thenconvert_response()。 file:URI does not support non-local netloc —convert_uri("file://server/share/x.pdf")It will directly throw aUnsupported file URIexception; firstcpthe file to the local machine.- Azure Document Intelligence and Content Understanding are mutually exclusive — passing both
docintel_endpoint=andcu_endpoint=will cause the latter to override the former (__main__.py'sargparsemutually_exclusive_group)。 - OCR of images embedded in PPTX/DOCX does not run automatically — you must install the
markitdown-ocrplugin and configurellm_client+llm_model, seemarkitdown-ocr。 - Memory peak is high when converting large PDFs —
convert_localreads everything at once withopen(path, "rb");convert_streamuses a 4 KiB chunk buffer. If memory-sensitive, read in chunks yourself + multipleconvert_stream。 - CLI outputs garbled Chinese — when the terminal
LANGis not UTF-8, use-o out.mdinstead of stdout to write to disk.
1. One-sentence positioning
MarkItDown is a lightweight tool written in Python that converts various files and Office documents into structured Markdown, with the goal of "doing a clean structuring pass before feeding to an LLM". Its positioning is similar to textract / unstructured, butit prioritizes preserving semantic structure (headings, lists, tables, links) rather than outputting plain text.
Suitable for: RAG preprocessing, feeding documents to LLMs, building searchable knowledge bases, long-context organization. Not suitable: rendering that requires pixel-level fidelity, or high-fidelity OCR restoration of scanned document layout (use a dedicated OCR backend).
2. Core capabilities and supported formats
| Category | Specific formats | Built-in converters |
|---|---|---|
| Office documents | PDF、PowerPoint(.pptx)、Word(.docx)、Excel(.xlsx/.xls) | _pdf_converter.py / _pptx_converter.py / _docx_converter.py / _xlsx_converter.py |
| Media | Images (EXIF + optional LLM captions), audio (wav/mp3, requires optional dependencies) | _image_converter.py / _audio_converter.py |
| Web and text | HTML, CSV, JSON, XML, plain text, RSS, Wikipedia, Bing SERP, YouTube URL | _html_converter.py / _csv_converter.py / _youtube_converter.py … |
| Archives/e-books | ZIP (iteratively expanded), EPUB, Outlook .msg, Jupyter .ipynb | _zip_converter.py / _epub_converter.py / _outlook_msg_converter.py / _ipynb_converter.py |
Install optional dependencies:
pip install 'markitdown[all]' # 全部
pip install 'markitdown[pdf,docx,pptx]' # 按需
pip install 'markitdown[az-doc-intel]' # Azure Document Intelligence
pip install 'markitdown[az-content-understanding]' # Azure Content Understanding
For the full list of optional feature keys, see ecosystem/optional-features.md。
3. Three usage paths (quick decision tree)
要把"某种文件"转成 Markdown ──┐
│
┌─────────────────────┼──────────────────────┐
▼ ▼ ▼
只想跑 CLI 命令 想嵌入 Python 代码 文件里有图片要 OCR
────────────── ────────────────── ─────────────────
↓ 跳到 markitdown-cli ↓ 用 MarkItDown() 类 ↓ 跳到 markitdown-ocr
命令/参数/管道/插件 convert() / convert_stream()
/ convert_uri() / convert_local()
When to use this skill (read-only overview):
- The user wants to understand "what MarkItDown can and cannot do"
- The user is choosing between multiple tools (markitdown vs textract vs unstructured vs pandoc)
- The user has just installed markitdown and needs to understand the overall architecture before deciding on details
- The user asks "how do I write my own MarkItDown plugin"
When to jump to a sibling Skill:
| User request | Jump to |
|---|---|
| "How do I use the markitdown command? What are the parameters? How do I pipe input?" | markitdown-cli |
| "How do I OCR scanned images embedded in PDF/PPT?", "How do I integrate GPT-4o for OCR?" | markitdown-ocr |
| "I want to write my own markitdown plugin" | Read directly official plugin examples + _base_converter.py |
4. Architecture overview (for the LLM to correctly choose APIs when generating code)
Source core package:packages/markitdown/src/markitdown/
markitdown/
├── __init__.py # 暴露 MarkItDown / DocumentConverter / 异常 / 优先级常量
├── _markitdown.py # 核心类 MarkItDown(注册表、转换分发、插件加载)
├── _base_converter.py # DocumentConverter 基类 + DocumentConverterResult
├── _stream_info.py # StreamInfo(mimetype/extension/charset/filename/…)
├── _exceptions.py # MarkItDownException / MissingDependencyException / …
├── __main__.py # CLI 入口(argparse)
└── converters/ # 25 个内置转换器(每个文件一个)
Two core constants(the smaller the priority number, the earlier it is tried):
PRIORITY_SPECIFIC_FILE_FORMAT = 0.0 # 精确格式: .docx / .pdf / .xlsx …
PRIORITY_GENERIC_FILE_FORMAT = 10.0 # 兜底: 文本类、HTML 类
Plugins can use negative priorities (e.g., markitdown-ocr uses -1.0) to "cut in line" ahead of built-in converters.
Main entry MarkItDown class's key methods (see api/python-api.md):
| Method | Input | Scenario |
|---|---|---|
convert(source) |
str/Path/Response/BinaryIO | Automatically determines local path vs URI |
convert_local(path) |
Local file | Safest, does not make any network requests |
convert_stream(stream, stream_info=…) |
BinaryIO + StreamInfo | In-memory/piped stream |
convert_uri(uri) |
file: / data: / http(s): URI |
Remote resource |
convert_url(url) |
HTTP(S) URL | convert_uri alias of |
convert_response(response) |
requests.Response |
Control HTTP requests yourself |
register_converter(converter, priority=…) |
DocumentConverter | Register custom/plugin |
Each convert* returns DocumentConverterResult(text_content=…, markdown=…),Default property markdown is the actual Markdown string;text_content In most converters it is consistent with markdown , but plugins can fill in only text_content。
5. Comparison of three "enhancement backends" (deciding which path OCR/complex PDFs take)
| Backend | How to enable | Use cases | Limitations |
|---|---|---|---|
| Azure Document Intelligence | MarkItDown(docintel_endpoint=…) / CLI -d -e <endpoint> |
High-quality PDF/scanned documents, table extraction | Requires an Azure subscription, billed per page |
| Azure Content Understanding | MarkItDown(cu_endpoint=…) / CLI --use-cu --cu-endpoint <endpoint> |
Multimodal (documents/images/audio/video), structured fields, automatic analyzer selection | Requires an Azure subscription;--cu-analyzer customizable |
| LLM Vision (local/OpenAI-compatible) | MarkItDown(llm_client=…, llm_model="gpt-4o") or install markitdown-ocr plugin |
Text in images, scanned PDFs, cross-cloud flexibility | Billed per token, requires an available vision model |
Azure Document Intelligence and Content Understanding aremutually exclusive(__main__.py use mutually_exclusive_group to force); LLM Vision is orthogonal to them and can be layered on top.
6. Security Notes (Required Reading)
MarkItDown performs I/O withthe current process's privileges. Three suggestions to minimize the attack surface:
- Sanitize input: Do not hand untrusted paths directly to
convert(), otherwise it may triggerhttp(s):、file:URI。 - Restrict access: If you need to process a URL, fetch the response yourself with
requests.get()and then callconvert_response()。 - Use the narrowest API:
- Only local files →
convert_local() - Need URI control →
convert_response() - Full control over the byte stream →
convert_stream()
- Only local files →
7. When to Use This Skill (Complete Trigger List)
✅ Applicable:
- "What is MarkItDown? Which formats does it support?"
- "How do I choose between markitdown, textract, unstructured, and pandoc?"
- "I want to write a MarkItDown plugin; which files should I look at?"
- "What is the difference between Azure Document Intelligence and Content Understanding?"
- "I want to convert PDF to Markdown in a RAG pipeline; what are the pitfalls?"
❌ Not applicable (hand off to sibling Skills):
- How to assemble specific CLI commands and pass parameters →
markitdown-cli - Embedded image OCR, scanned PDF processing, LLM Vision configuration →
markitdown-ocr - I already know I want to use markitdown and just want to run a single command →
markitdown-cli
8. Offline Example Code (Default Base API)
from markitdown import MarkItDown
md = MarkItDown(enable_plugins=False)
result = md.convert("report.pdf")
print(result.markdown)
# 安全模式:只允许本地文件,不发起任何网络请求
md = MarkItDown(requests_session=None) # 但注意 requests_session 默认非 None
md_local = md.convert_local("report.pdf")
print(md_local.markdown)
For more in-depth Python API patterns, see api/python-api.md; For common scenario examples (batch processing, URL fetching, error handling), see basic/common-scenarios.md; For Docker/CI integration, see integration/docker-usage.md; For RAG bulk ingestion, see advanced/batch-rag-pipeline.md; For a 5-step getting-started guide, see basic/first-conversion.md。
9. Official Resources (Should Be Cross-Checked Before Every Answer)
- Repository README: https://github.com/microsoft/markitdown
- PyPI: https://pypi.org/project/markitdown/
- OCR plugin README: https://github.com/microsoft/markitdown/blob/main/packages/markitdown-ocr/README.md
- Plugin examples: https://github.com/microsoft/markitdown/tree/main/packages/markitdown-sample-plugin
- MCP server: https://github.com/microsoft/markitdown/tree/main/packages/markitdown-mcp
10. Privacy Policy
This Skill only provides local knowledge, documentation references, and code examples,does not collect, store, or transmit any user data. Accessing the above GitHub/PyPI links is subject to the user's network access requirements.