Install
$ agentstack add mcp-nizoka-pdfnative-mcp Open-source listing — not yet scanned by AgentStack. Follow the source repository for install instructions.
About
pdfnative-mcp
> Model Context Protocol (MCP) server that bridges the pdfnative library — a zero-dependency, ISO 32000-1 compliant PDF engine — to any MCP-compatible AI client (Claude Desktop, Cursor, Continue, ChatGPT, Zed, …).
[](https://www.npmjs.com/package/pdfnative-mcp) [](https://www.npmjs.com/package/pdfnative-mcp) [](https://nodejs.org) [](LICENSE) [](https://github.com/Nizoka/pdfnative-mcp/actions/workflows/ci.yml) [](https://modelcontextprotocol.io) [](https://www.typescriptlang.org/) [](https://scorecard.dev/viewer/?uri=github.com/Nizoka/pdfnative-mcp) [](https://github.com/Nizoka/pdfnative-mcp/actions/workflows/codeql.yml)
✨ Features
pdfnative-mcp exposes 14 production-grade tools to any MCP host:
| Tool | Purpose | | ---------------------------------- | ------------------------------------------------------------------------------------------------ | | generate_basic_pdf | Multi-page A4 documents from structured blocks (headings, paragraphs, lists, page breaks). Embedded newlines auto-split into paragraphs. Optional pdfA. | | add_barcode | QR Code, Code 128, EAN-13, Data Matrix, PDF417 — embedded in a single-page PDF. | | add_international_text | 24 scripts (incl. Latin & COLRv1 colour emoji) with BiDi & OpenType shaping; multi-lang per document. | | add_table | Tabular reports with smart fields (wrap, repeatHeader, zebra, caption, minRowHeight, cellPadding). | | add_form | Interactive AcroForm PDFs with text fields, checkboxes, radio buttons, dropdowns. | | embed_image | Embed a JPEG or PNG image (base64) into a titled PDF document. | | prepare_signature_placeholder | Step 1 of the two-step sign workflow — create a PDF with a /Sig AcroForm placeholder. | | sign_pdf | Apply a PAdES-compatible CMS signature (RSA-SHA256 / ECDSA-SHA256 P-256). Auto-injects a placeholder when needed. | | verify_pdf | Verify every PAdES signature in a PDF (integrity + signature value + optional chain trust). | | validate_pdf (new in v1.1.0) | Validate a Tagged PDF for PDF/UA (ISO 14289-1) structural conformance (read-only). | | add_attachment | Generate a PDF/A-3 document with embedded files (Factur-X / ZUGFeRD invoices). | | extract_attachments | Read-only extraction of embedded files (Factur-X / ZUGFeRD XML round-trip) with byte-for-byte payloads. | | extract_text | Best-effort plain-text extraction from a non-encrypted PDF. | | inspect_pdf | Read-only inspection: PDF version, page count, encryption, PDF/A claim, signatures, attachments, placeholder state. |
New in v1.2.0:
- 🆕 Tool
extract_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. - 🌐 Unicode
normalize— 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 returned once as an embedded
resourcecontent 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. - ⬆ Dependency — upgraded to zod 4.
New in v1.1.0:
- 🆕 Tool
validate_pdf— read-only PDF/UA (ISO 14289-1) structural conformance check. - 🆕 Six new scripts — Telugu, Sinhala, Tibetan, Khmer, Myanmar, Ethiopic (24 scripts total).
- 🆕 COLRv1 colour emoji — native colour emoji with monochrome fallback.
- 🆕 Newline sanitizer — embedded
\nin paragraphs auto-splits into separate paragraphs (Safe PDF/A). - 🆕 Automatic NFC normalisation for
add_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).
New in v1.0.0:
- 🆕 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](docs/API_STABILITY.md). - 🆕 AI agent guide: [
docs/AI_GUIDE.md](docs/AI_GUIDE.md) — decision tree + common pitfalls. See also the root [AGENTS.md](AGENTS.md) operations manual. - 🆕 PDF/A authoring guide: [
docs/guides/PDFA.md](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). - ⏭ Deferred to v1.1:
merge_pdfs,split_pdf,redact_pdf(require pdfnative page-tree primitives not yet exported).
All tools support two output modes:
base64(default) — the generated PDF is returned once as 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 into structuredContent.base64. Read them from the embedded > resource block instead: > > ``diff > - 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:
verbosity: 'summary'— returns a compact scalar-only verdict (drops the heavy arrays / full text). E.g.verify_pdf→{ signatureCount, allValid, invalid, summary }.fields: ['a', 'b.c']— projects the structured result to named dot-paths; composes afterverbosity. Unknown paths are omitted leniently.
Smallest “is this PDF signed and valid?” probe: { "pdfBase64": "…", "verbosity": "summary", "fields": ["allValid"] }.
Why pdfnative?
pdfnative-mcp inherits every guarantee of the underlying engine:
- Zero runtime dependencies — pure JavaScript, no native bindings.
- ISO 32000-1 (PDF 1.7) compliant output.
- PDF/A-1b/2b/3b, AES-128/256 encryption, AcroForm, digital signatures.
- 16 Unicode scripts with built-in BiDi reordering, Arabic positional shaping, Thai/Devanagari/Bengali/Tamil OpenType shaping.
- Tree-shakeable ESM build.
🚀 Installation
# Run directly with npx (recommended for MCP clients)
npx -y pdfnative-mcp
# Or install globally
npm install -g pdfnative-mcp
pdfnative-mcp
Requirements: Node.js ≥ 22.
⚙️ Configuration
Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %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
Any MCP-compatible client that supports stdio servers will work. Use the same command + args + env triple. Example for 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 use the same shape inside their respective MCP config files.
Environment variables
| Variable | Purpose | | ----------------------------- | ---------------------------------------------------------------------------------- | | PDFNATIVE_MCP_OUTPUT_DIR | Absolute path to the sandbox directory. Required to enable outputMode: 'file'. | | PDFNATIVE_MCP_CACHE_DIR | Absolute path to enable the persistent SHA-256-keyed result cache (1 h TTL, 256 MiB LRU). When unset, the cache is disabled. | | PDFNATIVE_MCP_PORT | When set to a valid port (1–65535), starts an HTTP server on http://127.0.0.1:/mcp instead of stdio. |
🛠 Tool reference
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"
}
Supported formats: qr, code128, ean13, datamatrix, pdf417.
add_international_text
{
"title": "مرحبا بالعالم",
"lang": "ar",
"paragraphs": [
"هذا اختبار للنص العربي مع تشكيل OpenType ومحارف ثنائية الاتجاه.",
"Mixed content: العربية + English ✓"
]
}
Supported lang codes: ar, he, th, ja, zh, ko, el, hi, bn, ta, ru, ka, hy, tr, vi, pl, latin, emoji.
Multi-script documents — pass an array or comma-separated list:
{
"title": "Mixed Script",
"lang": ["ar", "emoji"],
"paragraphs": ["العربية مع رموز 🎉🚀"],
"pdfA": "pdfa2u"
}
sign_pdf
As of v1.0.0, sign_pdf auto-injects a /Sig placeholder when missing — you can sign any PDF in one call:
{
"pdfBase64": "",
"algorithm": "rsa-sha256",
"certDerBase64": "",
"rsaKeyPkcs1DerBase64": "",
"signerName": "Alice",
"reason": "Approval",
"location": "Paris, FR",
"signingTime": "2026-01-15T10:30:00Z"
}
For ECDSA P-256: use algorithm: "ecdsa-sha256" and supply either ecPrivateKeyDerBase64 (SEC1 or PKCS#8 DER) or ecPrivateScalarHex (64 hex chars).
PEM → DER conversion:
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
> Use prepare_signature_placeholder only when you need to customize the placeholder (e.g. larger placeholderBytes for >4096-bit RSA keys). Otherwise call sign_pdf directly.
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": "",
"mimeType": "image/jpeg",
"caption": "Front view of Model X",
"width": 400,
"outputMode": "base64"
}
> Note: pdfnative does not support alpha-channel PNGs (color type 6). Pre-process such images to remove the alpha channel before embedding.
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"
}
Pass the returned PDF bytes to sign_pdf to complete the signing workflow.
inspect_pdf
Read-only structural and security inspection — useful for downstream verification, CI assertions, and AI agents that need to reason about a PDF before acting on it.
{
"pdfBase64": "",
"pages": true,
"check": ["pdfa", "signed", "attachments"]
}
Returns:
{
"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[] accepts any of 'pdfa', 'signed', 'encrypted', 'placeholder', 'attachments'. checksPassed is the AND of all requested checks.
validate_pdf
Read-only PDF/UA (ISO 14289-1) structural conformance check for a Tagged PDF. Generate an accessible document with any tool using pdfA (e.g. pdfA: 'pdfa2u'), then validate the result:
{ "pdfBase64": "" }
Returns:
{
"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."
}
It verifies catalog /MarkInfo /Marked true, /StructTreeRoot (+ /ParentTree), /Metadata (XMP), /Lang, and per-page MCID uniqueness. This is a fast developer-time gate — not a substitute for a full reference validator (veraPDF), which additionally checks fonts, colour, and rendering.
verify_pdf, add_attachment, extract_text
See the dedicated sections in [docs/AI_GUIDE.md](docs/AIGUIDE.md) and the reference in [docs/KNOWLEDGE_BASE.md](docs/KNOWLEDGEBASE.md). Ready-to-run examples live under [examples/](examples/).
🔐 Security model
pdfnative-mcp runs inside the host process and exposes a stdio MCP serv
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Nizoka
- Source: Nizoka/pdfnative-mcp
- License: MIT
- Homepage: https://pdfnative.dev
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v1.2.0 Imported from the upstream source.