pdfnative

Motor de PDF local para agentes de IA. TypeScript sin dependencias, PDF/A, firmas, 800+ páginas/segundo.

Documentación

pdfnative-mcp

Servidor de Model Context Protocol (MCP) que conecta la librería pdfnative — un motor PDF sin dependencias y compatible con ISO 32000-1 — con cualquier cliente de IA compatible con MCP (Claude Desktop, Cursor, Continue, ChatGPT, Zed, …).

npm version npm downloads Node version License: MIT CI MCP TypeScript OpenSSF Scorecard CodeQL


✨ Características

pdfnative-mcp expone 24 herramientas de nivel profesional a cualquier host MCP:

HerramientaPropósito
generate_basic_pdfDocumentos A4 multipágina a partir de bloques estructurados (encabezados, párrafos, listas, saltos de página). Los saltos de línea incrustados se dividen automáticamente en párrafos. pdfA opcional.
add_barcodeCódigo QR, Code 128, EAN-13, Data Matrix, PDF417 — incrustados en un PDF de una sola página.
add_international_text24 scripts (incl. Latin y emoji de color COLRv1) con conformado BiDi y OpenType; multi-idioma por documento.
add_tableInformes tabulares con campos inteligentes (wrap, repeatHeader, zebra, caption, minRowHeight, cellPadding).
add_formCrear un nuevo PDF AcroForm interactivo con campos de texto, casillas de verificación, botones de opción, listas desplegables.
read_form_fields (nuevo en v1.5.0)Enumeración de solo lectura del árbol de campos de un AcroForm existente (nombres, tipos, valores, widgets).
fill_form (nuevo en v1.5.0)Rellenar y/o aplanar un AcroForm existente (actualización incremental no destructiva).
add_chart (nuevo en v1.5.0)Gráficos vectoriales nativos — barras / barras horizontales / líneas / circular / donut (operadores de ruta PDF puros, seguro para PDF/A).
embed_imageIncrustar una imagen JPEG o PNG (base64) en un documento PDF con título.
prepare_signature_placeholderPaso 1 del flujo de firma en dos pasos — crear un PDF con un marcador de posición AcroForm /Sig.
sign_pdfAplicar una firma CMS compatible con PAdES (RSA-SHA256 / ECDSA-SHA256 P-256). Inyecta automáticamente un marcador de posición cuando es necesario.
verify_pdfVerificar cada firma PAdES en un PDF (integridad + valor de firma + confianza de cadena opcional).
validate_pdf (nuevo en v1.1.0)Validar un PDF etiquetado para conformidad estructural PDF/UA (ISO 14289-1) (solo lectura).
add_attachmentGenerar un documento PDF/A-3 con archivos incrustados (facturas Factur-X / ZUGFeRD).
extract_attachmentsExtracción de solo lectura de archivos incrustados (ida y vuelta XML Factur-X / ZUGFeRD) con cargas útiles byte a byte.
extract_textExtracción de texto Unicode (resuelve /ToUnicode) con ejecuciones posicionadas opcionales; abre PDFs cifrados mediante password.
inspect_pdfInspección de solo lectura: versión PDF, número de páginas, cifrado (+ encryptionInfo preciso), declaración PDF/A, firmas, adjuntos, estado del marcador de posición.
encrypt_pdf (nuevo en v1.5.0)Reasegurar un PDF con AES-128 / AES-256 (contraseñas de propietario/usuario, permisos, rotación de contraseñas).
decrypt_pdf (nuevo en v1.5.0)Emitir una copia sin cifrar de un documento RC4 / AES-128 / AES-256.
merge_pdfs (nuevo en v1.3.0)Concatenar 2–50 PDFs en uno mediante la API de árbol de páginas de pdfnative.
split_pdf (nuevo en v1.3.0)Dividir un PDF en un documento por rango de páginas (salida múltiple).
extract_pages (nuevo en v1.3.0)Extraer un subconjunto arbitrario de páginas en un solo PDF.
annotate_pdf (nuevo en v1.4.0)Añadir anotaciones de marcado (resaltado, nota, cuadrado/círculo, línea, texto libre) como superposición visual — no una redacción.
draft_governance_issue (nuevo en v1.4.0)Redactar localmente un issue de GitHub conforme a gobernanza para revisión humana; nunca envía, sin red.

Nuevo en v1.5.0:

  • 📊 Gráficos vectoriales nativosadd_chart renderiza gráficos de barras / barras horizontales / líneas / circular / donut como operadores de ruta PDF puros (cero rasterización, seguro para PDF/A con texto alternativo automático). generate_basic_pdf también acepta un bloque chart para composición con texto y tablas.
  • 📝 Rellenar y aplanar formulariosread_form_fields lista los campos de un AcroForm existente; fill_form lo rellena y/o aplana mediante una actualización incremental no destructiva (la contraparte de add_form).
  • 🔐 Cifrado de ida y vueltaencrypt_pdf reasegura con AES-128 / AES-256 (RC4 nunca se emite), decrypt_pdf recupera una copia sin cifrar, una entrada password abre fuentes cifradas en las herramientas de solo lectura, y merge_pdfs / split_pdf / extract_pages ganan password + encrypt.
  • 🔤 Extracción de texto realextract_text ahora resuelve el CMap /ToUnicode de cada fuente (sin más salida de índice de glifos) y puede devolver runs posicionados.
  • 🔗 Recursos MCP nativos — los PDFs generados en sandbox se convierten en recursos pdfnative://output/… (resources/list + resources/read), con un resource_link en resultados en modo archivo para re-referencia entre llamadas.
  • 🏷️ Anotaciones de herramientas — cada herramienta anuncia readOnlyHint / destructiveHint / idempotentHint / openWorldHint.
  • Actualización del motorpdfnative v1.6.0 (descifrado/re-cifrado, extractText, relleno/aplanado, gráficos; subconjunto de emoji de color 221 → 1167 glifos).

Nuevo en v1.4.0:

  • 🤝 Gobernanza de IA + humano en el bucledraft_governance_issue permite a un agente redactar un issue de GitHub totalmente conforme localmente (borrador .md + informe de cumplimiento legible por máquina). El agente es un redactor, nunca un remitente autónomo: un humano es la única puerta, y el servidor hace cero escrituras en GitHub y ninguna llamada de red saliente. Respaldado por los prompts MCP governance_contract y draft_issue_workflow.
  • ✏️ Anotaciones de marcadoannotate_pdf superpone resaltados, notas adhesivas, subrayados, tachados, ondulados, cuadrados, círculos, líneas y anotaciones de texto libre en un PDF existente mediante actualización incremental. Es una capa de revisión visual, no una redacción — los bytes subyacentes permanecen.
  • 🔢 Etiquetas de página en inspect_pdf — exposición de solo lectura de rangos /PageLabels (romanos, decimales, con prefijo).
  • Script matemático / científicoadd_international_text acepta lang: 'math' (explícito, como emoji) para incrustar la fuente Noto Sans Math bajo demanda.
  • 🧩 Prompts MCP — el servidor ahora anuncia la capacidad prompts con governance_contract y draft_issue_workflow.
  • Actualización del motor — pdfnative v1.5.0.

Nuevo en v1.3.0:

  • 🆕 Tres herramientas de árbol de páginasmerge_pdfs, split_pdf, extract_pages (construidas sobre la API de árbol de páginas de pdfnative v1.4.0; las fuentes cifradas se rechazan).

  • 🔖 Marcadores, etiquetas de página y listas anidadasgenerate_basic_pdf gana outline ('auto' o árbol explícito), pageLabels, elementos de lista list multinivel, y viewerPreferences.

  • 📐 Bordes y alineación de celdas de tablaadd_table gana cellBorders, cellVAlign, y viewerPreferences; add_international_text gana viewerPreferences.

  • 🔐 Firma en tiempo constantesign_pdf firma claves RSA y EC-DER a través de un proveedor node:crypto con un respaldo transparente en JS puro; las firmas permanecen interoperables.

  • Actualización del motor — pdfnative v1.4.0.

  • 🆕 Herramienta extract_attachments — leer archivos incrustados de un PDF (completa el ida y vuelta Factur-X / ZUGFeRD) con cargas útiles byte a byte, un filtro filename, y una sonda de solo metadatos includeData: false.

  • 💧 Marcas de aguagenerate_basic_pdf y add_table aceptan un watermark opcional (texto, opacidad, ángulo, color, posición) renderizado en cada página.

  • 🌐 normalize UnicodeNFC/NFD/NFKC/NFKD opcionales en generate_basic_pdf y add_international_text.

  • 🪙 Lecturas frugales en tokens — las herramientas de solo lectura (inspect_pdf, verify_pdf, validate_pdf, extract_text, extract_attachments) aceptan entradas opcionales verbosity: 'summary' y fields: […] para respuestas ~90% más pequeñas en resultados grandes, sin pérdida de los campos en los que los agentes basan sus decisiones. Los valores predeterminados no cambian.

  • 🪙 Sin duplicación base64 — los PDFs generados (modo base64) se devuelven una vez como un bloque de contenido resource incrustado en lugar de copiarse también en structuredContent.

  • 🔧 Corrección de publicación en el registro MCPmcpName ahora usa el uso de mayúsculas canónico del login de GitHub (io.github.Nizoka/pdfnative-mcp) para que la validación sensible a mayúsculas del registro acepte el paquete npm.

  • Dependencia — actualizado a zod 4.

Nuevo en v1.1.0:

  • 🆕 Herramienta validate_pdf — verificación de conformidad estructural PDF/UA (ISO 14289-1) de solo lectura.
  • 🆕 Seis nuevos scripts — Telugu, Sinhala, Tibetano, Khmer, Myanmar, Etíope (24 scripts en total).
  • 🆕 Emoji de color COLRv1 — emoji de color nativo con respaldo monocromático.
  • 🆕 Saneador de saltos de línea\n incrustados en párrafos se dividen automáticamente en párrafos separados (seguro para PDF/A).
  • 🆕 Normalización NFC automática para add_international_text.
  • 🛠 Actualización del motorpdfnative v1.3.0: el signo del Euro / símbolos CP-1252 ahora se extraen correctamente, y las celdas de tabla envueltas obtienen MCIDs únicos por línea (seguro para PDF/UA).

Nuevo en v1.0.0:

  • 🆕 Tres nuevas herramientas: verify_pdf, add_attachment (Factur-X / ZUGFeRD), extract_text.
  • 🆕 Campos de tabla inteligentes: wrap, repeatHeader, zebra, caption, minRowHeight, cellPadding.
  • 🆕 inspect_pdf ahora informa hasSignaturePlaceholder y resumen por adjunto; nuevos valores check 'placeholder' y 'attachments'.
  • 🆕 Ergonomía de firma: sign_pdf acepta claves ECDSA SEC1 / PKCS#8 DER e inyecta automáticamente un marcador de posición /Sig cuando falta (firma de cualquier PDF en una sola llamada).
  • 🆕 Caché opcional (PDFNATIVE_MCP_CACHE_DIR): con clave SHA-256, TTL de 1 h, LRU de 256 MiB.
  • 🆕 _meta.apiVersion y _meta.examples por herramienta para descubrimiento por agentes de IA — ver docs/API_STABILITY.md.
  • 🆕 Guía para agentes de IA: docs/AI_GUIDE.md — árbol de decisión + errores comunes. Ver también el manual de operaciones raíz AGENTS.md.
  • 🆕 Guía de autoría PDF/A: docs/guides/PDFA.md.
  • 🛠 Renombrado de variable de entorno: PDFNATIVE_MCP_OUTPUT_DIR (antes PDFNATIVE_MPC_OUTPUT_DIR; el nombre antiguo sigue funcionando con una advertencia de deprecación única).
  • Ahora incluido: merge_pdfs, split_pdf, extract_pages (v1.3.0), annotate_pdf (v1.4.0), y las herramientas add_chart / read_form_fields / fill_form / encrypt_pdf / decrypt_pdf más el ida y vuelta cifrado y los recursos MCP nativos (v1.5.0). redact_pdf permanece diferido — pdfnative puede superponer/aplanar pero no eliminar contenido de página, y una "redacción" solo de superposición crearía una falsa seguridad, por lo que intencionalmente no se incluye (seguido como solicitud de eliminación de contenido upstream).

Todas las herramientas admiten dos modos de salida:

  • base64 (predeterminado) — el PDF generado se devuelve una vez como un bloque de contenido resource incrustado (un URI data:application/pdf;base64,…); structuredContent solo contiene { mode, sizeBytes }.
  • file — el PDF se escribe en un directorio aislado configurado mediante PDFNATIVE_MCP_OUTPUT_DIR. La salida de archivos está deshabilitada a menos que esta variable esté configurada; las rutas absolutas, el traversal de rutas, las extensiones que no sean .pdf y los bytes NUL se rechazan.

Actualización desde v1.1.0: el único cambio de comportamiento es que los bytes en modo base64 ya no se duplican en structuredContent.base64. Léelos desde el bloque resource incrustado en su lugar:

- const base64 = response.structuredContent.base64;   // v1.1.0
+ const block = response.content.find((c) => c.type === 'resource');
+ const base64 = block.resource.blob;                  // v1.2.0

Lecturas eficientes en tokens (v1.2.0). Las cuatro herramientas de solo lectura aceptan dos entradas opcionales:

  • verbosity: 'summary' — devuelve un veredicto compacto solo con escalares (omite los arrays pesados / texto completo). Por ejemplo, verify_pdf{ signatureCount, allValid, invalid, summary }.
  • fields: ['a', 'b.c'] — proyecta el resultado estructurado a rutas de puntos nombradas; se compone después de verbosity. Las rutas desconocidas se omiten de forma tolerante.

La sonda más pequeña para "¿este PDF está firmado y es válido?": { "pdfBase64": "…", "verbosity": "summary", "fields": ["allValid"] }.

¿Por qué pdfnative?

pdfnative-mcp hereda todas las garantías del motor subyacente:

  • Cero dependencias en tiempo de ejecución — JavaScript puro, sin enlaces nativos.
  • Salida compatible con ISO 32000-1 (PDF 1.7).
  • PDF/A-1b/2b/3b, cifrado AES-128/256, AcroForm, firmas digitales.
  • 16 escrituras Unicode con reordenamiento BiDi integrado, conformación posicional árabe, conformación OpenType para tailandés, devanagari, bengalí y tamil.
  • Build ESM con tree-shaking.

🚀 Instalación

# Run directly with npx (recommended for MCP clients)
npx -y pdfnative-mcp

# Or install globally
npm install -g pdfnative-mcp
pdfnative-mcp

Requisitos: Node.js ≥ 22.


⚙️ Configuración

Claude Desktop

Edita ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) o %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "pdfnative": {
      "command": "npx",
      "args": ["-y", "pdfnative-mcp"],
      "env": {
        "PDFNATIVE_MCP_OUTPUT_DIR": "/Users/you/Documents/mcp-pdfs"
      }
    }
  }
}

Cursor / Continue / Zed / Windsurf / Cline / Roo Code

Cualquier cliente compatible con MCP que admita servidores stdio funcionará. Usa el mismo trío command + args + env. Ejemplo para Cursor (~/.cursor/mcp.json):

{
  "mcpServers": {
    "pdfnative": {
      "command": "npx",
      "args": ["-y", "pdfnative-mcp"],
      "env": { "PDFNATIVE_MCP_OUTPUT_DIR": "/Users/you/Documents/mcp-pdfs" }
    }
  }
}

Windsurf / Cline / Roo Code usan la misma estructura dentro de sus respectivos archivos de configuración MCP.

🌐 Ecosistema y clientes de IA compatibles

pdfnative-mcp está diseñado para entornos nativos de MCP y funciona con clientes que admiten MCP sobre stdio.

La compatibilidad verificada por la comunidad incluye:

Variables de entorno

VariablePropósito
PDFNATIVE_MCP_OUTPUT_DIRRuta absoluta al directorio aislado. Requerida para habilitar outputMode: 'file'.
PDFNATIVE_MCP_CACHE_DIRRuta absoluta para habilitar la caché de resultados persistente con clave SHA-256 (TTL de 1 h, LRU de 256 MiB). Si no se configura, la caché está deshabilitada.
PDFNATIVE_MCP_PORTCuando se configura con un puerto válido (1–65535), inicia un servidor HTTP en http://127.0.0.1:<port>/mcp en lugar de stdio. Solo se vincula a loopback y habilita la protección contra DNS rebinding (Host/Origin externos → 403).

🛠 Referencia de herramientas

generate_basic_pdf

{
  "title": "Q1 2026 Report",
  "blocks": [
    { "type": "heading", "text": "Executive summary", "level": 1 },
    { "type": "paragraph", "text": "Revenue grew 24% year over year." },
    { "type": "list", "style": "bullet", "items": ["Strong APAC", "Stable EU", "Soft NA"] },
    { "type": "pageBreak" },
    { "type": "heading", "text": "Details", "level": 2 }
  ],
  "footerText": "Confidential — Internal use only",
  "outputMode": "base64"
}

add_barcode

{
  "format": "qr",
  "data": "https://pdfnative.dev",
  "caption": "Scan to learn more",
  "ecLevel": "H",
  "outputMode": "file",
  "outputPath": "tickets/event-42.pdf"
}

Formatos admitidos: qr, code128, ean13, datamatrix, pdf417.

add_international_text

{
  "title": "مرحبا بالعالم",
  "lang": "ar",
  "paragraphs": [
    "هذا اختبار للنص العربي مع تشكيل OpenType ومحارف ثنائية الاتجاه.",
    "Mixed content: العربية + English ✓"
  ]
}

Códigos lang admitidos: ar, he, th, ja, zh, ko, el, hi, bn, ta, ru, ka, hy, tr, vi, pl, latin, emoji, math.

Documentos multiescritura: pasa un array o una lista separada por comas:

{
  "title": "Mixed Script",
  "lang": ["ar", "emoji"],
  "paragraphs": ["العربية مع رموز 🎉🚀"],
  "pdfA": "pdfa2u"
}

sign_pdf

A partir de v1.0.0, sign_pdf inyecta automáticamente un marcador de posición /Sig cuando falta: puedes firmar cualquier PDF en una sola llamada:

{
  "pdfBase64": "<any base64 PDF>",
  "algorithm": "rsa-sha256",
  "certDerBase64": "<base64 X.509 cert in DER>",
  "rsaKeyPkcs1DerBase64": "<base64 PKCS#1 RSAPrivateKey DER>",
  "signerName": "Alice",
  "reason": "Approval",
  "location": "Paris, FR",
  "signingTime": "2026-01-15T10:30:00Z"
}

Para ECDSA P-256: usa algorithm: "ecdsa-sha256" y proporciona ecPrivateKeyDerBase64 (DER SEC1 o PKCS#8) o ecPrivateScalarHex (64 caracteres hexadecimales).

Conversión PEM → DER:

openssl x509 -in cert.pem -outform DER | base64 -w0                 # cert
openssl rsa  -in key.pem  -outform DER -traditional | base64 -w0    # RSA PKCS#1
openssl pkey -in key.pem  -outform DER | base64 -w0                 # ECDSA

Usa prepare_signature_placeholder solo cuando necesites personalizar el marcador de posición (por ejemplo, un placeholderBytes más grande para claves RSA >4096 bits). De lo contrario, llama a sign_pdf directamente.


add_table

{
  "title": "Monthly Sales",
  "headers": ["Region", "Units", "Revenue"],
  "rows": [
    ["APAC", "1200", "$240,000"],
    ["EMEA", "800", "$160,000"]
  ],
  "infoItems": [{ "label": "Period", "value": "January 2025" }],
  "footerText": "Internal use only",
  "outputMode": "base64"
}

add_form

{
  "title": "Employee Onboarding",
  "fields": [
    { "fieldType": "text", "name": "fullName", "label": "Full Name", "required": true },
    { "fieldType": "dropdown", "name": "dept", "label": "Department", "options": ["Engineering", "Sales", "HR"] },
    { "fieldType": "checkbox", "name": "agree", "label": "I agree to the terms", "checked": false }
  ],
  "outputMode": "base64"
}

embed_image

{
  "title": "Product Photo",
  "imageBase64": "<base64-encoded JPEG bytes>",
  "mimeType": "image/jpeg",
  "caption": "Front view of Model X",
  "width": 400,
  "outputMode": "base64"
}

Nota: pdfnative no admite PNG con canal alfa (tipo de color 6). Preprocesa dichas imágenes para eliminar el canal alfa antes de incrustarlas.

prepare_signature_placeholder

{
  "title": "Service Agreement",
  "signerName": "Alice Dupont",
  "reason": "Approved",
  "location": "Paris, FR",
  "blocks": [
    { "type": "paragraph", "text": "By signing below, I accept the terms and conditions." }
  ],
  "outputMode": "base64"
}

Pasa los bytes del PDF devueltos a sign_pdf para completar el flujo de trabajo de firma.

inspect_pdf

Inspección estructural y de seguridad de solo lectura: útil para verificación posterior, aserciones de CI y agentes de IA que necesitan razonar sobre un PDF antes de actuar sobre él.

{
  "pdfBase64": "<base64 PDF>",
  "pages": true,
  "check": ["pdfa", "signed", "attachments"]
}

Devuelve:

{
  "version": "1.7",
  "pageCount": 3,
  "encryption": "none",          // 'none' | 'aes-128' | 'aes-256' | 'rc4' | 'unknown'
  "pdfA": "3B",                  // null when no PDF/A claim is present
  "signatureCount": 1,
  "hasSignaturePlaceholder": false,
  "attachments": [{ "filename": "factur-x.xml", "mimeType": "application/xml", "sizeBytes": 1234, "relationship": "Source" }],
  "info": { "Producer": "pdfnative", "Title": "Invoice INV-2025-001" },
  "perPage": [{ "index": 0, "width": 595, "height": 842 }],
  "checks": { "pdfa": true, "signed": true, "attachments": true },
  "checksPassed": true
}

check[] acepta cualquiera de 'pdfa', 'signed', 'encrypted', 'placeholder', 'attachments'. checksPassed es el AND de todas las comprobaciones solicitadas.

validate_pdf

Comprobación estructural de conformidad PDF/UA (ISO 14289-1) de solo lectura para un PDF etiquetado. Genera un documento accesible con cualquier herramienta usando pdfA (por ejemplo, pdfA: 'pdfa2u') y luego valida el resultado:

{ "pdfBase64": "<tagged-pdf-base64>" }

Devuelve:

{
  "standard": "pdf-ua-1",
  "valid": true,
  "errors": [],          // blocking structural violations (empty when valid)
  "warnings": [],        // non-blocking best-practice recommendations
  "summary": "PDF/UA structural prerequisites hold."
}

Verifica el catálogo /MarkInfo /Marked true, /StructTreeRoot (+ /ParentTree), /Metadata (XMP), /Lang y la unicidad de MCID por página. Esta es una puerta rápida en tiempo de desarrollo: no sustituye a un validador de referencia completo (veraPDF), que además comprueba fuentes, color y renderizado.

annotate_pdf

Superpone anotaciones de marcado en un PDF existente mediante actualización incremental. Esta es una capa de revisión visual, no una redacción: el contenido subyacente no se modifica.

{
  "pdfBase64": "<base64 PDF>",
  "annotations": [
    { "type": "highlight", "page": 0, "rect": [72, 700, 520, 715], "color": [1, 1, 0], "contents": "Check this figure" },
    { "type": "text", "page": 0, "rect": [540, 700, 560, 720], "contents": "Reviewer note" }
  ]
}

Tipos: text, highlight, underline, strikeout, squiggly, square, circle, line, freetext. Las fuentes cifradas se rechazan (ENCRYPTED_SOURCE).

draft_governance_issue

Redacta un issue de GitHub conforme a gobernanza localmente para que un humano lo revise y lo envíe. El servidor nunca contacta con GitHub y no realiza llamadas de red salientes; devuelve el borrador en Markdown más un informe de cumplimiento legible por máquina.

{
  "title": "add_table drops the caption on the second page",
  "issueType": "bug",
  "summary": "The table caption is only rendered on page 1 when repeatHeader is true.",
  "reproduction": { "command": "node examples/run.mjs add-table-caption.json", "result": "Page 2 has no caption row." },
  "expectedBehavior": "The caption repeats with the header on every page.",
  "duplicateSearchPerformed": true
}

Un borrador que proponga una dependencia en tiempo de ejecución, omita una reproducción o establezca duplicateSearchPerformed: false se rechaza con GOVERNANCE_VIOLATION. Consulta docs/guides/AI_GOVERNANCE.md para el contrato completo de human-in-the-loop.

verify_pdf, add_attachment, extract_text

Consulta las secciones dedicadas en docs/AI_GUIDE.md y la referencia en docs/KNOWLEDGE_BASE.md. Los ejemplos listos para ejecutar están en examples/.


🔐 Modelo de seguridad

pdfnative-mcp se ejecuta dentro del proceso anfitrión y expone un servidor MCP stdio. No abre sockets de red y no realiza E/S fuera del sandbox configurado.

  • Escrituras de archivos están controladas por PDFNATIVE_MCP_OUTPUT_DIR. Si no se configura, el modo de salida file se rechaza con un SecurityError.
  • Resolución de rutas rechaza rutas absolutas, secuencias de traversal (..), bytes NUL y cualquier extensión distinta de .pdf.
  • Tamaño de salida limitado a 50 MB por llamada.
  • Entradas validadas contra esquemas JSON estrictos + comprobaciones en tiempo de ejecución con Zod en el límite de cada herramienta.

Consulta SECURITY.md para el proceso de divulgación responsable.


🧪 Desarrollo local

git clone https://github.com/Nizoka/pdfnative-mcp.git
cd pdfnative-mcp
npm install
npm run typecheck
npm run lint
npm test
npm run build

Prueba rápida del servidor sobre stdio:

node dist/cli.js
# In another terminal, send a JSON-RPC initialize request via stdin (e.g. with mcp-inspector).

Colaboradores: consulta docs/guides/LOCAL_TESTING.md para el flujo de trabajo completo de verificación local: la puerta de calidad, ejemplos como pruebas, validación de que los PDF generados son estructuralmente correctos (assertValidPdf, inspect_pdf, validate_pdf, verify_pdf), apertura de la salida en un visor, comprobación externa de PDF/A con veraPDF y el MCP Inspector.

📣 Proceso de publicación

pdfnative-mcp sigue el mismo formalismo de publicación que pdfnative:

  • Un archivo de notas de versión por etiqueta en release-notes/vX.Y.Z.md
  • CHANGELOG.md refleja cada lista de viñetas de la versión
  • El cuerpo de la Release de GitHub se copia de release-notes/vX.Y.Z.md
  • La publicación en npm la gestiona GitHub Actions Trusted Publishing (OIDC), sin NPM_TOKEN

Consulta release-notes/TEMPLATE.md para la estructura canónica y la lista de verificación de publicación.


📚 Estructura del proyecto

src/
├── cli.ts                      # stdio entrypoint (#!/usr/bin/env node)
├── index.ts                    # public library exports
├── server.ts                   # McpServer factory + tool registry
├── output.ts                   # sandboxed file writer / base64 emitter (single + multi)
├── text.ts                     # newline sanitizer (Safe PDF/A)
├── doc-features.ts             # nested lists, outline, page labels, viewer prefs
├── pagetree.ts                 # page-tree error mapping (merge/split/extract)
├── crypto-provider.ts          # node:crypto constant-time signature provider
├── errors.ts                   # ToolError, SecurityError
└── tools/
    ├── generate-basic-pdf.ts
    ├── add-barcode.ts
    ├── sign-pdf.ts
    ├── add-international-text.ts
    ├── add-table.ts
    ├── add-form.ts
    ├── embed-image.ts
    ├── inspect-pdf.ts
    ├── verify-pdf.ts
    ├── validate-pdf.ts
    ├── add-attachment.ts
    ├── extract-attachments.ts
    ├── extract-text.ts
    ├── merge-pdfs.ts
    ├── split-pdf.ts
    ├── extract-pages.ts
    └── prepare-signature-placeholder.ts
tests/                          # vitest suites

🗺 Hoja de ruta

v1.3.0 está publicada. El plan completo (hitos publicados, trabajo en curso y dirección a largo plazo) está en ROADMAP.md.

Bloqueado aguas arriba (manipulación del árbol de páginas):

  • redact_pdf y un round-trip de PDF cifrado: pdfnative aún no exporta las primitivas de redacción de contenido / descifrado necesarias para construirlos de forma segura. Siguen en la hoja de ruta, bloqueados por una API aguas arriba. (merge_pdfs, split_pdf y extract_pages se publicaron en v1.3.0.)

¿Tienes una idea de funcionalidad? Abre un issue o un PR.


⭐ Dale una estrella al proyecto

Si pdfnative-mcp te resulta útil, por favor ⭐ este repositorio — y considera también dar una estrella al motor subyacente Nizoka/pdfnative. Las estrellas ayudan a que otros descubran el proyecto y motivan el desarrollo continuo.


🤝 Contribuciones

Las contribuciones son muy bienvenidas. Por favor, lee CONTRIBUTING.md, revisa los issues abiertos y sigue el código de conducta.


📄 Licencia

MIT © 2026 Nizoka

pdfnative-mcp está construido sobre pdfnative y el Model Context Protocol TypeScript SDK.