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+

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, 6 resources, and 5 prompts — compatible with Claude, GPT, and any MCP client.

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. Remote/hosted use (e.g. the OpenAI Responses API hosted MCP tool) needs an HTTP transport and is not yet exposed.

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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

oxidize_pdf-0.15.0.tar.gz (664.0 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

oxidize_pdf-0.15.0-cp310-abi3-win_amd64.whl (5.1 MB view details)

Uploaded CPython 3.10+Windows x86-64

oxidize_pdf-0.15.0-cp310-abi3-manylinux_2_28_x86_64.whl (5.7 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.28+ x86-64

oxidize_pdf-0.15.0-cp310-abi3-manylinux_2_28_aarch64.whl (5.8 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.28+ ARM64

oxidize_pdf-0.15.0-cp310-abi3-macosx_11_0_arm64.whl (5.2 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

oxidize_pdf-0.15.0-cp310-abi3-macosx_10_12_x86_64.whl (5.5 MB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

Details for the file oxidize_pdf-0.15.0.tar.gz.

File metadata

  • Download URL: oxidize_pdf-0.15.0.tar.gz
  • Upload date:
  • Size: 664.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for oxidize_pdf-0.15.0.tar.gz
Algorithm Hash digest
SHA256 876a9bc32893d06d1ec3da4fe274bc08fea00849d2f63f5a7791d2c6faad625e
MD5 fb95740b09b49bb381830c1b94b60a82
BLAKE2b-256 95f171c58c78e357778e2ffbebe5d34685738675490eb88eef6b36b2626b87d0

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxidize_pdf-0.15.0.tar.gz:

Publisher: release.yml on bzsanti/oxidize-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file oxidize_pdf-0.15.0-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: oxidize_pdf-0.15.0-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 5.1 MB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for oxidize_pdf-0.15.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 984e60d9c2efb987e6192eb75774922fdaab89f1e7d68855a71f428bf59030d2
MD5 ad626303c0771d6c82d97dbbf906fe4b
BLAKE2b-256 6264198a4e554baf09542df8f1ec8052ed60a522d75b2685be24a584c24c645c

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxidize_pdf-0.15.0-cp310-abi3-win_amd64.whl:

Publisher: release.yml on bzsanti/oxidize-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file oxidize_pdf-0.15.0-cp310-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for oxidize_pdf-0.15.0-cp310-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 ec574e3c73891728ce823fba97392fd8cb7d9639914ded5767433509429514cf
MD5 0d9e75734d2a1a4f7f82b9f5835274fe
BLAKE2b-256 c095fd928c1e64a1ba4ed18821d5d23a44d96345282ad95635bce1ed9f8fcbd7

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxidize_pdf-0.15.0-cp310-abi3-manylinux_2_28_x86_64.whl:

Publisher: release.yml on bzsanti/oxidize-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file oxidize_pdf-0.15.0-cp310-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for oxidize_pdf-0.15.0-cp310-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 3c5b211e49164c5f724a5900486251ce1ee448d62f748ddcd9fbd65a30014e97
MD5 bb8b0c87fc9916b19ee1698bfffde040
BLAKE2b-256 6335a7e26729fc421298ec5ba64fafdba941e0e14cc5d5f6b3af7968958226e2

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxidize_pdf-0.15.0-cp310-abi3-manylinux_2_28_aarch64.whl:

Publisher: release.yml on bzsanti/oxidize-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file oxidize_pdf-0.15.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for oxidize_pdf-0.15.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5db2f59cee2e131466183f7420dac742f3e975889fa100a4795f50c847c431cf
MD5 db0d481b0ea98d536f4a0b47261c41ee
BLAKE2b-256 b3be3370fca26253afbc809f25a24faffde08822aadbd1f3f0c319a080f96867

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxidize_pdf-0.15.0-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on bzsanti/oxidize-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file oxidize_pdf-0.15.0-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for oxidize_pdf-0.15.0-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 66a39301f92736821b66936c9106b084c54ab9ac20de923a905195d6d606302d
MD5 46c70d2c9c55768353681a1060437203
BLAKE2b-256 a4894e8ed7702c7a58e31ee2d209a2cde7441cd76d1efe4743202167a0ba9b56

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxidize_pdf-0.15.0-cp310-abi3-macosx_10_12_x86_64.whl:

Publisher: release.yml on bzsanti/oxidize-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page