Pdfnative

by Nizoka

1.7k downloads Not rated yet

About

Enterprise-grade PDF engine for AI agents. Pure TypeScript, zero-dependency, and local-first. Allows agents to generate ISO-compliant PDF/A documents, handle digital signatures (PKCS#7), and process high-performance layouts (800+ pages in seconds).

Explore

- Pure TypeScript, zero external dependencies.
- Generates 800+ pages in under 4 seconds.
- Supports ISO-compliant PDF/A and PKCS#7 digital signatures.
- 100% local processing — no external API calls.
- Tools to generate structured PDFs, add barcodes, and handle Unicode text.

Setting up with Highlight

This MCP is not yet compatible with Highlight’s one-click setup. However, you can still use it with Highlight by following these steps:

  1. Download and install Highlight from highlightai.com/download
  2. Navigate to the plugins tab and select "Add Custom Plugin"
  3. Configure the plugin with the settings below
    Plugin Name Pdfnative
    Command (node, npx, python, etc.)

    Please refer to the README for specific instructions on how to obtain API keys or other required environment variables.

  4. Enable "Start Automatically" if you want the plugin to start when Highlight launches

From the repository

Add the server to your MCP client configuration (e.g., claude_desktop_config.json or Cursor settings) using the command npx -y pdfnative-mcp. No additional installation or setup steps are required beyond configuring the JSON.

generate_basic_pdf

Generate a multi-page A4 PDF from structured blocks (headings, paragraphs, lists, page breaks, spacers). DEFAULT TOOL for plain documents — prefer this over specialized tools unless you need barcodes, tables, attachments, or non-Latin scripts. Optional pdfA flag enables Tagged PDF / PDF/A-1b/2b/2u/3b output (auto-embeds Noto Sans for non-WinAnsi Latin per ISO 19005 §6.3.4). Returns the PDF as base64 by default, or writes it to a sandboxed file path when outputMode=file.

add_barcode

Generate a single-page PDF embedding a barcode or QR code. Supported formats: • qr — URLs, vCards, any UTF-8 text ≤ 4296 chars. Use ecLevel='H' for printed media (logos/dirt-tolerant); 'M' (default) for screens. • code128 — alphanumeric SKUs, ASCII payloads. • ean13 — retail product codes (must be 12 or 13 digits; 13th is auto-computed). • datamatrix— dense industrial / aerospace markings. • pdf417 — ID cards, boarding passes. Common recipe for a QR code pointing to a URL: { format: 'qr', data: 'https://example.com', caption: 'Scan me' }. The `data` field is the raw payload — do NOT pre-encode URLs.

sign_pdf

Apply a PAdES-compatible CMS digital signature to a PDF. Since v1.0.0 you can sign ANY PDF in ONE call — autoInjectPlaceholder defaults to true, so you do NOT need to run prepare_signature_placeholder first unless you want to customize the placeholder appearance. Supports RSA-SHA256 and ECDSA-SHA256 (P-256). Required inputs: pdfBase64, algorithm, certDerBase64, plus EITHER rsaKeyPkcs1DerBase64 (when algorithm='rsa-sha256') OR ecPrivateScalarHex / ecPrivateKeyDerBase64 (when algorithm='ecdsa-sha256'). To convert PEM keys to DER base64: `openssl pkey -in key.pem -outform DER | base64 -w0`. To convert a PEM X.509 cert: `openssl x509 -in cert.pem -outform DER | base64 -w0`. After signing, call verify_pdf to confirm validity.

add_international_text

Generate a PDF rendering text in any of 24 scripts (Arabic, Hebrew, Thai, CJK, Devanagari, Bengali, Tamil, Telugu, Sinhala, Tibetan, Khmer, Myanmar, Ethiopic, Cyrillic, Greek, Georgian, Armenian, Vietnamese, Turkish, Polish, Latin fallback) with optional COLRv1 colour emoji and mathematical / technical symbols (the "math" font — Noto Sans Math, ∀ ∃ √ ∑ ∫ ∞ ± ÷ ×). BiDi reordering (incl. UAX#9 isolates), Arabic harakat positioning, and complex-script OpenType shaping are handled automatically by the embedded Noto fonts; input is NFC-normalised for maximal glyph coverage and embedded newlines auto-split into paragraphs. Pass `lang` as a single code or an array (e.g. ["ar","emoji"] or ["latin","math"]) for multi-script / symbol runs.

add_table

Generate a tabular PDF report from column headers and data rows. Ideal for data exports, financial summaries, schedules. Smart-table fields (pdfnative v1.2) automatically engage the document backend: `wrap` (auto/always/never), `repeatHeader` (header row on every page), `zebra` (alternate-row tint), `caption` (above the table, tagged for PDF/A), `minRowHeight` (points), `cellPadding` (points). Every row must have the same length as `headers`. For PDF/A output, set pdfA="pdfa2b" (most compatible).

add_form

Generate a PDF containing an interactive AcroForm with text fields, text areas, checkboxes, radio buttons, and dropdowns. Suitable for data-capture forms, surveys, and fillable templates.

embed_image

Generate a PDF document with an embedded JPEG or PNG image. The image is accepted as a base64-encoded string and can include an optional caption and custom render dimensions.

prepare_signature_placeholder

Create a PDF with an embedded /Sig AcroForm placeholder ready to be digitally signed by the sign_pdf tool. NOTE: as of v1.0.0, sign_pdf auto-injects a placeholder when missing (autoInjectPlaceholder defaults to true), so this tool is OPTIONAL. Use it only when you need to: (a) customize the placeholder size for >4096-bit RSA keys via placeholderBytes, (b) attach the signature widget to a specific page via pageIndex, or (c) precompute and ship the placeholder PDF separately from the signing step. Otherwise call sign_pdf directly with any PDF.

inspect_pdf

Read-only inspection of an existing PDF: version, page count, encryption state, PDF/A claim, signature count, hasSignaturePlaceholder, embedded attachments[], document info / metadata. Use the `check` array for CI-style assertions — supported values: 'pdfa', 'signed' (true when at least one signature has signed content), 'encrypted', 'placeholder' (unsigned /Sig widget present), 'attachments' (at least one /EmbeddedFile). The checksPassed boolean is true only when ALL requested checks hold.

verify_pdf

Read-only verification of every PAdES Baseline / adbe.pkcs7.detached signature in a PDF. For each /Sig widget, recomputes the ByteRange SHA-256, validates the CMS messageDigest (integrity), and verifies the CMS signatureValue with the embedded signer certificate. Supports RSA-SHA256 and ECDSA-SHA256 (P-256). The response shape: { allValid, signatureCount, summary, signatures: [{ valid, integrity, signerSubject, signingTime, reason, chainTrust: 'self-signed'|'unverified'|'trusted', errors: [] }] }. Read `allValid` for an overall yes/no; iterate `signatures[]` for per-signature detail. Without trustedRootsDerBase64, chainTrust is 'self-signed' (single-cert chain) or 'unverified' (signer rooted in an external CA).

add_attachment

Generate a PDF/A-3 (ISO 19005-3) document with one or more embedded files. USE THIS INSTEAD OF generate_basic_pdf when you need a Factur-X / ZUGFeRD electronic invoice (single XML payload with relationship='Source'), or any PDF that must carry machine-readable side-files. The visible document body is supplied via the optional `blocks` parameter (same block schema as generate_basic_pdf). The tool auto-emits PDF/A-3b conformance — PDF/A-3 is the only PDF/A part that legally permits embedded files. Each attachment is capped at 8 MiB.

extract_text

Best-effort plain-text extraction from a non-encrypted PDF. Walks each page's content stream and pulls the operands of Tj/'/"/TJ text operators. The result.extractable boolean is FALSE when one or more pages have non-empty content but yielded no text (this is EXPECTED for PDFs using subset fonts without /ToUnicode CMaps — it is not an error). The accompanying `extractableReason` field explains why. Encrypted PDFs are rejected with EXTRACTION_UNSUPPORTED. Tagged-mode structure-tree extraction (cleaner output for tagged PDFs) is tracked on the roadmap.

validate_pdf

Read-only PDF/UA (ISO 14289-1) structural conformance check. Verifies the accessibility prerequisites of a Tagged PDF: catalog /MarkInfo /Marked true, /StructTreeRoot (+ /ParentTree), /Metadata (XMP), /Lang, and per-page MCID uniqueness. Response shape: { standard: 'pdf-ua-1', valid, errors: [], warnings: [], summary }. Read `valid` for an overall yes/no; iterate `errors[]` for blocking violations and `warnings[]` for best-practice recommendations. This is a fast structural gate, NOT a full reference validator (veraPDF) — it does not check fonts, colour or rendering. Generate accessible input with any document tool using pdfA (e.g. pdfA='pdfa2u'), then validate the result here.

extract_attachments

Read-only extraction of embedded files from a non-encrypted PDF (PDF/A-3 / Factur-X / ZUGFeRD). Walks the catalog /Names → /EmbeddedFiles tree and returns each attachment's metadata (name, mimeType, AFRelationship, description, sizeBytes) plus, by default, its decoded payload as dataBase64. Completes the invoice round-trip: add_attachment → inspect_pdf → extract_attachments. Pass `filename` to pull a single named file, or `includeData: false` for a metadata-only probe. Encrypted PDFs are rejected with EXTRACTION_UNSUPPORTED.

merge_pdfs

Concatenate 2–50 source PDFs into a single document (pdfnative v1.4 page-tree API). Each kept page's object graph is deep-copied into a fresh, self-contained PDF. Signatures and AcroForms are dropped (a page-tree edit invalidates /ByteRange); self-contained URI link annotations are preserved unless dropAnnotations=true. Encrypted sources are rejected (ENCRYPTED_SOURCE) — decrypt first. A secure-by-default 256 MiB in-memory assembly guard (maxOutputSizeBytes) guards against memory exhaustion; the emitted PDF is separately capped at 50 MiB (OUTPUT_TOO_LARGE). Returns one PDF (base64 or sandboxed file).

split_pdf

Split one PDF into several documents — one per requested page range (pdfnative v1.4 page-tree API). Ranges are 0-based and inclusive; `end` defaults to `start` (a single page). Each output is a fresh, self-contained PDF (signatures/AcroForm dropped; URI links kept unless dropAnnotations=true). Encrypted sources are rejected (ENCRYPTED_SOURCE). In base64 mode every produced PDF is returned as its own embedded resource block; in file mode each is written to a 1-based indexed sibling of outputPath ('out.pdf' → 'out-1.pdf', 'out-2.pdf', …). Use extract_pages instead when you want a single PDF from an arbitrary page subset.

extract_pages

Extract an arbitrary subset of pages (0-based, in the order given) from a PDF into a SINGLE new document (pdfnative v1.4 page-tree API). The output is a fresh, self-contained PDF (signatures/AcroForm dropped; URI links kept unless dropAnnotations=true). Encrypted sources are rejected (ENCRYPTED_SOURCE). Use split_pdf instead when you need several output PDFs (one per range).

annotate_pdf

Add markup / drawing annotations (ISO 32000-1 §12.5) to an existing PDF via pdfnative v1.5's annotation writer. Non-destructive incremental update: original content is preserved byte-for-byte and each annotation is appended to the target page's /Annots. Types: text (sticky note), highlight | underline | strikeout | squiggly (text-markup), square | circle (shapes), line, freetext. Each annotation needs a 0-based `page` and a `rect` [x1,y1,x2,y2]; line also needs `start`/`end`. Optional per-annotation: contents, color, opacity, title, plus type-specific fields (open/icon, quadPoints, interiorColor/borderWidth, fontSize). Encrypted sources are rejected (ENCRYPTED_SOURCE). NOTE: annotations are visual overlays — they do NOT remove or redact the underlying content.

draft_governance_issue

Produce a LOCAL, governance-compliant GitHub issue draft plus a structured compliance report — and NEVER submit anything. This is the MCP-native embodiment of the pdfnative AI-governance / Human-In-The-Loop contract (.github/ai-governance.json, .github/AGENT_RULES.md): the agent is a DRAFTSMAN, the human is the only gate. The server makes NO outbound network call and has NO GitHub write path. The assembled draft is validated against the zero-dependency + reproduction policy; a violation (proposing a runtime dependency, missing reproduction, or duplicateSearchPerformed=false) throws GOVERNANCE_VIOLATION so the human must fix it before submitting under their own identity. Returns the draft markdown inline by default; outputMode='file' also writes a .md to the sandbox. After calling this, present BOTH the draft and the compliance report to the user, then STOP.

read_form_fields

Read-only enumeration of an existing PDF's interactive AcroForm fields (pdfnative v1.6.0). Returns each terminal field's fully-qualified name, classified type (text | checkbox | radio | dropdown | listbox | button | signature | unknown), current value, flags (readOnly / required / multiline), choice options, and widget placements. Call this FIRST to discover field names before driving fill_form. Encrypted sources are supported via `password`. Token-frugal: verbosity:'summary' returns just { fieldCount }.

fill_form

Fill (and optionally flatten) the AcroForm of an EXISTING PDF (pdfnative v1.6.0) — the counterpart to add_form, which CREATES a new form. Non-destructive incremental update: original bytes are preserved (a prior signature stays valid for its revision). `values` maps fully-qualified field name → value: text/choice take a string (array for multi-select listboxes); checkbox/radio take a boolean or the export-state string. Set flatten:true to stamp appearances into page content and drop the interactive layer (pass no values + flatten:true for a pure flatten). Encrypted documents are supported via `password` (appended objects are encrypted under the existing scheme). Signature fields cannot be filled (FORM_UNSUPPORTED). Discover field names with read_form_fields first.

add_chart

Generate a single-page PDF with a native vector chart (pdfnative v1.6.0): bar, barH (horizontal bar), line (optional markers), pie or donut — rendered as pure PDF path operators, zero rasterisation. Multi-series bar/line, legends, 'nice' 1/2/5×10ⁿ axis ticks, gridlines, negative values, and a tagged-PDF /Figure + /Alt (auto-generated when altText omitted, so PDF/A stays conformant). Pie/donut use exactly one series (each value = a slice). Colours are hex strings (e.g. '#3366cc'). For a chart embedded amongst headings/paragraphs/tables, use a 'chart' block inside generate_basic_pdf instead.

encrypt_pdf

Re-secure an existing PDF with the PDF Standard Security Handler (pdfnative v1.6.0): AES-128 (V4/R4, default) or AES-256 (V5/R6). RC4 is never emitted. Set ownerPassword (required) and optionally userPassword (open password), algorithm, and permissions { print, copy, modify, extractText }. Re-encrypt an already-encrypted source under a NEW password by passing its current `password` (password rotation in one call). CAVEAT: encryption rebuilds the page tree, so existing signatures and the interactive AcroForm are DROPPED and only self-contained URI links are kept — encrypt BEFORE signing, not after.

decrypt_pdf

Open an encrypted PDF (pdfnative v1.6.0 reader/decryptor — RC4 V1–V4, AES-128 V4/R4, AES-256 V5/R6) and emit an UNENCRYPTED copy. Pass `password` (user or owner); documents with an empty user password decrypt without one. CAVEAT: decryption rebuilds the page tree, so existing signatures and the interactive AcroForm are DROPPED and only self-contained URI links are kept. To READ an encrypted PDF without rebuilding it, pass `password` directly to inspect_pdf / extract_text / extract_attachments instead.

- generate_basic_pdf: Generate a multi-page A4 PDF from structured blocks (headings, paragraphs, lists, page breaks, spacers). DEFAULT TOOL for plain documents — prefer this over specialized tools unless you need barcodes, tables, attachments, or non-Latin scripts. Optional pdfA flag enables Tagged PDF / PDF/A-1b/2b/2u/3b output (auto-embeds Noto Sans for non-WinAnsi Latin per ISO 19005 §6.3.4). Returns the PDF as base64 by default, or writes it to a sandboxed file path when outputMode=file.
- add_barcode: Generate a single-page PDF embedding a barcode or QR code. Supported formats:
• qr — URLs, vCards, any UTF-8 text ≤ 4296 chars. Use ecLevel='H' for printed media (logos/dirt-tolerant); 'M' (default) for screens.
• code128 — alphanumeric SKUs, ASCII payloads.
• ean13 — retail product codes (must be 12 or 13 digits; 13th is auto-computed).
• datamatrix— dense industrial / aerospace markings.
• pdf417 — ID cards, boarding passes.
Common recipe for a QR code pointing to a URL: { format: 'qr', data: 'https://example.com', caption: 'Scan me' }. The data field is the raw payload — do NOT pre-encode URLs.
- sign_pdf: Apply a PAdES-compatible CMS digital signature to a PDF. Since v1.0.0 you can sign ANY PDF in ONE call — autoInjectPlaceholder defaults to true, so you do NOT need to run prepare_signature_placeholder first unless you want to customize the placeholder appearance. Supports RSA-SHA256 and ECDSA-SHA256 (P-256). Required inputs: pdfBase64, algorithm, certDerBase64, plus EITHER rsaKeyPkcs1DerBase64 (when algorithm='rsa-sha256') OR ecPrivateScalarHex / ecPrivateKeyDerBase64 (when algorithm='ecdsa-sha256'). To convert PEM keys to DER base64: openssl pkey -in key.pem -outform DER | base64 -w0. To convert a PEM X.509 cert: openssl x509 -in cert.pem -outform DER | base64 -w0. After signing, call verify_pdf to confirm validity.
- add_international_text: Generate a PDF rendering text in any of 24 scripts (Arabic, Hebrew, Thai, CJK, Devanagari, Bengali, Tamil, Telugu, Sinhala, Tibetan, Khmer, Myanmar, Ethiopic, Cyrillic, Greek, Georgian, Armenian, Vietnamese, Turkish, Polish, Latin fallback) with optional COLRv1 colour emoji and mathematical / technical symbols (the "math" font — Noto Sans Math, ∀ ∃ √ ∑ ∫ ∞ ± ÷ ×). BiDi reordering (incl. UAX#9 isolates), Arabic harakat positioning, and complex-script OpenType shaping are handled automatically by the embedded Noto fonts; input is NFC-normalised for maximal glyph coverage and embedded newlines auto-split into paragraphs. Pass lang as a single code or an array (e.g. ["ar","emoji"] or ["latin","math"]) for multi-script / symbol runs.
- add_table: Generate a tabular PDF report from column headers and data rows. Ideal for data exports, financial summaries, schedules. Smart-table fields (pdfnative v1.2) automatically engage the document backend: wrap (auto/always/never), repeatHeader (header row on every page), zebra (alternate-row tint), caption (above the table, tagged for PDF/A), minRowHeight (points), cellPadding (points). Every row must have the same length as headers. For PDF/A output, set pdfA="pdfa2b" (most compatible).
- add_form: Generate a PDF containing an interactive AcroForm with text fields, text areas, checkboxes, radio buttons, and dropdowns. Suitable for data-capture forms, surveys, and fillable templates.
- embed_image: Generate a PDF document with an embedded JPEG or PNG image. The image is accepted as a base64-encoded string and can include an optional caption and custom render dimensions.
- prepare_signature_placeholder: Create a PDF with an embedded /Sig AcroForm placeholder ready to be digitally signed by the sign_pdf tool. NOTE: as of v1.0.0, sign_pdf auto-injects a placeholder when missing (autoInjectPlaceholder defaults to true), so this tool is OPTIONAL. Use it only when you need to: (a) customize the placeholder size for >4096-bit RSA keys via placeholderBytes, (b) attach the signature widget to a specific page via pageIndex, or (c) precompute and ship the placeholder PDF separately from the signing step. Otherwise call sign_pdf directly with any PDF.
- inspect_pdf: Read-only inspection of an existing PDF: version, page count, encryption state, PDF/A claim, signature count, hasSignaturePlaceholder, embedded attachments[], document info / metadata. Use the check array for CI-style assertions — supported values: 'pdfa', 'signed' (true when at least one signature has signed content), 'encrypted', 'placeholder' (unsigned /Sig widget present), 'attachments' (at least one /EmbeddedFile). The checksPassed boolean is true only when ALL requested checks hold.
- verify_pdf: Read-only verification of every PAdES Baseline / adbe.pkcs7.detached signature in a PDF. For each /Sig widget, recomputes the ByteRange SHA-256, validates the CMS messageDigest (integrity), and verifies the CMS signatureValue with the embedded signer certificate. Supports RSA-SHA256 and ECDSA-SHA256 (P-256). The response shape: { allValid, signatureCount, summary, signatures: [{ valid, integrity, signerSubject, signingTime, reason, chainTrust: 'self-signed'|'unverified'|'trusted', errors: [] }] }. Read allValid for an overall yes/no; iterate signatures[] for per-signature detail. Without trustedRootsDerBase64, chainTrust is 'self-signed' (single-cert chain) or 'unverified' (signer rooted in an external CA).
- add_attachment: Generate a PDF/A-3 (ISO 19005-3) document with one or more embedded files. USE THIS INSTEAD OF generate_basic_pdf when you need a Factur-X / ZUGFeRD electronic invoice (single XML payload with relationship='Source'), or any PDF that must carry machine-readable side-files. The visible document body is supplied via the optional blocks parameter (same block schema as generate_basic_pdf). The tool auto-emits PDF/A-3b conformance — PDF/A-3 is the only PDF/A part that legally permits embedded files. Each attachment is capped at 8 MiB.
- extract_text: Best-effort plain-text extraction from a non-encrypted PDF. Walks each page's content stream and pulls the operands of Tj/'/"/TJ text operators. The result.extractable boolean is FALSE when one or more pages have non-empty content but yielded no text (this is EXPECTED for PDFs using subset fonts without /ToUnicode CMaps — it is not an error). The accompanying extractableReason field explains why. Encrypted PDFs are rejected with EXTRACTION_UNSUPPORTED. Tagged-mode structure-tree extraction (cleaner output for tagged PDFs) is tracked on the roadmap.
- validate_pdf: Read-only PDF/UA (ISO 14289-1) structural conformance check. Verifies the accessibility prerequisites of a Tagged PDF: catalog /MarkInfo /Marked true, /StructTreeRoot (+ /ParentTree), /Metadata (XMP), /Lang, and per-page MCID uniqueness. Response shape: { standard: 'pdf-ua-1', valid, errors: [], warnings: [], summary }. Read valid for an overall yes/no; iterate errors[] for blocking violations and warnings[] for best-practice recommendations. This is a fast structural gate, NOT a full reference validator (veraPDF) — it does not check fonts, colour or rendering. Generate accessible input with any document tool using pdfA (e.g. pdfA='pdfa2u'), then validate the result here.
- extract_attachments: Read-only extraction of embedded files from a non-encrypted PDF (PDF/A-3 / Factur-X / ZUGFeRD). Walks the catalog /Names → /EmbeddedFiles tree and returns each attachment's metadata (name, mimeType, AFRelationship, description, sizeBytes) plus, by default, its decoded payload as dataBase64. Completes the invoice round-trip: add_attachment → inspect_pdf → extract_attachments. Pass filename to pull a single named file, or includeData: false for a metadata-only probe. Encrypted PDFs are rejected with EXTRACTION_UNSUPPORTED.
- merge_pdfs: Concatenate 2–50 source PDFs into a single document (pdfnative v1.4 page-tree API). Each kept page's object graph is deep-copied into a fresh, self-contained PDF. Signatures and AcroForms are dropped (a page-tree edit invalidates /ByteRange); self-contained URI link annotations are preserved unless dropAnnotations=true. Encrypted sources are rejected (ENCRYPTED_SOURCE) — decrypt first. A secure-by-default 256 MiB in-memory assembly guard (maxOutputSizeBytes) guards against memory exhaustion; the emitted PDF is separately capped at 50 MiB (OUTPUT_TOO_LARGE). Returns one PDF (base64 or sandboxed file).
- split_pdf: Split one PDF into several documents — one per requested page range (pdfnative v1.4 page-tree API). Ranges are 0-based and inclusive; end defaults to start (a single page). Each output is a fresh, self-contained PDF (signatures/AcroForm dropped; URI links kept unless dropAnnotations=true). Encrypted sources are rejected (ENCRYPTED_SOURCE). In base64 mode every produced PDF is returned as its own embedded resource block; in file mode each is written to a 1-based indexed sibling of outputPath ('out.pdf' → 'out-1.pdf', 'out-2.pdf', …). Use extract_pages instead when you want a single PDF from an arbitrary page subset.
- extract_pages: Extract an arbitrary subset of pages (0-based, in the order given) from a PDF into a SINGLE new document (pdfnative v1.4 page-tree API). The output is a fresh, self-contained PDF (signatures/AcroForm dropped; URI links kept unless dropAnnotations=true). Encrypted sources are rejected (ENCRYPTED_SOURCE). Use split_pdf instead when you need several output PDFs (one per range).
- annotate_pdf: Add markup / drawing annotations (ISO 32000-1 §12.5) to an existing PDF via pdfnative v1.5's annotation writer. Non-destructive incremental update: original content is preserved byte-for-byte and each annotation is appended to the target page's /Annots. Types: text (sticky note), highlight | underline | strikeout | squiggly (text-markup), square | circle (shapes), line, freetext. Each annotation needs a 0-based page and a rect [x1,y1,x2,y2]; line also needs start/end. Optional per-annotation: contents, color, opacity, title, plus type-specific fields (open/icon, quadPoints, interiorColor/borderWidth, fontSize). Encrypted sources are rejected (ENCRYPTED_SOURCE). NOTE: annotations are visual overlays — they do NOT remove or redact the underlying content.
- draft_governance_issue: Produce a LOCAL, governance-compliant GitHub issue draft plus a structured compliance report — and NEVER submit anything. This is the MCP-native embodiment of the pdfnative AI-governance / Human-In-The-Loop contract (.github/ai-governance.json, .github/AGENT_RULES.md): the agent is a DRAFTSMAN, the human is the only gate. The server makes NO outbound network call and has NO GitHub write path. The assembled draft is validated against the zero-dependency + reproduction policy; a violation (proposing a runtime dependency, missing reproduction, or duplicateSearchPerformed=false) throws GOVERNANCE_VIOLATION so the human must fix it before submitting under their own identity. Returns the draft markdown inline by default; outputMode='file' also writes a .md to the sandbox. After calling this, present BOTH the draft and the compliance report to the user, then STOP.
- read_form_fields: Read-only enumeration of an existing PDF's interactive AcroForm fields (pdfnative v1.6.0). Returns each terminal field's fully-qualified name, classified type (text | checkbox | radio | dropdown | listbox | button | signature | unknown), current value, flags (readOnly / required / multiline), choice options, and widget placements. Call this FIRST to discover field names before driving fill_form. Encrypted sources are supported via password. Token-frugal: verbosity:'summary' returns just { fieldCount }.
- fill_form: Fill (and optionally flatten) the AcroForm of an EXISTING PDF (pdfnative v1.6.0) — the counterpart to add_form, which CREATES a new form. Non-destructive incremental update: original bytes are preserved (a prior signature stays valid for its revision). values maps fully-qualified field name → value: text/choice take a string (array for multi-select listboxes); checkbox/radio take a boolean or the export-state string. Set flatten:true to stamp appearances into page content and drop the interactive layer (pass no values + flatten:true for a pure flatten). Encrypted documents are supported via password (appended objects are encrypted under the existing scheme). Signature fields cannot be filled (FORM_UNSUPPORTED). Discover field names with read_form_fields first.
- add_chart: Generate a single-page PDF with a native vector chart (pdfnative v1.6.0): bar, barH (horizontal bar), line (optional markers), pie or donut — rendered as pure PDF path operators, zero rasterisation. Multi-series bar/line, legends, 'nice' 1/2/5×10ⁿ axis ticks, gridlines, negative values, and a tagged-PDF /Figure + /Alt (auto-generated when altText omitted, so PDF/A stays conformant). Pie/donut use exactly one series (each value = a slice). Colours are hex strings (e.g. '#3366cc'). For a chart embedded amongst headings/paragraphs/tables, use a 'chart' block inside generate_basic_pdf instead.
- encrypt_pdf: Re-secure an existing PDF with the PDF Standard Security Handler (pdfnative v1.6.0): AES-128 (V4/R4, default) or AES-256 (V5/R6). RC4 is never emitted. Set ownerPassword (required) and optionally userPassword (open password), algorithm, and permissions { print, copy, modify, extractText }. Re-encrypt an already-encrypted source under a NEW password by passing its current password (password rotation in one call). CAVEAT: encryption rebuilds the page tree, so existing signatures and the interactive AcroForm are DROPPED and only self-contained URI links are kept — encrypt BEFORE signing, not after.
- decrypt_pdf: Open an encrypted PDF (pdfnative v1.6.0 reader/decryptor — RC4 V1–V4, AES-128 V4/R4, AES-256 V5/R6) and emit an UNENCRYPTED copy. Pass password (user or owner); documents with an empty user password decrypt without one. CAVEAT: decryption rebuilds the page tree, so existing signatures and the interactive AcroForm are DROPPED and only self-contained URI links are kept. To READ an encrypted PDF without rebuilding it, pass password directly to inspect_pdf / extract_text / extract_attachments instead.

Claude Desktop / Cursor

Paste into your MCP client config file to install this server.

{
    "mcpServers": {
        "pdfnative": {
            "pdfnative": {
                "command": "npx",
                "args": [
                    "-y",
                    "pdfnative-mcp"
                ]
            }
        }
    }
}

McpServers

{
    "pdfnative": {
        "command": "npx",
        "args": [
            "-y",
            "pdfnative-mcp"
        ]
    }
}

Model Context Protocol (MCP) serverthat bridges thepdfnativelibrary — a zero-dependency, ISO 32000-1 compliant PDF engine — to any MCP-compatible AI client (Claude Desktop, Cursor, Continue, ChatGPT, Zed, …).

pdfnative-mcpexposes24 production-grade toolsto any MCP host:

- 📊Native vector charts—add_chartrenders bar / horizontal-bar / line / pie / donut charts as pure PDF path operators (zero rasterisation, PDF/A-safe with auto alt text).generate_basic_pdfalso accepts achartblock for composition with text and tables.
- 📝Fill & flatten forms—read_form_fieldslists an existing AcroForm's fields;fill_formfills and/or flattens it via a non-destructive incremental update (the counterpart toadd_form).
- 🔐Encryption round-trip—encrypt_pdfre-secures with AES-128 / AES-256 (RC4 never emitted),decrypt_pdfrecovers an unencrypted copy, apasswordinput opens encrypted sources on the read-only tools, andmerge_pdfs/split_pdf/extract_pagesgainpassword+encrypt.
- 🔤Real text extraction—extract_textnow resolves each font's/ToUnicodeCMap (no more glyph-index output) and can return positionedruns.
- 🔗Native MCP resources— sandboxed generated PDFs becomepdfnative://output/…resources (resources/list+resources/read), with aresource_linkin file-mode results for cross-call re-reference.
- 🏷️Tool annotations— every tool advertisesreadOnlyHint/destructiveHint/idempotentHint/openWorldHint.
- ⬆Engine upgrade—
pdfnativev1.6.0(decrypt/re-encrypt,extractText, fill/flatten, charts; colour-emoji subset 221 → 1167 glyphs).

- 🤝AI governance + human-in-the-loop—draft_governance_issuelets an agent draft a fully compliant GitHub issuelocally(draft.md+ machine-readable compliance report). The agent is adraftsman, never an autonomous submitter: a human is the only gate, and the server makeszeroGitHub writes and no outbound network calls. Backed by thegovernance_contractanddraft_issue_workflowMCP prompts.
- ✏️Markup annotations—annotate_pdfoverlays highlight, sticky-note, underline, strikeout, squiggly, square, circle, line, and freetext annotations on an existing PDF via incremental update. It is avisual review layer, not a redaction— underlying bytes remain.
- 🔢Page labels ininspect_pdf— read-only surfacing of/PageLabelsranges (roman, decimal, prefixed).
- ∑Math / scientific script—add_international_textacceptslang: 'math'(explicit, likeemoji) to embed the Noto Sans Math face on demand.
- 🧩MCP prompts— the server now advertises thepromptscapability withgovernance_contractanddraft_issue_workflow.
- ⬆Engine upgrade— pdfnativev1.5.0.

-

🆕Three page-tree tools—merge_pdfs,split_pdf,extract_pages(built onpdfnative v1.4.0's page-tree API; encrypted sources are rejected).

🔖Bookmarks, page labels & nested lists—generate_basic_pdfgainsoutline('auto'or explicit tree),pageLabels, multi-levellistitems, andviewerPreferences.

📐Table cell borders & alignment—add_tablegainscellBorders,cellVAlign, andviewerPreferences;add_international_textgainsviewerPreferences.

🔐Constant-time signing—sign_pdfsigns RSA and EC-DER keys through anode:cryptoprovider with a transparent pure-JS fallback; signatures stay interoperable.

🆕Toolextract_attachments— read embedded files back out of a PDF (completes the Factur-X / ZUGFeRD round-trip) with byte-for-byte payloads, afilenamefilter, and anincludeData: falsemetadata-only probe.

💧Watermarks—generate_basic_pdfandadd_tableaccept an optionalwatermark(text, opacity, angle, colour, position) rendered on every page.

🌐Unicodenormalize— opt-inNFC/NFD/NFKC/NFKDongenerate_basic_pdfandadd_international_text.

🪙Token-frugal reads— the read-only tools (inspect_pdf,verify_pdf,validate_pdf,extract_text,extract_attachments) accept optionalverbosity: 'summary'andfields: […]inputs for ~90% smaller responses on large results, with no loss of the fields agents branch on. Defaults are unchanged.

🪙No base64 duplication— generated PDFs (base64 mode) are returnedonceas an embeddedresourcecontent block instead of also being copied intostructuredContent.

🔧MCP registry publish fix—mcpNamenow uses the canonical GitHub login casing (io.github.Nizoka/pdfnative-mcp) so the registry's case-sensitive validation accepts the npm package.

- 🆕Toolvalidate_pdf— read-only PDF/UA (ISO 14289-1) structural conformance check.
- 🆕Six new scripts— Telugu, Sinhala, Tibetan, Khmer, Myanmar, Ethiopic (24 scriptstotal).
- 🆕COLRv1 colour emoji— native colour emoji with monochrome fallback.
- 🆕Newline sanitizer— embedded\nin paragraphs auto-splits into separate paragraphs (Safe PDF/A).
- 🆕Automatic NFC normalisationforadd_international_text.
- 🛠Engine upgrade—pdfnative v1.3.0: the Euro sign / CP-1252 symbols now extract correctly, and wrapped table cells get unique per-line MCIDs (PDF/UA-safe).

- 🆕Three new tools:verify_pdf,add_attachment(Factur-X / ZUGFeRD),extract_text.
- 🆕Smart-table fields:wrap,repeatHeader,zebra,caption,minRowHeight,cellPadding.
- 🆕inspect_pdfnow reportshasSignaturePlaceholderand per-attachment summary; newcheckvalues'placeholder'and'attachments'.
- 🆕Signing ergonomics:sign_pdfaccepts ECDSA SEC1 / PKCS#8 DER keys and auto-injects a/Sigplaceholder when missing (one-call signing of any PDF).
- 🆕Opt-in cache(PDFNATIVE_MCP_CACHE_DIR): SHA-256 keyed, 1 h TTL, 256 MiB LRU.
- 🆕_meta.apiVersionand per-tool_meta.examplesfor AI-agent discovery — see
docs/API_STABILITY.md.
- 🆕AI agent guide:
docs/AI_GUIDE.md— decision tree + common pitfalls. See also the rootAGENTS.mdoperations manual.
- 🆕PDF/A authoring guide:
[docs/guides/PDFA.md.
- 🛠Env-var rename:PDFNATIVE_MCP_OUTPUT_DIR(wasPDFNATIVE_MPC_OUTPUT_DIR; old name still works with a one-shot deprecation warning).
- ✅Now shipped:merge_pdfs,split_pdf,extract_pages(v1.3.0),annotate_pdf(v1.4.0), and theadd_chart/read_form_fields/fill_form/encrypt_pdf/decrypt_pdftools plus the encrypted round-trip and native MCP resources (v1.5.0).redact_pdfstaysdeferred— pdfnative can overlay/flatten but notremovepage content, and an overlay-only "redaction" would create false security, so it is intentionally not shipped (tracked as an upstream content-removal request).

- base64(default)— the generated PDF is returnedonceas an embeddedresourcecontent block (adata:application/pdf;base64,…URI);structuredContentcarries only{ mode, sizeBytes }.
- file— the PDF is written to a sandboxed directory configured viaPDFNATIVE_MCP_OUTPUT_DIR. File output is disabled unless this variable is set; absolute paths, path traversal, non-.pdfextensions, and NUL bytes are all rejected.

Upgrading from v1.1.0:the only behaviour change is that base64-mode bytes are no longer duplicated intostructuredContent.base64. Read them from the embeddedresourceblock instead:

- 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

Token-frugal reads (v1.2.0).The four read-only tools accept two optional inputs:

…

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.