Blog

PDFs in Claude Code: Conversion, Tokens, and Preserving Structure

Markdown

MarkItDown, PyMuPDF4LLM, MCP, complete conversion scripts, PDF limits, and cases when visual analysis matters more than token savings.

Read full article

Key takeaway

Each PDF page in Claude Code costs 1,500–3,000 tokens before the first question—and Anthropic states this plainly in its documentation. In the illustrative calculation below, a 15-page report across 4 different chats uses 135,000 PDF input tokens at about $0.40, versus 18,000 Markdown input tokens at $0.054—about 87% less. This assumes 2,250 PDF tokens or 300 Markdown tokens per page at the example’s input rate; actual documents vary. This guide covers three conversion methods (MarkItDown, PyMuPDF4LLM, and an MCP server) and a ready-to-use bash script for a folder of documents.

Practical instructions for using Ailoot are in the documentation.

What happens to a PDF in Claude, and why does each page cost 1,500–3,000 tokens?

Key takeaway

When you upload a PDF to Claude Code, it doesn’t read it as a text file. First, each page is converted into an image, then text is extracted from it, and both layers—the image and the text—are added to the context together. That’s why one page takes up 1,500–3,000 tokens, and a 50-page document can use 75,000–150,000 tokens before you ask your first question.

Anthropic’s official documentation describes the process in three straightforward steps:

The system converts each document page into an image. Text from each page is extracted and provided alongside the page image. Claude analyzes both the text and images to better understand the document.

— Anthropic, https://platform.claude.com/docs/en/docs/build-with-claude/pdf-support

It sounds logical, but processing costs grow linearly with the number of pages. And here’s the figure that explains why your subscription limit runs out on a single PDF:

Each page typically uses 1,500–3,000 tokens depending on content density. Since each page is converted into an image, the same cost as for standard images applies.

— Anthropic, https://platform.claude.com/docs/en/docs/build-with-claude/pdf-support

To see how much that is, Anthropic measured the same 3-page PDF on Bedrock in two modes. In text mode (Converse Document Chat), it used ~1,000 tokens. With visual analysis (Claude PDF Chat), it used ~7,000 tokens. Including images makes processing 7 times more expensive.

Page screenshots are even worse: a 1000×1000-pixel screenshot costs about 1,300 tokens.

The mechanics are simple: PDFs are expensive because Claude doesn’t trust its OCR. It uses both text and image so it can compare them—and you pay for both layers at once. For large documents, you can do things differently: save the file as Markdown in your project folder and tell Claude, “here’s a document with information in it—spread it out.” It will distribute the content among its own files and continue working with the organized text instead of consuming everything at once.

How much does a PDF consume in a typical task?

Key takeaway

Consider a 15-page public report used in 4 different contexts—analysis, quotes, translation, and summary. Assume 2,250 input tokens per PDF page, 300 per converted Markdown page, and the same input rate for both. Re-uploading the PDF gives 135,000 input tokens, about $0.40; Markdown gives 18,000, or $0.054. The roughly 87% saving follows from those assumptions, not from a measurement of every PDF.

The specific numbers (Sonnet 4.x model, input at $3 per million tokens):

ApproachTokens (15 pages, 4 chats)Cost
PDF uploaded directly 4 times15 × 2250 × 4 = 135,000~$0.40
PDF → Markdown + 4 chats15 × 300 × 4 = 18,000~$0.054
Savings−87%−$0.35

And that’s for just one cycle of 4 requests. After that, prompt caching comes into play (5-minute TTL by default, up to 1 hour on an extended tier, with up to 90% off repeat calls within the window)—the savings multiply.

Each time you upload the same PDF in a new chat, Claude reads it again; the cache doesn’t carry over between chats.

If you convert the same 15-page PDF to Markdown once and then bring it into each of four new chats as a .md file, this example uses 15 × 300 × 4 = 18,000 input tokens instead of 135,000. The 300 tokens per converted page and 2,250 tokens per PDF page are assumptions for this calculation, not measured constants for every PDF. Count your actual document and confirm conversion quality before estimating savings.

This math gets even more significant with a Claude Pro subscription. One 100-page report can burn through the entire 5-hour limit. After converting to Markdown, 10+ such documents fit within the same budget.

What are Anthropic API limits for PDFs in 2026?

Key takeaway

Anthropic has strict limits: a maximum of 32 MB per request (including all content, not just the PDF) and a maximum of 600 pages per request. But the limit is lower for current Sonnet 4.x and Opus 4.x models with 200K context: 100 pages. You can send a PDF in three ways: by URL, in Base64, or through the Files API for reuse with file_id. The Files API plus splitting into parts is used for long documents.

Anthropic’s documentation lists the limits at the top (current as of May 31, 2026):

RequirementLimit
Maximum request size32 MB (varies by platform)
Maximum pages per request600 (100 for models with 200K-token context)
FormatStandard PDF without passwords or encryption

Both limits apply to the entire request body, including content alongside the PDF. For large PDFs, use the Files API and reference them with file_id to keep the request body small.

— Anthropic, https://platform.claude.com/docs/en/docs/build-with-claude/pdf-support

Claude.ai (the consumer web app) has different limits: a maximum of 500 MB per file and up to 20 files in a chat. But visual analysis works only for PDFs up to 100 pages—beyond that Claude sees only text, without charts and diagrams.

Three ways to send a PDF through the API:

  1. By URL - "source": {"type": "url", "url": "..."} - simplest when the document is online.
  2. In Base64 - "source": {"type": "base64", "media_type": "application/pdf", "data": "..."} - for local files.
  3. Through the Files API - "source": {"type": "file", "file_id": "file_abc123"} - for repeat requests; requires the beta header anthropic-beta: files-api-2025-04-14.

The Files API is the main way to save when working with the same PDF across different chats. Upload it once, get a file_id, and then all interactions use it. With cache_control: ephemeral, repeat calls cost 10% of the regular price.

Anthropic also offers official advice on minimizing usage:

Dense PDFs (with lots of small text, complex tables, or heavy graphics) may fill the context window before you hit the page limit. Try splitting the document into sections; for large files, reduce the resolution of embedded images before uploading.

— Anthropic, https://platform.claude.com/docs/en/docs/build-with-claude/pdf-support

Method 1: How do you set up MarkItDown in 5 minutes?

Key takeaway

MarkItDown is a Python utility from the Microsoft AutoGen team that converts PDFs, DOCX, PPTX, XLSX, HTML, audio, images, and even YouTube videos into clean Markdown. It has 134 thousand stars on GitHub, an MIT license, and installs with one command: pip install 'markitdown[all]'. It’s just as easy to use: markitdown document.pdf > document.md. The most versatile tool for converting files before using Claude Code.

MarkItDown is an official Microsoft project maintained by the AutoGen team. On GitHub, it has 134 thousand stars and 9.2 thousand forks (as of the end of May 2026). Its purpose is stated directly in the README:

A lightweight Python utility for converting files to Markdown for use with LLMs and text-analysis pipelines.

— Microsoft, https://github.com/microsoft/markitdown

Supported formats:

  • Documents: PDF, DOCX, PPTX, XLSX
  • Web: HTML, JSON, XML, CSV
  • Media: audio with transcription, images with EXIF and OCR, YouTube videos (via captions)
  • Archives: ZIP, EPub
  • Other: all attachments inside Outlook MSG files

Installation

Requirement: Python 3.10+ (usually already installed on macOS; you need to install it separately on Windows).

pip install 'markitdown[all]'

If you don’t need every format, you can install selected ones:

pip install 'markitdown[pdf, docx, pptx]'

Converting a single file

The simplest case:

markitdown document.pdf > document.md

After that, document.md will appear in the current folder. Bring it into Claude Code using @document.md or simply put it next to your project.

Python API

If you want to integrate it into your script:

from markitdown import MarkItDown

md = MarkItDown()
result = md.convert("research-paper.pdf")
print(result.text_content)

# You can save it straight away:
with open("research-paper.md", "w") as f:
    f.write(result.text_content)

What MarkItDown CANNOT do

  • OCR for scanned PDFs - it returns nothing. Scans require PyMuPDF4LLM or Docling.
  • Complex layouts with multiple columns - it may scramble the reading order.
  • Embedded URLs from PDFs - it doesn’t preserve them.

For simple PDFs (reports, articles, documentation), MarkItDown is the best choice: a versatile tool that installs in a minute and requires no Python knowledge. How it performs on documents with Cyrillic text and scans is shown in the measurements in the analysis of how to convert a PDF to text for AI.

Method 2: What does PyMuPDF4LLM offer, and when is it better?

Key takeaway

PyMuPDF4LLM is an Artifex Software project based on the native C MuPDF engine. It’s the fastest PDF converter (no GPU needed); smart OCR is applied only to unreadable regions and reduces processing time by 50%. It’s the only popular tool that preserves embedded URLs and images from PDFs. The drawback is its dual AGPL v3 / Artifex commercial license: for SaaS projects, AGPL means you must publish your code.

MarkItDown offers breadth of formats; PyMuPDF4LLM offers depth of PDF processing.

A lightweight PyMuPDF extension that turns PDFs into clean, structured data with minimal setup.

— Artifex Software, https://pymupdf.readthedocs.io/en/latest/pymupdf4llm/

The version as of May 31, 2026 is 1.27.2.3 (released April 24, 2026).

What’s included

  • Multi-column pages with the correct reading order
  • Tables converted into GitHub-flavored Markdown
  • Headers and footers removed automatically
  • Images extracted with relative links into a separate folder
  • Smart OCR: applied only to unreadable regions, saving ~50% of processing time
  • Native C engine, no GPU needed

Installation

pip install pymupdf4llm

Usage

import pymupdf4llm

# Basic use - straight to Markdown:
md_text = pymupdf4llm.to_markdown("document.pdf")

# Save it:
with open("document.md", "w") as f:
    f.write(md_text)

In one line, as promised:

python3 -c "import pymupdf4llm; \
  open('document.md','w').write(pymupdf4llm.to_markdown('document.pdf'))"

When to choose PyMuPDF4LLM over MarkItDown

  • When the PDF has many links that you need to preserve (MarkItDown loses them).
  • When the document is scanned and you need OCR.
  • When you need speed across thousands of files locally—the native C engine is faster than Python wrappers.
  • When you need images from the PDF in a separate folder for further processing.

Licensing detail (important for business)

PyMuPDF4LLM is dual-licensed: AGPL v3 OR Artifex commercial.

AGPL means: if you use the library in a public SaaS, you must publish your service’s entire source code under the same AGPL. For internal use (your script on your laptop), there are no restrictions.

For commercial development without disclosing code, buy a license from Artifex (artifex.com). Prices aren’t published; request them from sales.

If you’re building a product for clients, check the license at the start. MarkItDown (MIT) and Docling (MIT) are safer for SaaS.

Method 3: How do you connect the MarkItDown MCP server to Claude Code?

Key takeaway

The MarkItDown MCP server is the same MarkItDown wrapped in the MCP protocol, so Claude Code can convert PDFs on the fly without loading the original file into context. Connect it with a single command using uv; the version is pinned: markitdown-mcp@0.0.1a7. The tool Claude gets is convert_to_markdown(uri). Idle cost is ~110 tokens for the skill description, and zero when it isn’t needed.

MarkItDown in CLI mode means “I convert files manually in advance”; the MCP server means “Claude Code decides when to convert.”

Installation

You need the uv package manager. There’s no need to install the server separately; uv downloads it the first time it runs.

Configuration in Claude Code

One command connects the server to all your projects, with the version pinned:

claude mcp add --scope user --env 'ORT_DISABLE_TELEMETRY=1' --env 'UV_PYTHON=3.12' --transport stdio markitdown -- uvx markitdown-mcp@0.0.1a7
claude mcp list

The markitdown entry should say “Connected.” The first launch downloads about seventy packages and takes up to a minute; after that, the server starts in a second or two.

Here’s why the command needs the two variables. ORT_DISABLE_TELEMETRY=1 disables statistics that the onnxruntime engine inside the server sends to Microsoft by default on Mac and Linux. UV_PYTHON=3.12 runs the server on Python 3.12, for which prebuilt packages are available on Windows, Linux, and Macs with Apple Silicon. On Intel Macs and on macOS 13 and earlier, the server doesn’t install under Python 3.14. There’s a caveat for Intel and 3.12: uv will build the cryptography library from source because no prebuilt Intel package has been available since June 2026. Installation takes longer and may fail. If you don’t have Python 3.12, uv will download it for you.

The server runs directly on your computer and can open any file you have access to. If Claude Code was open, restart it, and markitdown will appear in the MCP server list.

How to use it

In Claude Code, simply say:

Convert /Users/your-user/Documents/report.pdf to Markdown and analyze the main points.

Claude calls convert_to_markdown(uri) itself, gets the Markdown, and works with it—the PDF isn’t loaded into the context at all.

Supported URIs

  • file:// - local files
  • http://, https:// - online documents
  • data: - inline data (Base64)

Security

From the official README:

The server does not support authorization and runs with the permissions of the user who launched it.

— Microsoft, https://github.com/microsoft/markitdown/tree/main/packages/markitdown-mcp

By default, it binds to localhost. If you run it over HTTP/SSE (option --http --host 127.0.0.1 --port 3001), don’t expose the port externally without an authenticated reverse proxy.

Which method should you choose for your task?

Key takeaway

MarkItDown is the all-rounder if you work with different formats (PDF + DOCX + PPTX + YouTube) and need a quick CLI command. PyMuPDF4LLM is the PDF specialist: faster, with OCR and link preservation, but an AGPL trap for SaaS. Docling is production-grade and handles tables and formulas best. Marker is for scientific papers with math. The MCP server is for when you don’t want to think about conversion and want Claude Code to decide for itself.

Extended comparison table:

ToolGitHub starsBest forSpeedLicense
MarkItDown (Microsoft)134kPDF + DOCX + PPTX + YouTube + audioMediumMIT
PyMuPDF4LLM (Artifex)-Native PDF, OCR, embedded URLsFastest (no GPU)AGPL v3 / commercial
Docling (IBM Research)60.7kProduction RAG, tables, formulasMediumMIT
Marker (datalab.to)35.6kScientific PDFs, arXiv, formulasHigh (with GPU)GPL-3.0 + Open Rail-M
MinerU-CJK documents (Chinese/Japanese)HighApache-2.0

Marker posts impressive accuracy figures on benchmarks:

0.18 seconds per page on an H100 GPU (122 pages per second). Accuracy of 95.67% versus Llamaparse (84.24%) and Mathpix (86.43%). On scientific papers, 96.67%.

— datalab.to, https://github.com/datalab-to/marker

But Marker requires a GPU for good speed and brings along machine-learning models. For most tasks (ordinary text PDFs), PyMuPDF4LLM or MarkItDown will do the job without a GPU in seconds.

A simple rule for choosing

  1. One or two PDFs, need it fast - MarkItDown CLI.
  2. Dozens of PDFs, need automation - MarkItDown MCP server or PyMuPDF4LLM in a script.
  3. PDFs with links and images where preserving structure matters - PyMuPDF4LLM.
  4. Production RAG for business where table stability matters - Docling.
  5. Scientific papers with formulas - Marker.
  6. Don’t want to think about it; let Claude convert it - MarkItDown MCP server.

How do you write a ready-to-use script to automatically convert a folder of documents?

Key takeaway

The most convenient pattern is a bash script that walks through a project folder, converts all PDFs, DOCX, and PPTX files to Markdown, and puts them in an _md/ subfolder. Set it up once, and any new folder of documents becomes “Claude-readable” in one pass. Then bring _md/ into Claude Code using @_md/ and work with the compressed text.

A practical example: imagine you have 40 PDF and PPTX reports from clients in one folder—brokerage statements, contracts, presentations. Uploading the folder straight into Claude is useless: the context window will fill with information before the first response. Run the whole folder through the script below in one pass, then continue working with lightweight .md files instead of bulky PDFs.

Save this script as scripts/docs-to-md.sh in the project root:

#!/bin/bash
# docs-to-md.sh - converts all documents in a folder to Markdown using MarkItDown
# Usage: bash docs-to-md.sh ./documents

set -e

INPUT_DIR="${1:-./documents}"
OUTPUT_DIR="${INPUT_DIR}/_md"

mkdir -p "$OUTPUT_DIR"

echo "Scanning $INPUT_DIR..."

for file in "$INPUT_DIR"/*.{pdf,docx,pptx,xlsx}; do
  [ -f "$file" ] || continue

  basename=$(basename "$file")
  name="${basename%.*}"
  output="$OUTPUT_DIR/${name}.md"

  if [ -f "$output" ] && [ "$output" -nt "$file" ]; then
    echo "Skipping $basename (already converted)"
    continue
  fi

  echo "Converting $basename..."
  markitdown "$file" > "$output"
done

echo "Done. Results are in $OUTPUT_DIR"

Make it executable:

chmod +x scripts/docs-to-md.sh

Run it:

bash scripts/docs-to-md.sh ./reports

After the run, ./reports/_md/ contains .md versions of all the documents. Bring them into Claude Code using @reports/_md/ and work with the compressed text instead of PDFs.

The script automatically skips files that have already been converted (if the .md file is newer than the source)—rerunning it is cheap and doesn’t recalculate everything.

Idempotency and incremental conversion

If you want the script to catch PDFs that have changed (were resaved under the same name), add a content-hash check:

hash=$(shasum -a 256 "$file" | cut -d' ' -f1)
hash_file="$OUTPUT_DIR/.${name}.sha256"

if [ -f "$hash_file" ] && [ "$(cat "$hash_file")" = "$hash" ]; then
  echo "Skipping $basename (hash matches)"
  continue
fi

markitdown "$file" > "$output"
echo "$hash" > "$hash_file"

This version reconverts a file only if its content has changed.

When is a PDF in Claude still better than Markdown?

Key takeaway

Markdown conversion loses three things: visual elements (diagrams, charts, blueprints), complex tables with merged cells and captions, and the document’s complete formatting as an artifact (for example, a contract you need to cite by page). If these things matter for the task, keep the PDF, enable visual analysis, and pay the visual cost knowingly.

Three cases where Markdown conversion falls short:

1. Visual analysis of diagrams and charts

If Claude needs to “read” a chart—a price curve, process diagram, or architecture diagram—that information isn’t in Markdown. Markdown preserves only figure captions; the figure itself is lost.

Solution: upload the PDF and explicitly enable visual mode. On the Claude API, the flag works automatically; on AWS Bedrock, you need the citations flag.

Claude analyzes both text and images to better understand the document.

— Anthropic, https://platform.claude.com/docs/en/docs/build-with-claude/pdf-support

2. Complex tables with merged cells

Markdown tables are flat. If the PDF has a table with merged cells, multi-level headers, or nested subtables, the converter will either flatten it or lose the relationships.

Solution: use the PDF directly, use Docling (it handles complex tables best), or manually format it after conversion.

3. Documents as artifacts with page references

For legal documents, contracts, and minutes, it matters that you can cite “page 7, paragraph 3.” Page numbers are lost in Markdown.

Solution: PDF + Files API + prompt caching. Upload it once, then refer to it by file_id; Claude sees the pagination and can cite specific pages.

Short documents

If a PDF is fewer than 2 pages and you use it once, conversion isn’t worth it. 5,000 tokens for a PDF versus 800 for Markdown isn’t enough savings to justify installing MarkItDown.

The break-even point is about 5+ pages or 2+ uses of the same document. Below that, upload the PDF directly; above that, convert it.

What are the 5 most common mistakes people make with PDFs in Claude?

Key takeaway

The main pitfalls: uploading the same PDF again in different chats instead of converting it once, not using prompt caching for repeat requests, using screenshots instead of text, failing to OCR scanned PDFs, and ignoring the 100-page limit for models with 200K context. Each mistake wastes tens of thousands of tokens for no good reason.

1. Uploading the same PDF in a new chat every time

Claude Pro has a message limit over 5 hours—one 50-page report can use it all up before you ask a second question.

There’s a simple principle for this: one task—one chat. When AI starts consuming an absurd number of tokens, it means you’re cramming everything into one chat and bringing the PDF in again and again. Keep one micro-task in each window. Convert the document to Markdown once, then add the .md file to every new window alongside the project. The context-window circle won’t turn yellow.

Solution: either convert it to Markdown once, or use the Files API with file_id and prompt caching.

2. A screenshot instead of text

A typical example: someone wants to show Claude a piece of code or a table, takes a screenshot of the entire 1920×1080 screen, and wonders why the limit ran out after 5 requests.

A 1000×1000-pixel screenshot costs ~1,300 tokens. The same text copied by hand costs 50–100 tokens. That’s a 13–26-fold difference.

Solution: crop screenshots tightly (to only the important part), or better yet, copy the text directly.

3. A scanned PDF without OCR

MarkItDown can’t do OCR. If you convert a scan, the result is an empty .md file (or 3 lines of noise).

Solution: for scans, use PyMuPDF4LLM (with its built-in smart OCR) or Docling.

4. Ignoring the 100-page limit

Anthropic’s documentation gives a limit of 600 pages per request—but in practice, the limit for models with 200K context (Sonnet 4.x, Opus 4.x) is 100 pages. The 600-page limit is intended for older models or special tiers.

If you upload a 150-page report to Sonnet 4.6, you’ll get an error or, worse, Claude will process only the first 100 pages and act as if it read the whole document.

Solution: split long PDFs into parts before uploading. Or convert them to Markdown—there’s no page limit, only a token limit.

5. Not using prompt caching for repeat requests

If you work with the same document through the API, wrap it in cache_control: ephemeral. Repeat calls within 5 minutes cost 10% of the initial price. One request costs more; the rest get a 90% discount.

Solution: enable prompt caching by default for anything you upload more than once.

What’s next: context engineering

Key takeaway

Converting PDFs to Markdown is one context-engineering technique, a new literacy for working with AI. A prompt is a question. Context is everything Claude sees before and around the question: the system prompt, CLAUDE.md, files, MCP servers, and session history. The cleaner the context, the more accurate the answer and the less it costs. Read the full analysis in the guide “Context Engineering in 2026.”

PDF-to-Markdown is one way to save tokens. By itself, it doesn’t make Claude’s answers more accurate. Accuracy comes from context engineering—the discipline of what you put into the model’s context before you ask a question.

If your CLAUDE.md has 800 lines, your project has 10 unnecessary MCP servers, and you bring in a 100-page PDF, Markdown conversion will prevent one leak, but the other three will remain. That’s why these guides cover:

Continue exploring Ailoot at ailoot.ai.

More details

Questions about PDFs in Claude Code: Conversion, Tokens, and Preserving Structure

How many Markdown tokens does the 15-page, four-chat example use?

Using the article’s assumption of 300 tokens per converted page, the total is 15 × 300 × 4 = 18,000 input tokens. That is an illustrative estimate; count the converted document’s tokens for your own file.

Is a text conversion enough for every PDF?

No. Inspect the converted Markdown against the PDF, especially tables, page order and content that depends on images. Compare token usage only after confirming that the information needed for your task survived conversion.

All articles