oxidize-pdf

Kit de ferramentas PDF baseado em Rust sobre MCP: criar, ler e analisar PDFs; extrair texto e entidades para RAG; converter para Markdown; dividir/mesclar/rotacionar/reordenar páginas; gerenciar campos de formulário e anotações; criptografar documentos. Executa localmente via uvx oxidize-mcp.

Documentação

oxidize-pdf

PyPI version CI License: MIT Python Typed MCP

oxidize-python MCP server

Biblioteca PDF com tecnologia Rust para Python. Gere, analise, divida, mescle e manipule PDFs com desempenho nativo. Inclui um servidor MCP integrado para que agentes de IA possam trabalhar com PDFs imediatamente.

Sem dependências C. Sem Java. Sem chamadas de subprocesso.

Instalação

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

Plataformas: Linux (x86_64, aarch64) | macOS (x86_64, Apple Silicon) | Windows (x86_64) Requer: Python 3.10+

Por que oxidize-pdf?

oxidize-pdfBibliotecas Python purasWrappers C/Java
DesempenhoNativo (Rust compilado)InterpretadoNativo, porém pesado
DependênciasZeroVariávelPoppler, Java, Ghostscript
Segurança de memóriaModelo de propriedade do RustDependente de GCManual / GC
Stubs de tipoCompleto (mypy/pyright)ParcialRaro
Pronto para IA (MCP)IntegradoNãoNão

Servidor MCP

Dê ao seu agente de IA todos os recursos de PDF em uma linha:

oxidize-mcp

O servidor integrado Model Context Protocol expõe 12 ferramentas, 6 recursos e 5 prompts — compatível com Claude, GPT e qualquer cliente MCP.

Integração com Claude Desktop

Adicione ao seu claude_desktop_config.json:

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

Integração com GitHub Copilot (VS Code)

O modo agente do Copilot fala MCP. Adicione .vscode/mcp.json ao seu workspace:

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

Abra a visualização de Chat, mude para o modo Agente, e as 12 ferramentas de PDF aparecem no seletor de ferramentas. (O mesmo bloco também funciona sob a chave mcp.servers no seu settings.json de usuário, se preferir uma instalação global.)

Integração com OpenAI Agents SDK

O OpenAI Agents SDK inicia o servidor via stdio e expõe suas ferramentas a um agente:

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)

Uma versão executável está em examples/openai_agents_quickstart.py.

Ambas as integrações executam o servidor localmente via stdio, então suas ferramentas operam em PDFs no diretório de workspace configurado. O uso remoto/hospedado (por exemplo, a ferramenta MCP hospedada da OpenAI Responses API) requer transporte HTTP e ainda não está exposto.

Ferramentas disponíveis

FerramentaO que faz
read_pdfLê metadados — contagem de páginas, versão, status de criptografia, título, autor
extract_textExtrai texto de todas as páginas ou de uma página específica
convert_pdfConverte para markdown, chunks ou formato otimizado para RAG
create_pdfCria um novo PDF com metadados opcionais
save_pdfSalva uma sessão em disco, com criptografia opcional
add_contentAdiciona páginas, texto e gráficos a uma sessão
annotate_pdfAdiciona anotações de texto e realces
manipulate_pdfDivide, mescla, rotaciona, extrai páginas, inverte, sobrepõe
manage_formsCria, preenche, lê e valida campos de formulário
secure_pdfCriptografa, verifica permissões, confere assinaturas
extract_entitiesExtrai entidades estruturadas de páginas
analyze_pdfValida estrutura, detecta corrupção, verifica conformidade com PDF/A

O servidor também expõe recursos (dados de sessão, capacidades, informações de versão) e prompts (fluxos de trabalho guiados para sumarização, extração de dados, preenchimento de formulários e mais).

Configuração

OXIDIZE_WORKSPACE=/path/to/pdfs oxidize-mcp

O servidor é configurado inteiramente por meio de variáveis de ambiente:

VariávelPadrãoFinalidade
OXIDIZE_WORKSPACE~/Documents/oxidize-mcpRaiz do sandbox; todos os caminhos devem resolver dentro dela.
OXIDIZE_ALLOWED_PATHS(nenhum)Diretórios extras separados por vírgula permitidos fora do workspace.
OXIDIZE_MAX_FILE_SIZE_MB100Rejeita PDFs de entrada maiores que isso em disco.
OXIDIZE_MAX_PAGES10000Rejeita documentos com mais páginas do que isso antes de qualquer trabalho de extração.
OXIDIZE_MAX_OUTPUT_BYTES10485760Limita o tamanho serializado da resposta JSON de uma ferramenta (10 MB).
OXIDIZE_MAX_SESSIONS10Máximo de sessões simultâneas de criação de PDF com estado.
OXIDIZE_MAX_SESSION_BYTES10485760Limita o conteúdo que uma única sessão pode acumular (10 MB).
OXIDIZE_SESSION_TIMEOUT3600Expiração da sessão, em segundos.

Os limites de recursos (OXIDIZE_MAX_*) protegem o servidor contra PDFs grandes ou maliciosos: documentos superdimensionados são rejeitados antecipadamente e as respostas das ferramentas são limitadas em vez de serializadas sem limite. Exceder um limite retorna um erro com código RESOURCE_LIMIT.

Ou inicie programaticamente:

from oxidize_pdf.mcp.server import run
run()

API Python

Criar um 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")

Analisar um PDF existente

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)

Operações

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

Gráficos

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")

Tipos

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

Tratamento de erros

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}")

Hierarquia de exceções: PdfError > PdfIoError, PdfParseError, PdfEncryptionError, PdfPermissionError

Servidor MCP

oxidize-pdf inclui um servidor MCP que expõe recursos de PDF a assistentes de IA como o Claude. Instale com o extra mcp:

pip install oxidize-pdf[mcp]

Claude Desktop

Adicione isso ao seu 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

Ferramentas disponíveis

FerramentaDescrição
read_pdfAbre um PDF e obtém metadados (páginas, versão, criptografia)
extract_textExtrai conteúdo de texto de páginas de PDF
convert_pdfConverte entre versões de PDF
analyze_pdfAnalisa estrutura, fontes, imagens e conformidade
extract_entitiesExtrai imagens e assinaturas digitais
manipulate_pdfDivide, mescla, rotaciona, extrai e reordena páginas
annotate_pdfAdiciona anotações de texto, realces e carimbos
manage_formsCria, preenche e lê campos de formulário de PDF
secure_pdfCriptografa, descriptografa e define permissões de documento
create_pdfCria um novo documento PDF com páginas
add_pdf_contentAdiciona texto, formas e imagens às páginas
save_pdfSalva o documento em arquivo ou bytes

Recursos

  • oxidize://fonts — Fontes de PDF integradas disponíveis
  • oxidize://page-sizes — Tamanhos de página padrão com dimensões
  • oxidize://capabilities — Capacidades do servidor e listagem de ferramentas
  • oxidize://version — Informações de versão
  • oxidize://workspace — Arquivos PDF no diretório do workspace
  • oxidize://session/{id} — Dados de sessão por ID

Limitações conhecidas

  • Suporte a escrita de criptografia: Document.encrypt() configura parâmetros de criptografia, mas a biblioteca Rust subjacente ainda não serializa o dicionário de criptografia na saída do PDF. A leitura de PDFs criptografados funciona corretamente.
  • A extração de imagens retorna fluxos incorporados brutos: extract_images_from_pdf extrai cada imagem incorporada como está (por exemplo, um JPEG DCTDecode é gravado byte a byte). O pré-processamento de imagem — correção automática de rotação, aprimoramento de contraste, redução de ruído, upscaling, forçar escala de cinza — não está disponível, porque a compilação exclui o recurso external-images upstream (e sua dependência do crate image). Isso mantém a extração fiel e sem perdas; não retorna silenciosamente resultados vazios ou simulados.
  • Somente CPython: PyPy e GraalPy não são suportados.

Licença

MIT — veja LICENSE para detalhes.