Server data from the Official MCP Registry
PDF MCP server: PDF/A, PDF/X-4, PAdES (LTV), forms, 32 scripts, JPEG 2000, spot colours. 28 tools
About
PDF MCP server: PDF/A, PDF/X-4, PAdES (LTV), forms, 32 scripts, JPEG 2000, spot colours. 28 tools
Security Report
pdfnative-mcp is a PDF generation and manipulation MCP server that runs locally over stdio, with an optional loopback-only HTTP mode protected by an opt-in bearer token. The visible code shows deliberate security hardening (output sandboxing, zip-bomb caps, refusal to cache encrypted or password-bearing outputs, weak-token rejection) and no exfiltration, shell execution, or hardcoded secrets in the excerpts reviewed. Remaining concerns are minor: the HTTP mode is unauthenticated by default and the excerpt is truncated so not every tool implementation was inspected. Supply chain analysis found 2 known vulnerabilities in dependencies (0 critical, 1 high severity). Package verification found 1 issue.
6 files analyzed · 6 issues found
Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.
Permissions Required
This plugin requests these system permissions. Most are normal for its category.
What You'll Need
Set these up before or after installing:
Environment variable: PDFNATIVE_MCP_OUTPUT_DIR
Environment variable: PDFNATIVE_MCP_OUTPUT_BASE_URL
Environment variable: PDFNATIVE_MCP_CACHE_DIR
Environment variable: PDFNATIVE_MCP_FONT_DIR
Environment variable: PDFNATIVE_MCP_PORT
Environment variable: PDFNATIVE_MCP_HTTP_TOKEN
Environment variable: PDFNATIVE_MCP_MAX_INFLATE_BYTES
Environment variable: PDFNATIVE_MCP_CREATION_DATE
Environment variable: SOURCE_DATE_EPOCH
Environment variable: PDFNATIVE_MCP_TSA_URL
Environment variable: PDFNATIVE_MCP_TSA_AUTH
Environment variable: PDFNATIVE_MCP_REVOCATION
Environment variable: PDFNATIVE_MCP_NETWORK_ALLOWED_HOSTS
Environment variable: PDFNATIVE_MCP_NETWORK_TIMEOUT_MS
How to Install
Add this to your MCP configuration file:
{
"mcpServers": {
"io-github-nizoka-pdfnative-mcp": {
"env": {
"SOURCE_DATE_EPOCH": "your-source-date-epoch-here",
"PDFNATIVE_MCP_PORT": "your-pdfnative-mcp-port-here",
"PDFNATIVE_MCP_TSA_URL": "your-pdfnative-mcp-tsa-url-here",
"PDFNATIVE_MCP_FONT_DIR": "your-pdfnative-mcp-font-dir-here",
"PDFNATIVE_MCP_TSA_AUTH": "your-pdfnative-mcp-tsa-auth-here",
"PDFNATIVE_MCP_CACHE_DIR": "your-pdfnative-mcp-cache-dir-here",
"PDFNATIVE_MCP_HTTP_TOKEN": "your-pdfnative-mcp-http-token-here",
"PDFNATIVE_MCP_OUTPUT_DIR": "your-pdfnative-mcp-output-dir-here",
"PDFNATIVE_MCP_REVOCATION": "your-pdfnative-mcp-revocation-here",
"PDFNATIVE_MCP_CREATION_DATE": "your-pdfnative-mcp-creation-date-here",
"PDFNATIVE_MCP_OUTPUT_BASE_URL": "your-pdfnative-mcp-output-base-url-here",
"PDFNATIVE_MCP_MAX_INFLATE_BYTES": "your-pdfnative-mcp-max-inflate-bytes-here",
"PDFNATIVE_MCP_NETWORK_TIMEOUT_MS": "your-pdfnative-mcp-network-timeout-ms-here",
"PDFNATIVE_MCP_NETWORK_ALLOWED_HOSTS": "your-pdfnative-mcp-network-allowed-hosts-here"
},
"args": [
"-y",
"pdfnative-mcp"
],
"command": "npx"
}
}
}Documentation
View on GitHubFrom the project's GitHub README.
pdfnative-mcp
MCP server for PDF generation, PDF/A archival, PDF/X-4 print exchange, spot colours, right-to-left and 32-script text, JPEG 2000, fine typography, PAdES signing with long-term validation, AcroForms, merge/split, encryption and layout preview — 28 tools and 7 prompts on the pdfnative engine (zero-dependency, ISO 32000-1 compliant), for Claude Desktop, Cursor, ChatGPT and any Model Context Protocol client.
✨ Features
pdfnative-mcp exposes 28 production-grade tools to any MCP host:
| Tool | Purpose |
|---|---|
generate_basic_pdf | Multi-page documents from 13 block kinds — heading, paragraph, list, table, image (JPEG/PNG/JPEG 2000), link, toc (printed table of contents), barcode, svg, formField, chart, pageBreak, spacer — every DocumentBlock the engine offers. Embedded newlines auto-split into paragraphs. Optional pdfA, pdfx (new in v1.7.0), print, metadata, embedFonts, watermark, outline, layout options (pageSize, margins, headerTemplate / footerTemplate, compress, debug, encrypt), typography (new in v1.7.0) and CMYK colours (new in v1.7.0). |
inspect_layout (new in v1.6.0) | Read-only pagination dry run of the same blocks (+ title, footerText, pdfA, normalize, embedFonts, font, pageSize, margins, headerTemplate, footerTemplate, typography): page count and where every block lands, no PDF produced. |
add_barcode | QR Code, Code 128, EAN-13, Data Matrix, PDF417 — embedded in a single-page PDF. |
add_international_text | 32 Unicode scripts — Gujarati, Gurmukhi, Kannada, Malayalam and Odia (new in v1.8.0), Lao, Tai Tham, New Tai Lue, Tai Le and Cham (v1.7.0) — plus Latin, math and COLRv1 colour emoji (flag / ZWJ sequences, skin-tone modifiers), with BiDi & OpenType shaping; multi-lang per document. |
add_table | Tabular reports with smart fields (wrap, repeatHeader, zebra, caption, minRowHeight, cellPadding). |
add_form | Create a new interactive AcroForm PDF with text fields, text areas, checkboxes, radio buttons, dropdowns, list boxes (+ placeholder hint text). |
read_form_fields | Read-only enumeration of an existing AcroForm's field tree (names, types, values, widgets). |
fill_form | Fill and/or flatten an existing AcroForm (non-destructive incremental update). |
add_chart | Native vector charts v2 — bar / barH / stackedBar / stackedBarH / line / area / scatter / pie / donut, secondary axis, log & time scales, data labels, per-value bar colours and optional series labels (new in v1.8.0) (pure PDF path operators, PDF/A-safe). |
embed_image | Embed a JPEG, PNG or JPEG 2000 image (image/jp2, new in v1.8.0) (base64) into a titled PDF document (align, alt text for tagged output). |
prepare_signature_placeholder | Optional step 1 of the sign workflow — create a PDF with a /Sig placeholder (signer metadata, subFilter, reserveTimestamp baked in). |
sign_pdf | PAdES B-B / B-T CMS signature (RSA-SHA256/384/512, ECDSA-SHA256 P-256; profile: 'pades', timestamp, certChainDerBase64, multiple signatures, pinnable signingTime). Auto-injects a placeholder when needed. |
add_ltv (new in v1.6.0) | PAdES B-LT — embed a /DSS with certificates + OCSP/CRL material (operator-configured provider, or caller-supplied offline material composed by the engine — `match: 'all' |
timestamp_pdf (new in v1.6.0) | PAdES B-LTA — append an RFC 3161 /DocTimeStamp from the operator-configured TSA; re-run to extend the archival chain. |
verify_pdf | Verify every PAdES signature and document timestamp (integrity + signature value + optional chain trust; a /DocTimeStamp counts in allValid like any signature); ltv: true reports the B-B…B-LTA level. |
validate_pdf | Validate a Tagged PDF for PDF/UA (ISO 14289-1) structural conformance, or with standard: 'pdf-x-4' (new in v1.7.0) the structural prerequisites of PDF/X-4 (ISO 15930-7) — read-only, not a certified preflight. |
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 | Unicode text extraction (resolves /ToUnicode; logical order for right-to-left and Indic text, tagged or not) with optional positioned runs; onStreamError (new in v1.8.0); opens encrypted PDFs via password. |
inspect_pdf | Read-only inspection: PDF version, page count, encryption (+ precise encryptionInfo), PDF/A claim, PDF/X claim (pdfX, new in v1.7.0), signatures (+ inventory, /DSS, document timestamps), page boxes, /Trapped, attachments, placeholder state, annotations: true inventory of existing page annotations. |
update_metadata (new in v1.6.0) | Rewrite /Info title / author / subject / keywords (+ XMP, dates included) of an existing PDF as an incremental update; pin modDate for reproducible bytes. |
encrypt_pdf | Re-secure a PDF with AES-128 / AES-256 (owner/user passwords, permissions, password rotation). |
decrypt_pdf | Emit an unencrypted copy of an RC4 / AES-128 / AES-256 document. |
merge_pdfs | Concatenate 2–50 PDFs into one via pdfnative's page-tree API (page boxes preserved). |
split_pdf | Split one PDF into one document per page range (multi-output). |
extract_pages | Pull an arbitrary page subset into a single PDF. |
annotate_pdf | Add markup annotations (highlight, note, square/circle, line, freetext) and link annotations (new in v1.8.0) as a visual overlay — not a redaction. |
draft_governance_issue | Draft a governance-compliant GitHub issue locally for human review; never submits, no network. |
New in v1.8.0:
- 🎨 Spot colours —
print.spotColoursdeclares inks with a process alternate;{ spot, tint }(a /Separation plate) and{ inks: { … } }(a /DeviceN mix) are accepted wherever a colour is — table borders, templates, watermarks, charts, SVG, annotations. An undeclared ink is refused by name. - ↔️ Right-to-left documents —
direction: 'auto' | 'ltr' | 'rtl'on the nine document tools,inspect_layoutand each paragraph; untagged output carries/ActualTexton right-to-left and reordered shaped runs (actualText: falseto opt out), soextract_textreturns reading order with or without a PDF/A claim. - 🌏 32 Unicode scripts —
add_international_textgainsgu(Gujarati),pa(Gurmukhi),kn(Kannada),ml(Malayalam) andor(Odia); every shaper names its glyphs inToUnicode, so Tai Tham passes PDF/A-2u too. - 🖼️ JPEG 2000 —
mimeType: 'image/jp2'(a JP2 file or a raw codestream) onembed_image, theimageblock and image watermarks, embedded as/JPXDecodewithout re-encoding;PDFA1_JPX_IMAGEunder PDF/A-1,PDFA_JPX_IMAGEfor an opacity channel. - 🖨️ PDF/X-4 + PDF/A-2 dual claim —
pdfx: 'pdfx4'combines withpdfA: 'pdfa2b' | 'pdfa2u'in one file;pdfa1bandpdfa3bare refused with the engine's own message. - 🔗 Link annotations —
annotate_pdf type: 'link'adds a/URIlink to an existing page (http:/https:/mailto:). - 🔤 Operator fonts —
PDFNATIVE_MCP_FONT_DIRregisters the operator's.ttf/.otffiles at boot (parsed by the engine, ≤ 64 files);font: '<slug>'ongenerate_basic_pdf,inspect_layoutandadd_international_textdraws that face first —FONT_NOT_FOUNDlists the slugs. See docs/guides/FONTS.md. - 🌐 File mode behind a reverse proxy —
PDFNATIVE_MCP_OUTPUT_BASE_URLmaps the sandbox to a public base URL: file-mode results carryurland name it instead of the host's path (issue #66); pure string formatting, never requested. - 📊 Charts —
series[].colors(one colour per bar) and an optional serieslabel("Series N" otherwise). - 🔏 LTV, ECDSA —
add_ltv mode: 'offline'composes/DSS+/VRIthrough the engine (match: 'all' | 'chain');verify_pdfverifies ECDSA through the engine'secdsaVerifyHash(the local P-256 code is gone). - 📖 extract_text — a content stream over the decompression cap is now
PDF_PARSE_FAILEDnaming the remedy (onStreamError: 'skip'restores the 1.7.0 empty page);inspect_pdfdecodes/Infotext strings (UTF-16BE titles read back as text). - 🤝 Governance as resources —
pdfnative://governance/policyandpdfnative://governance/rulesserve the AI-governance contract byte-identical to the repository (always listed); 13 engine diagnostics (4 new), 48 error codes (FONT_NOT_FOUND),prepare_signature_placeholder.blockstakes 5000 items likegenerate_basic_pdf(llama.cpp grammar, issue #65); calls carryingpasswordare never cached. - 🧪 Hardening — the pdfnative 1.9 release pipeline (guard → build → publish → attest → registry: Trusted Publishing, SHA-512-pinned npm client, registry bytes attested with three SBOMs,
server.jsonpublished to the MCP registry with the workflow's OIDC identity), ClusterFuzzLite over five boundary targets,workflow-lint(zizmor + actionlint) as a required check, block-mode egress on the Linux jobs whose hosts are baselined (audit mode with a dated reason elsewhere), CodeQL on the workflows, Node 26 advisory, apack-manifestgate step, every Dependabot and code-scanning alert of the 1.7.0 line closed. Catalogue:tools/list≈ 357 kB under a 384 KiB budget. - ⬆ Engine upgrade — pdfnative v1.9.0. No breaking change to the tool API; the bytes that change (lean compact subsets,
/ActualTextspans, one text object per line) are declared in the release note and the sample baseline is re-anchored once.
New in v1.7.0:
- 🔤 Fine typography — an opt-in
typographyobject on the nine document tools and oninspect_layout:splitParagraphswithorphans/widows,keepHeadingsWithNext,unitBinding,bindShortWords,punctuationSpacing('fr','fr-CA'or explicit rules),opticalMargins,metrics: 'exact',fontFeatures(11 OpenType tags),kerning,hyphenationLanguage. Paragraph blocks gainalign(left/right/center/justify),keepWithNextandsplittable; heading blocks gainkeepWithNext. Honest limits:kerning,fontFeaturesand the'fr'narrow no-break space needembedFonts: true(base-14 Helvetica degrades'fr'to'fr-CA');tnum/lnumchange nothing on the bundled Noto Sans (diagnosticTYPOGRAPHY_FEATURE_INEFFECTIVE); no hyphenation dictionary is installed, sohyphenationLanguagehas no effect here — soft hyphens (U+00AD) are honoured. Seedocs/guides/TYPOGRAPHY.md. - 🎨 CMYK everywhere a colour is accepted —
'c m y k'operand strings (0–1) and[c, m, y, k]percent tuples (0–100) beside the existing hex / RGB forms: watermarks, header / footer templates, table cell borders, outline entries, charts,linkandsvgblocks,annotate_pdf. Every 1.6.0 colour form still validates. - 🖨️ PDF/X-4 —
pdfx: 'pdfx4'on six generation tools (generate_basic_pdf,add_table,add_chart,add_barcode,embed_image,add_international_text), CMYK or GrayoutputIntentprofiles beside RGB,print.marks.colourBars, andvalidate_pdf { standard: 'pdf-x-4' }to check the result;inspect_pdfreports the claim (pdfX, check'pdfx'). It requires the printer's ICC profile (device classprtr— none is bundled), needsembedFonts: truefor a conformant file (PDFX_NO_FONT_ENTRIESotherwise;strict: truerefuses), and combines withpdfA: 'pdfa2b' | 'pdfa2u'since v1.8.0 (pdfa1b/pdfa3bandencryptrefused). The validation is structural — not a certified preflight; the result says so itself incaveats[]. Seedocs/guides/PRINT.md. - 🌏 27 Unicode scripts —
add_international_textacceptslo(Lao),nod(Tai Tham),khb(New Tai Lue),tdd(Tai Le) andcjm(Cham);ha,yo,ig,sware aliases oflatin(tone marks attach); emoji skin-tone modifiers render. Tai Tham under PDF/A must usepdfa2b, notpdfa2u(one glyph lacks aToUnicodeentry upstream). - 🔁 Reproducible on every host — every date is written in UTC,
{date}in a header or footer follows the pinned instant, and the operator can pin the whole process withPDFNATIVE_MCP_CREATION_DATEorSOURCE_DATE_EPOCH(see Environment variables). Not covered, by design:signingTime,modDate, RFC 3161 tokens and revocation data, encryption, ECDSA signatures. Seedocs/guides/REPRODUCIBLE.md. - 🚦
strictescalates by diagnostic code —PDFA_*→PDF_A_COMPLIANCE_VIOLATION,PDFX_*→PDF_X_COMPLIANCE_VIOLATION(new), anything else →DIAGNOSTIC_ESCALATED(new). Both new codes can only be returned by a call that setsstrict: true. - 🧩 A seventh MCP prompt,
typography— andprint_ready,reproducible_output,pdfa_validrewritten for CMYK, PDF/X-4, colour bars and the UTC / operator pin. - 🐛 Fixes — a 0–1 RGB triple (
watermark.color, theannotate_pdfcolours) now renders the colour it names ([1, 0, 0]used to render almost black); any unexpected failure of a tool that takes PDF input is classifiedPDF_PARSE_FAILEDinstead of surfacing uncoded. - ✅ Closed upstream — a PDF/A form built with
embedFonts: truenow validates under veraPDF (the AcroForm font is embedded), andinspect_layoutmeasures atocblock exactly as the build lays it out. - 🧪 One gate, hardened CI, verified docs —
npm run gateis the single definition of green (the built server is driven over stdio and stdout must carry JSON-RPC frames only); veraPDF is blocking over a 41-file conformance corpus; a 96-sample byte baseline guards the output;npm run verify:docsholds every count, version, tool, error code and operator variable quoted in the docs todocs/assets/ecosystem.jsonand the source tree. - 🧾 Catalogue —
tools/listgrows to ≈ 306 kB in 1.7.0 (the typography fragment and the widened colour schemas are inlined in every tool that carries them;npx tsx scripts/tool-shape.ts --checkheld it under 320 KiB and the instructions under 8 KiB);_meta.apiVersionis1.7.0. - ⬆ Engine upgrade — pdfnative v1.8.0. No breaking change to the tool API; the bytes that do change (embedded TrueType subsets,
print.marks, shaped text with mark positioning, UTC dates) are listed under Upgrade inrelease-notes/v1.7.0.md.
New in v1.6.0:
- 🧱 Full engine coverage — 13 block kinds —
generate_basic_pdfaccepts everyDocumentBlockpdfnative offers: the newtable,image,link,toc,barcode,svgandformFieldblocks share their body with the dedicated tools (add_table,embed_image,add_barcode,add_form) so a standalone artefact and an inline block validate and render identically. Rules:linkacceptshttp:/https:/mailto:only (control characters rejected);imageblocks are bounded (12 M base64 characters each, 24 MiB decoded per call; PNG must be 8-bit, non-interlaced, without alpha or palette — rejected with a remedy);svgcovers paths, basic shapes and<text>(notransform,<g>, gradients or CSS — silently ignored; nothing is ever fetched);tocpairs withoutline: 'auto';formFieldunder a PDF/A claim reportsPDFA_UNEMBEDDED_FORM_FONT;barcodehas noalt(engine limitation). - 📐 Layout options on the nine document tools —
pageSize(A4default,Letter,Legal,A3,Tabloid),margins(all four, 0–200 pt),headerTemplate/footerTemplatewith{page}{pages}{title}{date}(afooterTemplatereplaces the default footer, sofooterTextis then ignored;{date}was the build-day wall clock in 1.6.0 — since v1.7.0 it follows the pinned instant),compress(FlateDecode streams — smaller file, different bytes; XMP stays plain under PDF/A) anddebug(guide rectangles, unmarked content — not for PDF/UA). Absent by default, so default output stays byte-identical. - 🔐 Encryption at build time —
encrypton seven document tools (generate_basic_pdf,add_table,add_form,add_international_text,embed_image,add_barcode,add_chart): Standard Security Handler, AES-128 default / AES-256, keeps the AcroForm (unlikeencrypt_pdf, which rebuilds the page tree). Exclusive withpdfA(VALIDATION_ERROR), never cached; not offered onprepare_signature_placeholder(must stay signable) oradd_attachment(PDF/A-3). - 📏
inspect_layout— the 28th tool: a read-only pagination dry run over the sameblocksand layout inputs, reportingtotalPagesand each block's page / x / top / width / height without rendering a PDF. Known engine gap in 1.6.0 (closed in v1.7.0): atocblock was measured as 0 pt, so documents with a printed contents could paginate one page later than previewed. - 🔎
inspect_pdf annotations: true— lists every page annotation (subtype, 0-based page, rect, contents truncated to 200 chars, title, colour, quadPoints, link URL) plusannotationCount; newcheck: 'annotations'. - 🖼️ Image watermarks —
watermark.image(JPEG/PNG, default opacity 0.10, own 8 MiB cap) ongenerate_basic_pdfandadd_table, alone or combined withtext(default opacity 0.15);position: 'background' | 'foreground'for both. Either opacity below 1.0 is rejected underpdfa1b. - 🧯
PDFNATIVE_MCP_MAX_INFLATE_BYTES— operator override of the engine's 100 MiB per-stream decompression cap (integer ≥ 1024; an invalid value refuses to start). A capped attachment stream failsextract_attachments includeData: truewithPDF_PARSE_FAILED;extract_textdegrades to empty page text (the engine swallows per-page decode failures). - 📝 Forms —
add_formandformFieldblocks gainlistboxandplaceholder;fieldType: 'textarea'now reaches the engine asmultilineText(it was passed through unmapped before and rendered as a single-line field — a bug fix that changes bytes for that input).embed_imagegainsalignandalt. - 🔏 PAdES long-term validation ladder —
sign_pdfgainsprofile: 'pades'(ETSI EN 319 142-1 baseline, ESS signing-certificate-v2,ETSI.CAdES.detached),timestamp: true(B-T, RFC 3161), RSA-SHA384/512,certChainDerBase64,fieldName/allowMultiplefor several signatures; newadd_ltvembeds a/DSS(B-LT,mode: 'online'through the operator provider ormode: 'offline'with caller-supplied DER material); newtimestamp_pdfappends a/DocTimeStamp(B-LTA).verify_pdf ltv: truereports profile, timestamp, revocation status andltvLevel. Seedocs/guides/LTV.md. - 🌐 Network charter — no outbound request by default. The only egress the server can ever perform goes to the RFC 3161 / OCSP / CRL endpoints the operator configured (
PDFNATIVE_MCP_TSA_URL,PDFNATIVE_MCP_REVOCATION,PDFNATIVE_MCP_NETWORK_ALLOWED_HOSTS), behind an SSRF guard; tool arguments can never supply a URL. - 🖨️ Print production — every document tool accepts
print(TrimBox / BleedBox / ArtBox / CropBox or thebleedshorthand, crop + registrationmarks,/UserUnit),metadata(/Author,/Subject,/Keywords,/Trapped) andoutputIntent(custom RGB ICC for PDF/A);viewerPreferencesgainsduplex,pickTrayByPDFSize,printPageRange,numCopies.inspect_pdf pages: truereports the boxes; merge / split / extract preserve them. Seedocs/guides/PRINT.md. - ✍️
update_metadata— rewrite/Info+ XMP of an existing PDF as an incremental update (earlier revisions and signatures preserved verbatim). - 📊 Charts v2 —
stackedBar/stackedBarH/area/scatter, secondary right axis (axis2),axis.scale: 'log',xAxis.type: 'linear' | 'time',dataLabels,labelStride/labelRotation; overlapping category labels are thinned automatically. - 📜 Honest PDF/A —
embedFonts: trueembeds Noto Sans Latin (base-14 Helvetica is not embedded, so a PDF/A claim on plain Latin text is rejected by veraPDF),strict: truefails instead of producing a non-conformant file,includeDiagnostics: trueechoes engine diagnostics. Local veraPDF script (npm run validate:pdfa) over a 26-file corpus (24 validated, 3 of them negative canaries; 2 page-tree outputs skipped) and a fail-closedVERAPDF_REQUIRED=1mode; the CI workflow pins the installer by SHA-256 and stays non-blocking in 1.6.0 (blocking since v1.7.0, where--require-allon the gate replacesVERAPDF_REQUIRED=1). Known engine gaps in 1.6.0:add_formoutput fails PDF/A-2b even withembedFonts(unembedded/DR /Helv— closed in v1.7.0), and aprepare_signature_placeholderoutput is conformant only once signed. - 🧰
inspect_pdf—signatures: trueinventory,dss/docTimestampCount/trapped(presence-gated), newcheckvaluesdss,docTimestamp,trapped;checkslists only the keys you requested, andsignedis structural (a signed field exists — validity isverify_pdf's job). - 🔁 Reproducible output — opt-in
creationDateon all nine document tools pins/CreationDate, the XMP dates and the trailer/ID;signingTimeonprepare_signature_placeholder(and onsign_pdf, now with time-zone offsets) pins/Sig /M. Identical bytes on the same host time zone in 1.6.0 (on every host since v1.7.0: dates are written in UTC). Backed by thereproducible_outputprompt. - 🛡️ Hardened boundary — strict input schemas (unknown or misspelt keys →
VALIDATION_ERRORinstead of being silently ignored);data:…;base64,prefixes tolerated, PEM-where-DER and double-encoded payloads rejected with the exact remedy; page-index mistakes on the page-tree tools areVALIDATION_ERRORwith a 0-based hint; an unknown tool name is a JSON-RPC protocol error (-32602,[UNKNOWN_TOOL]). - 🔑 HTTP bearer token — opt-in
PDFNATIVE_MCP_HTTP_TOKENgates the Streamable HTTP endpoint (401+WWW-Authenticateotherwise). Without it the loopback endpoint has no authentication — seeSECURITY.md. - 🧾 Catalogue —
tools/listis ≈ 245 kB (1.5.0: ≈ 108 kB) because every block kind, layout option andencryptfragment is now advertised inline — no$ref/$defsby policy, so hosts that forwardinputSchemato function-calling APIs never meet a reference; the server instructions are ≈ 6.7 kB (from 12.9 kB). Structure is guarded byscripts/tool-shape.mjs(scripts/tool-shape.tssince v1.7.0) +tests/catalogue-parity.test.ts, andtests/catalogue-superset.test.tsproves the live catalogue is a superset of the published 1.5.0 one; at most two executable_meta.examplesper tool, the rest underexamples/. Four new recipe prompts:pades_ladder,print_ready,reproducible_output,pdfa_valid. - 🐛 Fixes — signer metadata (
signerName/reason/location/contactInfo) never reached the/Sigdictionary on pdfnative < 1.7; it is now baked at placeholder time.verify_pdfno longer reportsallValid: falseon B-LTA documents (a/DocTimeStampwas parsed as a CMS signature). - 🔌 MCP 2026-07-28 on the MCP TypeScript SDK v2 (
@modelcontextprotocol/server) with automatic fallback to the 2025-erainitializehandshake — existing hosts keep working unchanged. See MCP protocol compliance. - ⬆ Engine upgrade — pdfnative v1.7.0 (LTV, print production, charts v2, digest agility, flag / ZWJ emoji sequences, UAX #9 fixes).
New in v1.5.0:
- 📊 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 become
pdfnative://output/…resources (resources/list+resources/read), with aresource_linkin file-mode results for cross-call re-reference. - 🏷️ Tool annotations — every tool advertises
readOnlyHint/destructiveHint/idempotentHint/openWorldHint. - ⬆ Engine upgrade — pdfnative v1.6.0 (decrypt/re-encrypt,
extractText, fill/flatten, charts; colour-emoji subset 221 → 1167 glyphs).
New in v1.4.0:
- 🤝 AI governance + human-in-the-loop —
draft_governance_issuelets an agent draft a fully compliant GitHub issue locally (draft.md+ machine-readable compliance report). The agent is a draftsman, never an autonomous submitter: a human is the only gate, and the server makes zero GitHub writes (and, since v1.6.0, no outbound call other than to operator-configured TSA / OCSP / CRL endpoints). 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 a visual review layer, not a redaction — underlying bytes remain. - 🔢 Page labels in
inspect_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 the
promptscapability withgovernance_contractanddraft_issue_workflow. - ⬆ Engine upgrade — pdfnative v1.5.0.
New in v1.3.0:
-
🆕 Three page-tree tools —
merge_pdfs,split_pdf,extract_pages(built on pdfnative v1.4.0's page-tree API; encrypted sources were rejected until v1.5.0 addedpassword). -
🔖 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 (raw P-256 scalars stay pure JS, and verification is pure JS); signatures stay interoperable. -
⬆ Engine upgrade — pdfnative v1.4.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;imagesince v1.6.0) 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;read_form_fieldssince v1.5.0) 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 — seedocs/API_STABILITY.md. - 🆕 AI agent guide:
docs/AI_GUIDE.md— decision tree + common pitfalls. See also the agent contract,docs/AGENT_CONTRACT.md(catalogue, decision tree, recipes, error table); contributors and coding agents start atAGENTS.md. - 🆕 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), theadd_chart/read_form_fields/fill_form/encrypt_pdf/decrypt_pdftools plus the encrypted round-trip and native MCP resources (v1.5.0), andadd_ltv/timestamp_pdf/update_metadataplus print production and charts v2 (v1.6.0).redact_pdfstays deferred — pdfnative can overlay/flatten but not remove page content, and an overlay-only "redaction" would create false security, so it is intentionally not shipped (tracked as an upstream content-removal request).
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 }(plusdiagnostics[]whenincludeDiagnostics: true, and asummaryforadd_ltv).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 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 seven read-only tools (inspect_pdf, verify_pdf, validate_pdf, extract_text, extract_attachments, read_form_fields, inspect_layout) 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 }(+ltvLevelwithltv: true);inspect_pdfkeepsdocTimestampCount/trapped/checksPassedwhen present.fields: ['a', 'b.c']— projects the structured result to named dot-paths; composes afterverbosity. Unmatched paths are omitted and reported in_meta.unmatchedFields(with_meta.availableFields).
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 in the engine — pure JavaScript, no native bindings (this server adds only the MCP SDK and zod: three runtime dependencies in total).
- ISO 32000-1 (PDF 1.7) compliant output.
- PDF/A-1b/2b/2u/3b, AES-128/256 encryption, AcroForm, digital signatures.
- 32 Unicode scripts (39
langcodes incl.latin,emoji,mathand the fourlatinaliases) with built-in BiDi reordering, Arabic positional shaping, Indic / Thai OpenType shaping and, since v1.8.0, a base textdirection(auto/ltr/rtl) for right-to-left documents. - PDF/X-4 print exchange, DeviceCMYK colour and fine typography (orphan / widow control, justification, French punctuation spacing, OpenType features).
- 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.
🌐 Supported AI Ecosystem & Clients
pdfnative-mcp is designed for MCP-native environments and works with clients that support MCP over stdio or Streamable HTTP.
Community-verified compatibility includes:
- Ontheia — a self-hosted, open-source AI agent platform (privacy-first). Reported as working out of the box in issue #41 and listed on Ontheia's compatible MCP servers page.
🔌 MCP protocol compliance
Since v1.6.0 the server is built on the MCP TypeScript SDK v2 (@modelcontextprotocol/server) and speaks MCP 2026-07-28:
Documentation truncated — see the full README on GitHub.
Reviews
No reviews yet
Be the first to review this server!
More Developer Tools MCP Servers
Rea
Freeby Morluto · Developer Tools
Reverse engineer anything from your terminal or agent with one CLI and MCP server.
Paperclip
Freeby Paperclipai · Developer Tools
Trending hip-hop artist momentum scores across four cultural dimensions.
Fetch
Freeby Modelcontextprotocol · Developer Tools
Web content fetching and conversion for efficient LLM usage
Git
Freeby Modelcontextprotocol · Developer Tools
Read, search, and manipulate Git repositories programmatically
Toleno
Freeby Toleno · Developer Tools
Toleno Network MCP Server — Manage your Toleno mining account with Claude AI using natural language.
MCP Marketplace
Freeby mcp-marketplace · Developer Tools
Search and install MCP servers from inside your AI client.
