oxidize-pdf
Kit de herramientas PDF impulsado por Rust sobre MCP: crear, leer y analizar PDFs; extraer texto y entidades para RAG; convertir a Markdown; dividir/combinar/rotar/reordenar páginas; gestionar campos de formulario y anotaciones; cifrar documentos. Se ejecuta localmente mediante uvx oxidize-mcp.
Documentación
oxidize-pdf
Biblioteca PDF impulsada por Rust para Python. Genera, analiza, divide, combina y manipula PDFs con rendimiento nativo. Incluye un servidor MCP integrado para que los agentes de IA puedan trabajar con PDFs sin configuración adicional.
Sin dependencias de C. Sin Java. Sin llamadas a subprocesos.
Instalación
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) Requiere: Python 3.10+
¿Por qué oxidize-pdf?
| oxidize-pdf | Pure-Python libs | C/Java wrappers | |
|---|---|---|---|
| Rendimiento | Nativo (Rust compilado) | Interpretado | Nativo pero pesado |
| Dependencias | Cero | Varía | Poppler, Java, Ghostscript |
| Seguridad de memoria | Modelo de propiedad de Rust | Dependiente del GC | Manual / GC |
| Stubs de tipos | Completo (mypy/pyright) | Parcial | Raro |
| Listo para IA (MCP) | Integrado | No | No |
Servidor MCP
Dale a tu agente de IA capacidades PDF completas en una línea:
oxidize-mcp
El servidor Model Context Protocol integrado expone 12 herramientas, 6 recursos y 5 indicaciones — compatible con Claude, GPT y cualquier cliente MCP.
Integración con Claude Desktop
Añade a tu claude_desktop_config.json:
{
"mcpServers": {
"oxidize-pdf": {
"command": "oxidize-mcp",
"env": {
"OXIDIZE_WORKSPACE": "/path/to/your/pdfs"
}
}
}
}
Integración con GitHub Copilot (VS Code)
El modo agente de Copilot habla MCP. Añade .vscode/mcp.json a tu espacio de trabajo:
{
"servers": {
"oxidize-pdf": {
"command": "oxidize-mcp",
"env": {
"OXIDIZE_WORKSPACE": "/path/to/your/pdfs"
}
}
}
}
Abre la vista de Chat, cambia al modo Agente y las 12 herramientas PDF aparecerán en el selector de herramientas. (El mismo bloque también funciona bajo la clave mcp.servers en tu settings.json de usuario si prefieres una instalación global.)
Integración con OpenAI Agents SDK
El OpenAI Agents SDK inicia el servidor sobre stdio y expone sus herramientas a un 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)
Una versión ejecutable está en examples/openai_agents_quickstart.py.
Ambas integraciones ejecutan el servidor localmente sobre stdio, por lo que sus herramientas operan sobre PDFs en el directorio de espacio de trabajo configurado. El uso remoto/alojado (por ejemplo, la herramienta MCP alojada de OpenAI Responses API) necesita un transporte HTTP y aún no está expuesto.
Herramientas disponibles
| Herramienta | Qué hace |
|---|---|
read_pdf | Lee metadatos — número de páginas, versión, estado de cifrado, título, autor |
extract_text | Extrae texto de todas las páginas o de una página específica |
convert_pdf | Convierte a markdown, fragmentos o formato optimizado para RAG |
create_pdf | Crea un nuevo PDF con metadatos opcionales |
save_pdf | Guarda una sesión en disco, con cifrado opcional |
add_content | Añade páginas, texto y gráficos a una sesión |
annotate_pdf | Añade anotaciones de texto y resaltados |
manipulate_pdf | Divide, combina, rota, extrae páginas, invierte, superpone |
manage_forms | Crea, rellena, lee y valida campos de formulario |
secure_pdf | Cifra, comprueba permisos, verifica firmas |
extract_entities | Extrae entidades estructuradas de las páginas |
analyze_pdf | Valida la estructura, detecta corrupción, comprueba el cumplimiento PDF/A |
El servidor también expone recursos (datos de sesión, capacidades, información de versión) e indicaciones (flujos de trabajo guiados para resumen, extracción de datos, relleno de formularios y más).
Configuración
OXIDIZE_WORKSPACE=/path/to/pdfs oxidize-mcp
El servidor se configura completamente mediante variables de entorno:
| Variable | Predeterminado | Propósito |
|---|---|---|
OXIDIZE_WORKSPACE | ~/Documents/oxidize-mcp | Raíz del sandbox; todas las rutas deben resolverse dentro de ella. |
OXIDIZE_ALLOWED_PATHS | (ninguno) | Directorios adicionales separados por comas permitidos fuera del espacio de trabajo. |
OXIDIZE_MAX_FILE_SIZE_MB | 100 | Rechaza PDFs de entrada más grandes que esto en disco. |
OXIDIZE_MAX_PAGES | 10000 | Rechaza documentos con más páginas que esto antes de cualquier trabajo de extracción. |
OXIDIZE_MAX_OUTPUT_BYTES | 10485760 | Limita el tamaño serializado de la respuesta JSON de una herramienta (10 MB). |
OXIDIZE_MAX_SESSIONS | 10 | Máximo de sesiones concurrentes de creación de PDF con estado. |
OXIDIZE_MAX_SESSION_BYTES | 10485760 | Limita el contenido que una sola sesión puede acumular (10 MB). |
OXIDIZE_SESSION_TIMEOUT | 3600 | Caducidad de la sesión, en segundos. |
Los límites de recursos (OXIDIZE_MAX_*) protegen al servidor de un PDF grande o malicioso: los documentos sobredimensionados se rechazan de antemano y las respuestas de las herramientas están limitadas en lugar de serializarse sin límite. Superar un límite devuelve un error con código RESOURCE_LIMIT.
O iniciar programáticamente:
from oxidize_pdf.mcp.server import run
run()
API de Python
Crear un 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")
Analizar un 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)
Operaciones
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
Manejo de errores
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}")
Jerarquía de excepciones: PdfError > PdfIoError, PdfParseError, PdfEncryptionError, PdfPermissionError
Servidor MCP
oxidize-pdf incluye un servidor MCP que expone capacidades PDF a asistentes de IA como Claude. Instala con el extra mcp:
pip install oxidize-pdf[mcp]
Claude Desktop
Añade esto a tu 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
Herramientas disponibles
| Herramienta | Descripción |
|---|---|
read_pdf | Abre un PDF y obtén metadatos (páginas, versión, cifrado) |
extract_text | Extrae contenido de texto de las páginas del PDF |
convert_pdf | Convierte entre versiones de PDF |
analyze_pdf | Analiza estructura, fuentes, imágenes y cumplimiento |
extract_entities | Extrae imágenes y firmas digitales |
manipulate_pdf | Divide, combina, rota, extrae y reordena páginas |
annotate_pdf | Añade anotaciones de texto, resaltados y sellos |
manage_forms | Crea, rellena y lee campos de formulario PDF |
secure_pdf | Cifra, descifra y establece permisos de documento |
create_pdf | Crea un nuevo documento PDF con páginas |
add_pdf_content | Añade texto, formas e imágenes a las páginas |
save_pdf | Guarda el documento en archivo o bytes |
Recursos
oxidize://fonts— Fuentes PDF integradas disponiblesoxidize://page-sizes— Tamaños de página estándar con dimensionesoxidize://capabilities— Capacidades del servidor y listado de herramientasoxidize://version— Información de versiónoxidize://workspace— Archivos PDF en el directorio del espacio de trabajooxidize://session/{id}— Datos de sesión por ID
Limitaciones conocidas
- Soporte de escritura de cifrado:
Document.encrypt()configura los parámetros de cifrado, pero la biblioteca Rust subyacente aún no serializa el diccionario de cifrado en la salida del PDF. La lectura de PDFs cifrados funciona correctamente. - La extracción de imágenes devuelve flujos incrustados sin procesar:
extract_images_from_pdfextrae cada imagen incrustada tal cual (por ejemplo, un JPEGDCTDecodese escribe byte a byte). El preprocesamiento de imágenes — corrección automática de rotación, mejora de contraste, reducción de ruido, ampliación, forzar escala de grises — no está disponible, porque la compilación excluye la característicaexternal-imagesupstream (y su dependencia de crateimage). Esto mantiene la extracción fiel y sin pérdidas; no devuelve silenciosamente resultados vacíos o simulados. - Solo CPython: PyPy y GraalPy no son compatibles.
Licencia
MIT — consulta LICENSE para más detalles.