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
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-pdf | Bibliotecas Python puras | Wrappers C/Java | |
|---|---|---|---|
| Desempenho | Nativo (Rust compilado) | Interpretado | Nativo, porém pesado |
| Dependências | Zero | Variável | Poppler, Java, Ghostscript |
| Segurança de memória | Modelo de propriedade do Rust | Dependente de GC | Manual / GC |
| Stubs de tipo | Completo (mypy/pyright) | Parcial | Raro |
| Pronto para IA (MCP) | Integrado | Não | Nã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
| Ferramenta | O que faz |
|---|---|
read_pdf | Lê metadados — contagem de páginas, versão, status de criptografia, título, autor |
extract_text | Extrai texto de todas as páginas ou de uma página específica |
convert_pdf | Converte para markdown, chunks ou formato otimizado para RAG |
create_pdf | Cria um novo PDF com metadados opcionais |
save_pdf | Salva uma sessão em disco, com criptografia opcional |
add_content | Adiciona páginas, texto e gráficos a uma sessão |
annotate_pdf | Adiciona anotações de texto e realces |
manipulate_pdf | Divide, mescla, rotaciona, extrai páginas, inverte, sobrepõe |
manage_forms | Cria, preenche, lê e valida campos de formulário |
secure_pdf | Criptografa, verifica permissões, confere assinaturas |
extract_entities | Extrai entidades estruturadas de páginas |
analyze_pdf | Valida 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ável | Padrão | Finalidade |
|---|---|---|
OXIDIZE_WORKSPACE | ~/Documents/oxidize-mcp | Raiz 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_MB | 100 | Rejeita PDFs de entrada maiores que isso em disco. |
OXIDIZE_MAX_PAGES | 10000 | Rejeita documentos com mais páginas do que isso antes de qualquer trabalho de extração. |
OXIDIZE_MAX_OUTPUT_BYTES | 10485760 | Limita o tamanho serializado da resposta JSON de uma ferramenta (10 MB). |
OXIDIZE_MAX_SESSIONS | 10 | Máximo de sessões simultâneas de criação de PDF com estado. |
OXIDIZE_MAX_SESSION_BYTES | 10485760 | Limita o conteúdo que uma única sessão pode acumular (10 MB). |
OXIDIZE_SESSION_TIMEOUT | 3600 | Expiraçã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
| Ferramenta | Descrição |
|---|---|
read_pdf | Abre um PDF e obtém metadados (páginas, versão, criptografia) |
extract_text | Extrai conteúdo de texto de páginas de PDF |
convert_pdf | Converte entre versões de PDF |
analyze_pdf | Analisa estrutura, fontes, imagens e conformidade |
extract_entities | Extrai imagens e assinaturas digitais |
manipulate_pdf | Divide, mescla, rotaciona, extrai e reordena páginas |
annotate_pdf | Adiciona anotações de texto, realces e carimbos |
manage_forms | Cria, preenche e lê campos de formulário de PDF |
secure_pdf | Criptografa, descriptografa e define permissões de documento |
create_pdf | Cria um novo documento PDF com páginas |
add_pdf_content | Adiciona texto, formas e imagens às páginas |
save_pdf | Salva o documento em arquivo ou bytes |
Recursos
oxidize://fonts— Fontes de PDF integradas disponíveisoxidize://page-sizes— Tamanhos de página padrão com dimensõesoxidize://capabilities— Capacidades do servidor e listagem de ferramentasoxidize://version— Informações de versãooxidize://workspace— Arquivos PDF no diretório do workspaceoxidize://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_pdfextrai cada imagem incorporada como está (por exemplo, um JPEGDCTDecodeé 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 recursoexternal-imagesupstream (e sua dependência do crateimage). 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.