Skip to main content

oxidize-pdf

PyPI version CI License: MIT Python Typed MCP

oxidize-python MCP server

Rust-powered PDF library for Python. Generate, parse, split, merge, and manipulate PDFs with native performance. Ships with a built-in MCP server so AI agents can work with PDFs out of the box.

No C dependencies. No Java. No subprocess calls.

Installation

pip install oxidize-pdf            # Core library
pip install "oxidize-pdf[mcp]"     # + MCP server for AI agents

Platforms: Linux (x86_64, aarch64) | macOS (x86_64, Apple Silicon) | Windows (x86_64) Requires: Python 3.10+

Version 0.19.0 pins Rust core 5.1.3. See the upstream integration review for new extraction options, compatibility details and pending integrations.

Why oxidize-pdf?

oxidize-pdf Pure-Python libs C/Java wrappers
Performance Native (compiled Rust) Interpreted Native but heavy
Dependencies Zero Varies Poppler, Java, Ghostscript
Memory safety Rust ownership model GC-dependent Manual / GC
Type stubs Full (mypy/pyright) Partial Rare
AI-ready (MCP) Built-in No No

MCP Server

Give your AI agent full PDF capabilities in one line:

oxidize-mcp

The built-in Model Context Protocol server exposes 12 tools, 5 static resources plus a session resource template, and 5 prompts over stdio. Install oxidize-pdf[mcp] to include its dependencies; the base library keeps MCP optional.

Version 0.20 uses FastMCP 4 and MCP Python SDK 2, with support for both modern and legacy stdio clients. See the migration guide for versions and installation routes.

Claude Desktop integration

Add to your claude_desktop_config.json:

{
  "mcpServers": {
    "oxidize-pdf": {
      "command": "oxidize-mcp",
      "env": {
        "OXIDIZE_WORKSPACE": "/path/to/your/pdfs"
      }
    }
  }
}

GitHub Copilot (VS Code) integration

Copilot's agent mode speaks MCP. Add .vscode/mcp.json to your workspace:

{
  "servers": {
    "oxidize-pdf": {
      "command": "oxidize-mcp",
      "env": {
        "OXIDIZE_WORKSPACE": "/path/to/your/pdfs"
      }
    }
  }
}

Open the Chat view, switch to Agent mode, and the 12 PDF tools appear in the tool picker. (The same block also works under the mcp.servers key in your user settings.json if you prefer a global install.)

OpenAI Agents SDK integration

The OpenAI Agents SDK spawns the server over stdio and exposes its tools to an agent:

from agents import Agent, Runner
from agents.mcp import MCPServerStdio

async with MCPServerStdio(
    params={"command": "oxidize-mcp", "env": {"OXIDIZE_WORKSPACE": "/path/to/your/pdfs"}},
    cache_tools_list=True,
) as server:
    agent = Agent(
        name="PDF assistant",
        instructions="Use the oxidize-pdf tools to inspect and manipulate PDFs.",
        mcp_servers=[server],
    )
    result = await Runner.run(agent, "How many pages does report.pdf have?")
    print(result.final_output)

A runnable version is in examples/openai_agents_quickstart.py.

Both integrations run the server locally over stdio, so its tools operate on PDFs in the configured workspace directory. This package does not expose a hosted HTTP endpoint. ChatGPT web needs a remote connection; developer-mode testing can also use Secure MCP Tunnel with a local stdio server. No ChatGPT plugin is published by this migration.

Available tools

Tool What it does
read_pdf Read metadata — page count, version, encryption status, title, author
extract_text Extract text from all pages or a specific page
convert_pdf Convert to markdown, chunks, or RAG-optimized format
create_pdf Create a new PDF with optional metadata
save_pdf Save a session to disk, with optional encryption
add_content Add pages, text, and graphics to a session
annotate_pdf Add text annotations and highlights
manipulate_pdf Split, merge, rotate, extract pages, reverse, overlay
manage_forms Create, fill, read, and validate form fields
secure_pdf Encrypt, check permissions, verify signatures
extract_entities Extract structured entities from pages
analyze_pdf Validate structure, detect corruption, check PDF/A compliance

The server also exposes resources (session data, capabilities, version info) and prompts (guided workflows for summarization, data extraction, form filling, and more).

Configuration

OXIDIZE_WORKSPACE=/path/to/pdfs oxidize-mcp

The server is configured entirely through environment variables:

Variable Default Purpose
OXIDIZE_WORKSPACE ~/Documents/oxidize-mcp Sandbox root; all paths must resolve inside it.
OXIDIZE_ALLOWED_PATHS (none) Comma-separated extra directories allowed outside the workspace.
OXIDIZE_MAX_FILE_SIZE_MB 100 Reject input PDFs larger than this on disk.
OXIDIZE_MAX_PAGES 10000 Reject documents with more pages than this before any extraction work.
OXIDIZE_MAX_OUTPUT_BYTES 10485760 Cap the serialized size of a tool's JSON response (10 MB).
OXIDIZE_MAX_SESSIONS 10 Maximum concurrent stateful PDF-creation sessions.
OXIDIZE_MAX_SESSION_BYTES 10485760 Cap the content a single session may accumulate (10 MB).
OXIDIZE_SESSION_TIMEOUT 3600 Session expiry, in seconds.

Resource caps (OXIDIZE_MAX_*) protect the server from a large or malicious PDF: oversized documents are rejected up front and tool responses are bounded rather than serialized unbounded. Exceeding a cap returns an error with code RESOURCE_LIMIT.

Or start programmatically:

from oxidize_pdf.mcp.server import run
run()

Python API

Create a PDF

from oxidize_pdf import Document, Page, Font, Color

doc = Document()
doc.set_title("My Document")
doc.set_author("Jane Doe")

page = Page.a4()
page.set_font(Font.HELVETICA, 24.0)
page.set_text_color(Color.black())
page.text_at(72.0, 750.0, "Hello from oxidize-pdf!")

page.set_font(Font.TIMES_ROMAN, 12.0)
page.text_at(72.0, 700.0, "Generated with Python + Rust.")

doc.add_page(page)
doc.save("output.pdf")

Parse an existing PDF

from oxidize_pdf import PdfReader

reader = PdfReader.open("document.pdf")
print(f"Pages: {reader.page_count}, Version: {reader.version}")

for i, text in enumerate(reader.extract_text()):
    print(f"--- Page {i + 1} ---")
    print(text)

Operations

from oxidize_pdf import split_pdf, merge_pdfs, rotate_pdf, extract_pages

split_pdf("input.pdf", "output_dir/")                       # Split into individual pages
merge_pdfs(["part1.pdf", "part2.pdf"], "merged.pdf")         # Merge multiple PDFs
rotate_pdf("input.pdf", "rotated.pdf", 90)                   # Rotate all pages
extract_pages("input.pdf", "subset.pdf", [0, 2, 4])          # Extract specific pages

Graphics

from oxidize_pdf import Document, Page, Color

doc = Document()
page = Page.a4()

page.set_fill_color(Color.hex("#3498db"))
page.draw_rect(72.0, 700.0, 200.0, 100.0)
page.fill()

page.set_stroke_color(Color.red())
page.set_line_width(2.0)
page.draw_circle(300.0, 500.0, 50.0)
page.stroke()

doc.add_page(page)
doc.save("graphics.pdf")

Types

from oxidize_pdf import Color, Point, Rectangle, Margins, Font

# Colors
Color.rgb(1.0, 0.0, 0.0)          # RGB
Color.hex("#ff6600")               # Hex
Color.cmyk(0.0, 1.0, 1.0, 0.0)   # CMYK

# Geometry
Point(72.0, 720.0)
Rectangle.from_xywh(72.0, 72.0, 468.0, 648.0)
Margins.uniform(72.0)

# Fonts — all 14 standard PDF fonts
Font.HELVETICA    # Font.HELVETICA_BOLD
Font.TIMES_ROMAN  # Font.TIMES_BOLD
Font.COURIER      # Font.COURIER_BOLD

Error handling

from oxidize_pdf import PdfReader, PdfError, PdfIoError, PdfParseError

try:
    reader = PdfReader.open("missing.pdf")
except PdfIoError as e:
    print(f"I/O error: {e}")
except PdfParseError as e:
    print(f"Parse error: {e}")
except PdfError as e:
    print(f"PDF error: {e}")

Exception hierarchy: PdfError > PdfIoError, PdfParseError, PdfEncryptionError, PdfPermissionError

MCP Server

oxidize-pdf includes an MCP server that exposes PDF capabilities to AI assistants like Claude. Install with the mcp extra:

pip install oxidize-pdf[mcp]

Claude Desktop

Add this to your claude_desktop_config.json:

{
  "mcpServers": {
    "oxidize-pdf": {
      "command": "uvx",
      "args": ["--from", "oxidize-pdf[mcp]", "oxidize-mcp"]
    }
  }
}

Claude Code

claude mcp add oxidize-pdf -- uvx --from "oxidize-pdf[mcp]" oxidize-mcp

Available tools

Tool Description
read_pdf Open a PDF and get metadata (pages, version, encryption)
extract_text Extract text content from PDF pages
convert_pdf Convert between PDF versions
analyze_pdf Analyze structure, fonts, images, and compliance
extract_entities Extract images and digital signatures
manipulate_pdf Split, merge, rotate, extract, and reorder pages
annotate_pdf Add text annotations, highlights, and stamps
manage_forms Create, fill, and read PDF form fields
secure_pdf Encrypt, decrypt, and set document permissions
create_pdf Create a new PDF document with pages
add_pdf_content Add text, shapes, and images to pages
save_pdf Save the document to file or bytes

Resources

  • oxidize://fonts — Available built-in PDF fonts
  • oxidize://page-sizes — Standard page sizes with dimensions
  • oxidize://capabilities — Server capabilities and tool listing
  • oxidize://version — Version information
  • oxidize://workspace — PDF files in the workspace directory
  • oxidize://session/{id} — Session data by ID

Known limitations

  • Encryption write support: Document.encrypt() configures encryption parameters but the underlying Rust library does not yet serialize the encryption dictionary to the PDF output. Reading encrypted PDFs works correctly.
  • Image extraction returns raw embedded streams: extract_images_from_pdf extracts each embedded image as-is (e.g. a DCTDecode JPEG is written byte-for-byte). Image preprocessing — auto rotation-correction, contrast enhancement, denoise, upscaling, force-grayscale — is not available, because the build excludes the upstream external-images feature (and its image-crate dependency). This keeps extraction faithful and lossless; it does not silently return empty or stub results.
  • CPython only: PyPy and GraalPy are not supported.

License

MIT — see LICENSE for details.

Release files for oxidize-pdf 0.20.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for oxidize-pdf 0.20.0
File Size Uploaded
oxidize_pdf-0.20.0.tar.gz 706.6 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for oxidize-pdf 0.20.0
File
oxidize_pdf-0.20.0-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
oxidize_pdf-0.20.0-cp310-abi3-manylinux_2_28_x86_64.whl CPython 3.10 abi3 Linux glibc 2.28+ x86-64 Details
oxidize_pdf-0.20.0-cp310-abi3-manylinux_2_28_aarch64.whl CPython 3.10 abi3 Linux glibc 2.28+ ARM64 Details
oxidize_pdf-0.20.0-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details
oxidize_pdf-0.20.0-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details

Total release size: 32.2 MB

Release files / oxidize_pdf-0.20.0.tar.gz

Download URL oxidize_pdf-0.20.0.tar.gz
Size 706.6 kB
Tags Source
SHA-256 checksum
How to use checksums
8bc17cfdaf60f2ca8c53facff2ceb5f0b7a6c5a512e9e344bb3a91cd834e540f
BLAKE2b-256 checksum
How to use checksums
ef22fa1c8166fdae7b3927be647968b333e2a288b0e3318a0f4c162af894c753
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release files / oxidize_pdf-0.20.0-cp310-abi3-win_amd64.whl

Download URL oxidize_pdf-0.20.0-cp310-abi3-win_amd64.whl
Size 5.9 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
b758e29fdef9a87366e779971bcd4131ddf843925f0791ab4d3fa8f6ad1e458a
BLAKE2b-256 checksum
How to use checksums
3bfe27c9e2dbece142e10a8fea14f3b3d0b11fb03e0b279c5fea701f94e2a97e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release files / oxidize_pdf-0.20.0-cp310-abi3-manylinux_2_28_x86_64.whl

Download URL oxidize_pdf-0.20.0-cp310-abi3-manylinux_2_28_x86_64.whl
Size 6.6 MB
Tags CPython 3.10 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
4fce450c98533e7818d90b84b1c72dd4f6945f1615a7635679fa5cc479ea59ab
BLAKE2b-256 checksum
How to use checksums
d476b83de37c5b19036ec9b60aface630ab5d5a830733e519f00bd720651d7ce
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release files / oxidize_pdf-0.20.0-cp310-abi3-manylinux_2_28_aarch64.whl

Download URL oxidize_pdf-0.20.0-cp310-abi3-manylinux_2_28_aarch64.whl
Size 6.6 MB
Tags CPython 3.10 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
71352195f7d6d45249ce075c3dd72b9d3e3ba20eca43373b2affe6484c6287c5
BLAKE2b-256 checksum
How to use checksums
ed07cb3cf776ff2955387a037c76dfec604b423330dbd6f0a571ade0f7eb8030
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release files / oxidize_pdf-0.20.0-cp310-abi3-macosx_11_0_arm64.whl

Download URL oxidize_pdf-0.20.0-cp310-abi3-macosx_11_0_arm64.whl
Size 6.0 MB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
4c185e4c083ca6eec48f994cec97870f387759b7120021a74aac0d00bcb52010
BLAKE2b-256 checksum
How to use checksums
867213c8d75dba9dab928b591d6180a80d3f45d412931e7b76cec1b4a7be34c1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release files / oxidize_pdf-0.20.0-cp310-abi3-macosx_10_12_x86_64.whl

Download URL oxidize_pdf-0.20.0-cp310-abi3-macosx_10_12_x86_64.whl
Size 6.3 MB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
0b162360aeb47eab69ded00d81287ec5a771577863b828e8a0617b0f55db5212
BLAKE2b-256 checksum
How to use checksums
237d64ee928622c207e52f8f1f0a96f008f6f62dfbff3ccb8cf28ef17d606424
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.20.0 This release

6 release files

0.19.0

6 release files

0.18.0

6 release files

0.17.0

6 release files

0.16.0

6 release files

0.15.1

6 release files

0.15.0

6 release files

0.14.0

6 release files

0.13.0

6 release files

0.12.0

6 release files

0.11.0

6 release files

0.9.0

29 release files

0.6.0

29 release files

0.5.2

29 release files

0.5.1

29 release files

0.4.3

28 release files

0.4.2

28 release files

0.4.1

28 release files

0.4.0

28 release files

0.3.1

28 release files

0.3.0

28 release files

0.2.1

28 release files

0.2.0

28 release files

0.1.1

28 release files

0.1.0

28 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page