MarkItDown(読み方はマークイットダウン)は、Microsoftが公開しているオープンソースのPythonツールです。PDF・Word・Excel・PowerPointなどのファイルを、生成AIに読ませやすいMarkdownテキストへ変換します。Markdownを書くエディタではありません。この記事では2026年10月時点の最新版0.1.8を使い、インストールからCLI・Python APIの使い方、形式ごとに実際どう変換されるかまでを実測で示します。uvで入れると旧版の0.1.5が入ってしまう問題と、Shift_JISのCSVが文字化けする問題も扱います。
まとめ:MarkItDownの正体と導入時の要点
- 正体:Microsoftの microsoft/markitdown で開発される、MITライセンスのファイル→Markdown変換ツール(CLIとPythonライブラリ)。GUIは無い。
- 最新版:0.1.8(2026年9月21日)。対応するPythonは3.10〜3.14。
- インストール:
pip install 'markitdown[all]'。uvで同じ指定をすると0.1.5に止まるので、--prerelease=allowを付けるか、必要な形式だけをextrasで指定する。 - 得意な形式:Word・PowerPoint・テキストPDF・Excel。構造の保持範囲は形式によって異なり、PDFの見出しやOffice文書の結合セルは確認が必要。
- 苦手な形式:文字レイヤーのないスキャンPDFや画像内の文字は、標準のままでは抽出できない。画像のメタデータは出力される場合がある。markitdown-ocrプラグインかAzureのサービスを併用する。
- 日本語の注意:Shift_JISのCSVは自動判定で文字化けする。
-c cp932で文字コードを指定する。
MarkItDownとは:読み方・開発元・変換の向き
読み方とMicrosoftのリポジトリ
MarkItDownは「マークイットダウン」と読みます。リポジトリは2024年11月13日に作られ、2026年10月18日時点でGitHubのスターは約19万です。パッケージは PyPIのmarkitdown で配布されており、ライセンスはMITなので、商用でも無償で使えて改変もできます。版番号はまだ0.1系で、2026年は2月に0.1.5、5月に0.1.6、7月に0.1.7、9月に0.1.8が出ています。
変換の向きは「各種ファイル→Markdown」だけ
入力はPDFやOffice文書で、出力はMarkdownの文字列です。MarkdownをPDFに書き出す、Markdownをプレビューするといった逆向きの処理や編集はできません。「markitdown gui」で探す人も多いのですが、公式のGUIはありません。READMEの貢献方針では、デスクトップアプリ・Webフロントエンド・REST APIサーバーをこのリポジトリでは受け付けない対象としています。画面から使いたい場合は、公式パッケージのmarkitdown-mcpをClaude Desktopなどに接続し、チャット画面から変換を呼び出せます。
LLMの前処理にMarkdownを使う理由
公式READMEは、主要なLLMがMarkdownを日常的に読み書きしていて構造を理解しやすいこと、記号が少なくトークン効率が良いことを、Markdownを選んだ理由に挙げています。一方で同じREADMEは、出力は人が読む前提の高忠実な変換には最適でない場合があるとも書いています。用途は、RAGの取り込みや全文検索の前処理です。チャンク分割から検索までの工程はRAGパイプラインとは?取り込み系と推論系に分ける工程設計と再索引の実装判断にまとめています。
対応ファイル形式とextras(追加依存)の対応表
MarkItDownの本体は軽く、形式ごとの読み込みライブラリはextras(角括弧の追加指定)で入れます。READMEの一覧とPyPIの依存定義を突き合わせると、対応は次のとおりです。
| 形式 | extras | 中で使うライブラリ |
|---|---|---|
| pdfminer.six・pdfplumber | ||
| Word(.docx) | docx | mammoth・lxml |
| PowerPoint(.pptx) | pptx | python-pptx |
| Excel(.xlsx) | xlsx | openpyxl・pandas |
| 旧Excel(.xls) | xls | xlrd・pandas |
| Outlook(.msg) | outlook | olefile |
| 音声(wav・mp3) | audio-transcription | SpeechRecognition・pydub |
| YouTubeの字幕 | youtube-transcription | youtube-transcript-api |
| HTML・CSV・JSON・XML・EPub・ZIP | 不要 | 本体の依存のみ |
| Azure Document Intelligence | az-doc-intel | azure-ai-documentintelligence |
| Azure Content Understanding | az-content-understanding | azure-ai-contentunderstanding |
[all] はこれをすべて入れます。2026年10月18日に計測したところ、pipの仮想環境は [all] で405MB、[pdf,docx,pptx,xlsx] だけなら247MB でした。コンテナに載せる場合は、必要な形式だけを指定したほうがイメージが小さくなります。
MarkItDownのインストール手順(pip・uv・pipx)
pipによる導入とOS・シェル別の実行準備
READMEにある前提は Python 3.10から3.14 で、仮想環境の利用が推奨されています。以下のコマンド例はbash・zsh向けです。Windowsのcmd.exeではpipの引数を囲む単引用符を二重引用符に変えます(仮想環境の有効化は、cmd.exeでは .venv\Scripts\activate.bat、PowerShellでは .venv\Scripts\Activate.ps1 です)。
python -m venv .venv
source .venv/bin/activate
pip install 'markitdown[all]'
# 必要な形式だけ入れる場合
pip install 'markitdown[pdf,docx,pptx,xlsx]'
# 入った版を確かめる
markitdown -v
pip 26.2.1で試すと0.1.8が入り、markitdown -v は markitdown 0.1.8 を返しました。
uvで入れると0.1.5に止まる問題と回避策
uvで uv pip install 'markitdown[all]' を実行すると、エラーも警告も出ずに0.1.5が入ります(uv 0.11.31で、新しく作った仮想環境で再現)。原因は、0.1.8の [all] が azure-ai-contentunderstanding>=1.2.0b1 というベータ版を要求していることです。この依存の安定版は1.1.0までしかありません。uvのプレリリースの扱いは、条件を満たす安定版の候補がすべて退けられたときにだけプレリリースへ切り替える仕組みです。そのため、ベータ版の依存を必要としない古いmarkitdownを選んで解決を終えます。pipは、要求側がベータ版を明示しているときはそれを受け入れるので、0.1.8が入ります。
0.1.5で止まると、0.1.6で入ったAzure Content Understanding対応とPDF変換時のメモリ増加の修正が抜けます。0.1.8で入った MARKITDOWN_DOCINTEL_ENDPOINT などの環境変数も効きません。回避策は次のどちらかです。
# 1. プレリリースの依存を許可する(新しい仮想環境で 0.1.8 になることを確認)
uv pip install --prerelease=allow 'markitdown[all]'
# 2. Content Understanding を使わないなら、必要な形式だけを指定する(0.1.8 が入る)
uv pip install 'markitdown[pdf,docx,pptx,xlsx]'
# 既に 0.1.5 が入った環境は、上書きされないので作り直すか -U を付ける
既に0.1.5が入っている仮想環境では、--prerelease=allow を付けて同じコマンドを打っても0.1.5のまま残りました。インストールしたら、必ず markitdown -v で版を確かめてください。
Homebrew公式formulaの提供状況とpipx・Dockerでの導入
macOSで brew info markitdown を実行すると「No available formula with the name “markitdown”」と返り、Homebrewの公式formulaはありません(2026年10月18日に確認)。どの仮想環境からでもコマンドとして呼びたいなら、pipxで入れます。
brew install pipx
pipx install 'markitdown[all]'
# Docker と Git を用意し、公式リポジトリのルートでビルドする
git clone https://github.com/microsoft/markitdown.git
cd markitdown
docker build -t markitdown:latest .
docker run --rm -i markitdown:latest < ~/your-file.pdf > output.md
MarkItDownの使い方:CLIによるファイル変換
MarkItDown CLIの基本コマンドと主要オプション
引数にファイルを渡すと、変換したMarkdownが標準出力に出ます。-o を付けるとファイルに保存します。
markitdown report.pdf # 標準出力へ
markitdown report.pdf -o report.md # ファイルへ保存
cat report.pdf | markitdown -x pdf # 標準入力から渡す(-x は拡張子のヒント)
markitdown --list-plugins # 入っているプラグインの一覧
0.1.8の --help に出るオプションは、-x(拡張子)・-m(MIMEタイプ)・-c(文字コード)のヒント3種、-d/-e(Document Intelligence)、--use-cu/--cu-endpoint(Content Understanding)、-p(プラグインを有効にする)、--keep-data-uris(base64の画像を省略せずに残す)です。
Shift_JISのCSVに対する文字コード指定(-c cp932)
Excelから「CSV」で保存したファイルは、日本語版WindowsではShift_JIS(CP932)になることが多い形式です。このCSVをヒントなしで変換すると、文字コードの自動判定が外れてハングルのような文字列になりました。
$ markitdown meibo_sjis.csv
| 롊덒붥뜂 | 럞뼹 | 븫룓 |
$ markitdown meibo_sjis.csv -c cp932
| 社員番号 | 氏名 | 部署 |
| --- | --- | --- |
| 1001 | 山田太郎 | 営業部 |
Pythonから呼ぶ場合は StreamInfo(charset="cp932") を渡します(次の章のコードを参照)。社内の業務CSVを一括変換するときは、文字コードがUTF-8かCP932かを先に決めておかないと、化けた行がそのままRAGの索引に入ります。
Python APIによる組み込みと一括変換
convertとconvert_localの使い分け
基本は MarkItDown().convert() に渡して、戻り値の .markdown を読むだけです。旧来の .text_content も残っていて、0.1.8では同じ文字列を返します。READMEのコード例は .markdown に統一されています。
from markitdown import MarkItDown, StreamInfo
md = MarkItDown()
result = md.convert_local("uriage.xlsx")
print(result.markdown)
# Shift_JIS の CSV は文字コードを渡す
result = md.convert_local("meibo_sjis.csv", stream_info=StreamInfo(charset="cp932"))
convert() はローカルのパスに加えて http:・https:・file:・data: のURIも受け付けます。READMEのSecurity Considerationsは、MarkItDownは実行中のプロセスの権限で入出力を行うと警告しています。そのうえで、ローカルファイルしか扱わないなら convert_local()、ストリームなら convert_stream() と、用途に合う一番狭いメソッドを呼ぶよう勧めています。利用者がアップロードしたファイル名やURLをそのまま convert() に渡すと、サーバーの内部ネットワークや機密ファイルを読みに行く入口になります。
フォルダを一括変換するスクリプトと実測時間
CLIは1回呼ぶたびにPythonの起動とライブラリの読み込みが入ります。数百ファイルを変換するなら、変換器を1つ作ってPythonの中でループさせます。
import pathlib
from markitdown import MarkItDown
md = MarkItDown()
src, dst = pathlib.Path("docs"), pathlib.Path("md")
dst.mkdir(exist_ok=True)
for p in sorted(src.glob("*")):
if not p.is_file() or p.suffix.lower() not in {".docx", ".xlsx", ".pptx", ".pdf"}:
continue
r = md.convert_local(p)
(dst / f"{p.stem}{p.suffix.replace('.', '_')}.md").write_text(r.markdown, encoding="utf-8")
Intel Core i9-9880HのMacで、後述の社内規程、売上表、導入スケジュールを使ったWord・Excel・PowerPoint・PDFの計4ファイルを対象に、3回計測しました。import に1.6〜1.9秒かかり、変換そのものは1ファイル0.02〜0.38秒で、4ファイルの合計は2.1〜2.4秒でした。CLIは1回あたり約2.3秒かかったので、ファイルの数が増えるほどループさせたほうが速くなります。インストール直後の初回だけは、CLIの1回目に21秒かかりました。
形式別の変換結果を実測(Word・Excel・PowerPoint・PDF)
python-docx・openpyxl・python-pptxで日本語のサンプルを作り、PDFはそのWordをLibreOfficeで書き出しました。以下は0.1.8の変換結果の抜粋です。一部の行と空行を省略しています。Excelの例はLibreOfficeで再計算・保存したファイルの結果です。
Wordの変換例:見出し・箇条書きの保持と表の空ヘッダー
# 社内規程 改定案
本書は2026年度の経費精算ルールの改定案です。
## 1. 適用範囲
* 全従業員
* 業務委託先(契約で定める場合)
## 2. 上限額
| | | |
| --- | --- | --- |
| 区分 | 上限 | 承認者 |
| 交通費 | 30,000円 | 課長 部長 |
| 宿泊費 | 15,000円/泊 |
Wordの見出しスタイルは #・## に、箇条書きは * に変わります。表は1行目が空の見出し行になり、本来の見出し「区分・上限・承認者」はデータ行に回りました。縦に結合した承認者のセルは「課長 部長」が1つのセルにまとまり、次の行は列が1つ足りない状態になります。結合セルを使った表は、変換したあとで列の数を確かめてください。
Excelの変換例:欠損値を含む列の小数表示とNaN
## 売上
| 月 | 東京 | 大阪 |
| --- | --- | --- |
| 4月 | 1200.0 | 800.0 |
| 合計 | 2550.0 | 1710.0 |
| NaN | NaN | NaN |
| 結合セルの注記 | NaN | NaN |
## メモ
| 集計は税抜 |
シートごとに ## シート名 の見出しが付き、表になります。今回の表では欠損値を含む数値列が浮動小数点型として読み込まれたため、整数の 1200 は 1200.0 に、空のセルや結合されたセルは NaN になります。数式のセルには、ファイルに保存されている計算結果が入ります。openpyxlで作っただけの未計算のファイルでは合計行が NaN になり、LibreOfficeで開いて保存し直すと 2550.0 が入りました。計算結果が要る表は、Excelで一度保存したファイルを渡します。
PowerPointの変換結果:スライド番号と発表者ノートの出力
<!-- Slide number: 1 -->
# 導入スケジュール
10月 要件定義
11月 PoC
12月 本番
### Notes:
発表者メモ: 予算は別紙
スライドごとにHTMLコメントでスライド番号が入り、タイトルは # になります。発表者ノートは ### Notes: の下に出るので、社外に出せないメモをノートに書いた資料をRAGに入れる場合は注意が必要です。
PDFの変換例:表の抽出と見出し記法の欠落
社内規程 改定案
本書は2026年度の経費精算ルールの改定案です。
1. 適用範囲
全従業員
2. 上限額
| 区分 | 上限 | 承認者 |
| --- | --------- | --- |
| 交通費 | 30,000円 | 課長 |
| 宿泊費 | 15,000円/泊 | 部長 |
同じ内容をPDFにすると、表はきれいな表になる一方で、見出しの # は付かず平文になりました。PDFには見出しタグを保持できる形式もありますが、今回の標準変換では見出しがMarkdownの見出し記法に変換されませんでした。箇条書きの「・」は、Wordの記号フォントに由来する私用領域の文字(U+F0B7)として出力され、画面では空白のように見えます。チャンク分割で見出しを区切りに使う場合、PDFの変換結果では見出しを手がかりにできません。見出しを復元したいPDFには、レイアウト解析を持つPyMuPDF4LLMやDoclingのほうが向いています。
スキャンPDF・画像内の文字抽出と標準変換の限界
PDFを一度PNG画像にしてからPDFに戻した「スキャン相当」のPDFを変換すると、出力は改行1文字だけでした。PNGを直接渡しても本文は出ません。READMEの対応形式には「Images (EXIF metadata and OCR)」とありますが、標準の変換器が画像から取り出すのはEXIFなどのメタデータで、文字を読む処理は次の章の仕組みを足したときに動きます。
スキャンPDF・画像・図を読ませる方法(markitdown-ocr・LLM・Azure)
markitdown-ocrプラグインによるLLM Vision文字認識
公式のプラグイン markitdown-ocr(0.1.1・2026年9月21日)は、PDF・DOCX・PPTX・XLSXに埋め込まれた画像の文字を、LLMのVision機能で読み取ります。Tesseractのような専用のOCRエンジンではありません。llm_client を渡さないと、プラグインは読み込まれてもOCRを黙って飛ばし、標準の変換器で処理します。
python -m pip install markitdown-ocr openai
APIキーを環境変数 OPENAI_API_KEY に設定し、次のコードをPythonファイルに保存して実行します。
from markitdown import MarkItDown
from openai import OpenAI
md = MarkItDown(enable_plugins=True, llm_client=OpenAI(), llm_model="gpt-4o")
print(md.convert("scanned.pdf").markdown)
インストールすると依存としてPyMuPDF 1.28.2も入ります。PyMuPDFのライセンスはAGPL-3.0とArtifexの商用ライセンスの二本立てなので、社外に配布する製品やSaaSに組み込む場合はPyMuPDF(fitz)のライセンスの扱いを先に確認してください。MarkItDown本体のMITライセンスとは条件が違います。
llm_clientによる画像・PPTXの図への説明文付与
本体にも、llm_client と llm_model を渡して画像に説明文を付ける機能があります。READMEによると対象は現時点で画像とPPTXだけです。モデルの呼び出しは1回ごとに課金されるので、図が多い資料を一括で変換する前に、何枚の画像があるかを数えておきます。OpenAIのクライアントの作り方はOpenAI Python SDKの使い方で扱っています。
Azure Document IntelligenceとContent Understandingの使い分け
手元のOCRで足りない帳票や複雑な表は、Azureのサービスに処理を任せます。READMEの比較表を要約すると、違いは次のとおりです。
| 項目 | 標準の変換器 | Document Intelligence | Content Understanding |
|---|---|---|---|
| 処理場所 | 主にローカル(音声認識は外部通信) | Azure | Azure |
| 項目抽出 | なし | この連携では出ない | YAMLのfront matter |
| 音声・動画 | 音声のみ(簡易) | 非対応 | 音声・動画とも対応 |
| 費用 | 計算資源のみ | API呼び出しごと | API呼び出しごと |
| CLIのオプション | なし | -d -e | –use-cu –cu-endpoint |
# エンドポイントを環境変数に置けば -d だけで済む(0.1.8 から)
export MARKITDOWN_DOCINTEL_ENDPOINT="https://<your-resource>.cognitiveservices.azure.com/"
markitdown scanned.pdf -o scanned.md -d
# Content Understanding は PDF だけを送るよう絞れる
markitdown report.pdf --use-cu --cu-endpoint "<endpoint>" --cu-file-types pdf
Content Understandingは、請求書の金額や日付のような項目を取り出したいときと、動画を扱うときの選択肢です。料金と分析器の選び方はAzure Content Understandingとは?Document Intelligenceとの違い・料金・REST APIの使い方で解説しています。
MCPサーバー(markitdown-mcp)によるClaudeなどとの連携
markitdown-mcp(0.0.1a7・アルファ版)は、MarkItDownをMCPのツールとして公開するサーバーです。公開されるツールは convert_to_markdown(uri) の1つだけで、http:・https:・file:・data: のURIを受け付けます。既定の通信方式はSTDIOで、--http を付けるとStreamable HTTPで 127.0.0.1:3001 に待ち受けます。
pip install markitdown-mcp
markitdown-mcp # STDIO(Claude Desktop などから起動される)
markitdown-mcp --http --host 127.0.0.1 --port 3001 # http://127.0.0.1:3001/mcp
# プラグイン(markitdown-ocr など)を使うときは環境変数で有効にする
MARKITDOWN_ENABLE_PLUGINS=true markitdown-mcp
Claude Desktopの設定ファイルに書く例は、パッケージのREADMEではDockerイメージを使う形になっています。先に公式リポジトリの packages/markitdown-mcp ディレクトリで docker build -t markitdown-mcp:latest . を実行します。次の設定のホスト側パスを実際の保存先に置き換え、コンテナ内の file:///workdir/example.pdf のようなURIを渡します。
{
"mcpServers": {
"markitdown": {
"command": "docker",
"args": ["run", "--rm", "-i", "-v", "/home/user/data:/workdir", "markitdown-mcp:latest"]
}
}
}
READMEは、このサーバーを信頼できるローカルのエージェントから使うものと位置づけています。--host 0.0.0.0 のように外向きのインターフェースで待ち受けると、ネットワーク上の誰でもサーバーのプロセス権限でファイルやURLを読ませられるので、避けてください。DifyなどのワークフローツールにMCPのHTTPエンドポイントとして登録する場合も、同じホストか閉じたネットワークの中で動かす構成にします。サーバー側のコードは公式Python SDK v2の MCPServer で書かれていて、自分でツールを足す場合の書き方はMCP Python SDK v2 移行:FastMCPからMCPServerへの書き換え手順と据え置き判断が参考になります。
他の変換ツールとの使い分けと他言語からの利用
Docling・Marker・PyMuPDF4LLM・MinerUとの違い
MarkItDownの強みは、Office文書・HTML・CSV・ZIPまでを1つのAPIで扱えることと、依存が軽いことです。PDFのレイアウトを解析する機械学習モデルは持っていません。PDFが中心なら、レイアウトを解析するツールのほうが見出しや段組みを正しく扱えます。
| ツール | 得意な入力 | PDFのレイアウト解析 | ライセンス |
|---|---|---|---|
| MarkItDown | Office・HTML・CSV等 | なし | MIT |
| PyMuPDF4LLM | あり | AGPL/商用 | |
| Docling | PDF・Office | あり(モデル使用) | MIT |
| Marker | あり(モデル使用) | Apache-2.0(重みは別規約) | |
| MinerU | PDF(論文・数式) | あり(モデル使用) | Apache-2.0+追加条項 |
社内の文書がWordとExcel中心で、PDFは文字の入ったものだけならMarkItDownで足ります。スキャンPDFや段組みの論文が多いなら、PDFだけを専用ツールに回して、残りをMarkItDownで変換する分担が無駄がありません。RAGに載せる前のチャンクの大きさはチャンクとトークンの違いとは?チャンク分割の手法とRAGのサイズ設計を日本語で実測で検証しています。
Java・JavaScript・.NETからのCLI・MCP連携
公式の実装はPythonだけです。JavaやNode.jsのアプリから使うなら、CLIを子プロセスとして呼ぶか、markitdown-mcpを同じホストで立ててMCPクライアントから呼ぶのが手堅い方法です。READMEの方針どおり、HTTP APIのサーバーは公式からは提供されないので、自前でラップする場合は前述の入力の検証を自分で組み込みます。
社内文書を取り込むRAGの設計や運用を外部に相談したい場合は、RAG構築支援で前処理から検索精度の評価まで対応しています。
MarkItDownを採用すべきでない場面
- 人が読む文書への変換:README自身が、人向けの高忠実な変換には最適でない場合があると書いています。Wordから原稿を作って人が編集するなら、書式を残せるPandocを使います。
- スキャンPDFが大半の書類:標準では文字を抽出できず、外部のLLM APIやAzureを併用する場合は、利用サービスの料金体系に応じた費用が発生します。件数が多いなら専用OCRの費用と比べてから決めます。
- Excelの数値を集計に使う:欠損を含む列では
1200.0やNaNが混ざるので、pandasやopenpyxlで直接読みます。 - 利用者が渡したURLやパスを変換するサーバー:取得先を自分で制限できない設計なら採用を見送ります。
よくある質問
MarkItDownの読み方は?
「マークイットダウン」です。文書の書式であるMarkdown(マークダウン)とは別物で、各種ファイルをMarkdownに変換するMicrosoftのツールです。
MarkItDownは無料で商用利用できますか?
MITライセンスなので無料で商用利用できます。ただし、markitdown-ocrを入れると依存に入るPyMuPDFはAGPL-3.0と商用ライセンスの二本立てです。LLMやAzureを併用した場合は、それぞれのAPIの利用料がかかります。
MarkItDownにGUIはありますか?
公式のGUIはありません。READMEは、デスクトップアプリやWebの画面を公式リポジトリでは受け付けない対象としています。画面から使いたい場合は、markitdown-mcpをClaude Desktopなどに登録して、チャットで変換を頼む方法が公式の範囲で使えます。
Homebrewでインストールできますか?
Homebrewの公式formulaはありません(2026年10月18日に確認)。macOSでは仮想環境で pip install 'markitdown[all]' とするか、コマンドとして使いたいなら pipx install 'markitdown[all]' を使います。
Windowsでのインストール方法は?
Python 3.10〜3.14を入れ、Mac・Linuxと同じく pip install 'markitdown[all]' を実行します。仮想環境の有効化はcmd.exeでは .venv\Scripts\activate.bat、PowerShellでは .venv\Scripts\Activate.ps1 です。cmd.exeでpipを実行するときは、パッケージ指定を単引用符ではなく二重引用符で囲みます。