# System map — microsoft/markitdown

> Canonical page: https://codevetter.com/unpack/markitdown/system-map

# System map — microsoft/markitdown

Scanned commit b8f79c57ebc0044be41323d89b2a45d3fda8460e (2026-09-21). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

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. — [packages/markitdown/src/markitdown/_markitdown.py#L141-168](https://github.com/microsoft/markitdown/blob/b8f79c57ebc0044be41323d89b2a45d3fda8460e/packages/markitdown/src/markitdown/_markitdown.py#L141-L168)
- 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). — [packages/markitdown/src/markitdown/_markitdown.py#L101-107](https://github.com/microsoft/markitdown/blob/b8f79c57ebc0044be41323d89b2a45d3fda8460e/packages/markitdown/src/markitdown/_markitdown.py#L101-L107) [packages/markitdown/src/markitdown/_markitdown.py#L226-253](https://github.com/microsoft/markitdown/blob/b8f79c57ebc0044be41323d89b2a45d3fda8460e/packages/markitdown/src/markitdown/_markitdown.py#L226-L253) [packages/markitdown/src/markitdown/_markitdown.py#L737-739](https://github.com/microsoft/markitdown/blob/b8f79c57ebc0044be41323d89b2a45d3fda8460e/packages/markitdown/src/markitdown/_markitdown.py#L737-L739)
- 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. — [packages/markitdown/src/markitdown/_base_converter.py#L5-105](https://github.com/microsoft/markitdown/blob/b8f79c57ebc0044be41323d89b2a45d3fda8460e/packages/markitdown/src/markitdown/_base_converter.py#L5-L105)
- 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. — [packages/markitdown/src/markitdown/_stream_info.py#L5-32](https://github.com/microsoft/markitdown/blob/b8f79c57ebc0044be41323d89b2a45d3fda8460e/packages/markitdown/src/markitdown/_stream_info.py#L5-L32)
- 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. — [packages/markitdown/pyproject.toml#L74-75](https://github.com/microsoft/markitdown/blob/b8f79c57ebc0044be41323d89b2a45d3fda8460e/packages/markitdown/pyproject.toml#L74-L75) [packages/markitdown/src/markitdown/__main__.py#L51-145](https://github.com/microsoft/markitdown/blob/b8f79c57ebc0044be41323d89b2a45d3fda8460e/packages/markitdown/src/markitdown/__main__.py#L51-L145)
- 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. — [packages/markitdown-mcp/src/markitdown_mcp/__main__.py#L16-24](https://github.com/microsoft/markitdown/blob/b8f79c57ebc0044be41323d89b2a45d3fda8460e/packages/markitdown-mcp/src/markitdown_mcp/__main__.py#L16-L24) [packages/markitdown-mcp/src/markitdown_mcp/__main__.py#L58-135](https://github.com/microsoft/markitdown/blob/b8f79c57ebc0044be41323d89b2a45d3fda8460e/packages/markitdown-mcp/src/markitdown_mcp/__main__.py#L58-L135)
- 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]. — [packages/markitdown/pyproject.toml#L27-64](https://github.com/microsoft/markitdown/blob/b8f79c57ebc0044be41323d89b2a45d3fda8460e/packages/markitdown/pyproject.toml#L27-L64)
- 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. — [packages/markitdown/src/markitdown/_markitdown.py#L110-130](https://github.com/microsoft/markitdown/blob/b8f79c57ebc0044be41323d89b2a45d3fda8460e/packages/markitdown/src/markitdown/_markitdown.py#L110-L130) [packages/markitdown-sample-plugin/src/markitdown_sample_plugin/_plugin.py#L25-31](https://github.com/microsoft/markitdown/blob/b8f79c57ebc0044be41323d89b2a45d3fda8460e/packages/markitdown-sample-plugin/src/markitdown_sample_plugin/_plugin.py#L25-L31) [packages/markitdown-ocr/pyproject.toml#L55-57](https://github.com/microsoft/markitdown/blob/b8f79c57ebc0044be41323d89b2a45d3fda8460e/packages/markitdown-ocr/pyproject.toml#L55-L57)
- 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. — [Dockerfile#L1-34](https://github.com/microsoft/markitdown/blob/b8f79c57ebc0044be41323d89b2a45d3fda8460e/Dockerfile#L1-L34)
- 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. — [.github/workflows/tests.yml](https://github.com/microsoft/markitdown/blob/b8f79c57ebc0044be41323d89b2a45d3fda8460e/.github/workflows/tests.yml) [.github/workflows/pre-commit.yml](https://github.com/microsoft/markitdown/blob/b8f79c57ebc0044be41323d89b2a45d3fda8460e/.github/workflows/pre-commit.yml) [.github/constraints.txt](https://github.com/microsoft/markitdown/blob/b8f79c57ebc0044be41323d89b2a45d3fda8460e/.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. — [packages/markitdown/src/markitdown/__init__.py#L5-34](https://github.com/microsoft/markitdown/blob/b8f79c57ebc0044be41323d89b2a45d3fda8460e/packages/markitdown/src/markitdown/__init__.py#L5-L34) [packages/markitdown/src/markitdown/converters/__init__.py#L5-54](https://github.com/microsoft/markitdown/blob/b8f79c57ebc0044be41323d89b2a45d3fda8460e/packages/markitdown/src/markitdown/converters/__init__.py#L5-L54)
- 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. — [packages/markitdown/pyproject.toml#L71-72](https://github.com/microsoft/markitdown/blob/b8f79c57ebc0044be41323d89b2a45d3fda8460e/packages/markitdown/pyproject.toml#L71-L72) [packages/markitdown/src/markitdown/__about__.py](https://github.com/microsoft/markitdown/blob/b8f79c57ebc0044be41323d89b2a45d3fda8460e/packages/markitdown/src/markitdown/__about__.py) [packages/markitdown-mcp/src/markitdown_mcp/__about__.py](https://github.com/microsoft/markitdown/blob/b8f79c57ebc0044be41323d89b2a45d3fda8460e/packages/markitdown-mcp/src/markitdown_mcp/__about__.py) [packages/markitdown-ocr/src/markitdown_ocr/__about__.py](https://github.com/microsoft/markitdown/blob/b8f79c57ebc0044be41323d89b2a45d3fda8460e/packages/markitdown-ocr/src/markitdown_ocr/__about__.py)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
