CodeVetter · Repo Unpack · System map
microsoft/markitdown
The repo is a uv/pip-installable Python monorepo under packages/ with four distributions: markitdown (the library + `markitdown` CLI), markitdown-mcp (an MCP server wrapping the library), markitdown-ocr (a first-party plugin adding LLM-vision OCR), and markitdown-sample-plugin (an RTF reference plugin). The core engine is the MarkItDown class in _markitdown.py, which owns a requests.Session, a magika.Magika identifier, and a priority-sorted list of ConverterRegistration entries. All format logic lives in ~25 DocumentConverter subclasses under converters/ plus shared helpers in converter_utils/. Build is hatchling-based; tests run via `hatch test` or pytest in CI across Python 3.10-3.14 on Linux, Windows, and Windows ARM64.
- The central orchestrator is class MarkItDown in packages/markitdown/src/markitdown/_markitdown.py (line 141); its constructor builds a requests.Session with an 'Accept: text/markdown, text/html;q=0.9, ...' header and instantiates magika.Magika() for file-type identification.
- Built-in converters are registered in enable_builtins() in a deliberate order: PlainTextConverter, ZipConverter, and HtmlConverter get PRIORITY_GENERIC_FILE_FORMAT (10.0) while ~15 specific converters get PRIORITY_SPECIFIC_FILE_FORMAT (0.0); lower values are tried first and registration order within a priority is reversed (insert at index 0).
- Every converter implements the DocumentConverter interface defined in _base_converter.py: accepts(file_stream, stream_info, **kwargs) -> bool and convert(...) -> DocumentConverterResult; DocumentConverterResult carries `markdown` plus optional `title`, with `text_content` kept as a soft-deprecated alias.
- Stream metadata flows through the frozen dataclass StreamInfo (mimetype, extension, charset, filename, local_path, url) with a copy_and_update() merge helper in _stream_info.py.
- The CLI entrypoint is `markitdown = markitdown.__main__:main` declared in pyproject [project.scripts]; __main__.py builds an argparse parser supporting -o/--output, -x/--extension, -m/--mime-type, -c/--charset, -d/--use-docintel, --use-cu, -p/--use-plugins, --list-plugins, and --keep-data-uris.
- The MCP server package markitdown-mcp defines one tool `convert_to_markdown(uri)` on an MCPServer('markitdown') instance and can run over stdio (mcp.run()) or HTTP via a combined Starlette app merging the SSE and Streamable-HTTP sub-apps served by uvicorn on 127.0.0.1:3001 by default.
- Core runtime dependencies are deliberately thin: beautifulsoup4, requests, markdownify, magika~=0.6.1, charset-normalizer, defusedxml; all heavy parsers (mammoth, python-pptx, pandas/openpyxl/xlrd, pdfminer.six, pdfplumber, olefile, pydub, SpeechRecognition, youtube-transcript-api, Azure SDKs) are optional extras declared in pyproject.toml [project.optional-dependencies].
- Third-party plugins are discovered via importlib.metadata entry_points(group='markitdown.plugin') in _load_plugins(); each plugin module must expose register_converters(markitdown, **kwargs), demonstrated by the sample plugin and the markitdown-ocr package's [project.entry-points."markitdown.plugin"] declaration.
- The root Dockerfile builds a python:3.13-slim-trixie image installing ffmpeg and libimage-exiftool-perl, sets EXIFTOOL_PATH/FFMPEG_PATH/ORT_DISABLE_TELEMETRY env vars, pip-installs markitdown[all] plus the sample plugin, drops to USER nobody:nogroup, and uses ENTRYPOINT ['markitdown'] for stdin->stdout conversion.
- CI runs three pytest/hatch jobs in .github/workflows/tests.yml (core hatch test matrix on ubuntu + windows + windows-11-vs2026-arm; ocr-tests installing both local packages; mcp-tests installing markitdown[all] + markitdown-mcp) plus a separate pre-commit workflow, with PIP_CONSTRAINT/UV_CONSTRAINT pinned to .github/constraints.txt.
- The public API surface is explicitly re-exported in markitdown/__init__.py: MarkItDown, DocumentConverter, DocumentConverterResult, StreamInfo, the exception hierarchy, and the two PRIORITY_* constants; converter classes are importable from markitdown.converters.
- Versions are managed per-package via hatch's [tool.hatch.version] pointing at each package's __about__.py: markitdown 0.1.8, markitdown-mcp 0.0.1a7, markitdown-ocr 0.1.1.