pdfnative-mcp
A zero-dependency MCP server (pdfnative-mcp) exposing 28 tools and 7 prompts for creating, transforming, signing, and verifying PDFs in any Model Context Protocol host (Claude Desktop, Cursor, ChatGPT, etc.).
Generate documents — multi-page PDFs from 13 block kinds (heading, paragraph, list, table, image, link, TOC, barcode, SVG, form field, chart, page break, spacer) with PDF/A, PDF/X-4, headers/footers, watermarks, margins, page sizes, outlines, page labels and print production boxes.
Advanced typography & colour — orphans/widows, justification, kerning, OpenType features, unit binding, French spacing, spot colours and CMYK everywhere a colour is accepted.
International text — 32 Unicode scripts (Arabic, Hebrew, Indic, CJK, Thai, etc.), BiDi/RTL reordering, colour emoji, math symbols and operator-supplied fonts.
Native vector charts & barcodes — bar/stacked/line/area/scatter/pie/donut charts with axes, legends and data labels; QR, Code 128, EAN-13, Data Matrix and PDF417.
Forms — create AcroForms, read field trees, and fill/flatten existing forms non-destructively.
Signatures & LTV — PAdES B-B/B-T/B-LT/B-LTA CMS signing (RSA/ECDSA), signature placeholders, DSS/revocation material, RFC 3161 timestamps and full signature verification.
Document lifecycle — merge, split, extract pages, annotate (markup/link overlays), update metadata, encrypt/decrypt (AES-128/256) and embed/extract attachments (Factur-X/ZUGFeRD).
Analysis & validation — inspect structure, metadata, signatures and annotations; dry-run pagination; extract text with positioned runs; structurally validate PDF/UA and PDF/X-4.
Governance — draft human-in-the-loop GitHub issues locally (never submitted, no network writes).
Safety — strict schemas, sandboxed file output, no outbound calls by default (only operator-configured TSA/OCSP/CRL), loopback-only HTTP with optional bearer token.
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 |
| Multi-page documents from 13 block kinds — |
| Read-only pagination dry run of the same |
| QR Code, Code 128, EAN-13, Data Matrix, PDF417 — embedded in a single-page PDF. |
| 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. |
| Tabular reports with smart fields (wrap, repeatHeader, zebra, caption, minRowHeight, cellPadding). |
| Create a new interactive AcroForm PDF with text fields, text areas, checkboxes, radio buttons, dropdowns, list boxes (+ |
| Read-only enumeration of an existing AcroForm's field tree (names, types, values, widgets). |
| Fill and/or flatten an existing AcroForm (non-destructive incremental update). |
| 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 a JPEG, PNG or JPEG 2000 image ( |
| Optional step 1 of the sign workflow — create a PDF with a |
| PAdES B-B / B-T CMS signature (RSA-SHA256/384/512, ECDSA-SHA256 P-256; |
| PAdES B-LT — embed a |
| PAdES B-LTA — append an RFC 3161 |
| Verify every PAdES signature and document timestamp (integrity + signature value + optional chain trust; a |
| Validate a Tagged PDF for PDF/UA (ISO 14289-1) structural conformance, or with |
| Generate a PDF/A-3 document with embedded files (Factur-X / ZUGFeRD invoices). |
| Read-only extraction of embedded files (Factur-X / ZUGFeRD XML round-trip) with byte-for-byte payloads. |
| Unicode text extraction (resolves |
| Read-only inspection: PDF version, page count, encryption (+ precise |
| Rewrite |
| Re-secure a PDF with AES-128 / AES-256 (owner/user passwords, permissions, password rotation). |
| Emit an unencrypted copy of an RC4 / AES-128 / AES-256 document. |
| Concatenate 2–50 PDFs into one via pdfnative's page-tree API (page boxes preserved). |
| Split one PDF into one document per page range (multi-output). |
| Pull an arbitrary page subset into a single PDF. |
| Add markup annotations (highlight, note, square/circle, line, freetext) and |
| 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.
Related MCP server: pdf-agent-toolkit-mcp
🚀 Installation
# Run directly with npx (recommended for MCP clients)
npx -y pdfnative-mcp
# Or install globally
npm install -g pdfnative-mcp
pdfnative-mcpRequirements: 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:
Stateless serving —
server/discoverreplaces the session handshake; every result carriesresultTypeand the_metaserverInfoenvelope. Over HTTP, 2026-07-28 clients sendMcp-Method/Mcp-Nameheaders with eachPOST /mcp.Cache hints —
tools/listandprompts/listarepublicwith a 24 httlMs,server/discoverispublicfor 1 h, andresources/list/resources/templates/list/resources/readareprivatewithttlMs: 0(generated PDFs are per-host user data).Resource errors — an unknown resource URI is reported as JSON-RPC
-32602(Invalid params), as the 2026-07-28 specification requires.Automatic legacy fallback — a client that opens with
initialize(2025-11-25, 2025-06-18 or 2025-03-26) is served through the SDK's legacy path on both stdio and HTTP. Nothing changes for existing hosts.HTTP —
GET/DELETE /mcpanswer 405 (no SSE resumability; the server is stateless). The loopback bind and theHost/Originguard are unchanged, and theOriginport must now equal the server port (the SDK check alone is port-agnostic);PDFNATIVE_MCP_HTTP_TOKENadds an opt-in bearer-token gate (401+WWW-Authenticatewithout it). JSON-RPC batch arrays (2025-03-26) are accepted over HTTP. Keep-alive connections no longer accumulate socket listeners.stdio — as in every SDK release to date, a request sent before
initializeis dropped without a reply and JSON-RPC batch arrays are not accepted on stdio (unchanged from 1.5.0; no major host batches).Protocol errors —
tools/callwith an unknown tool name is a JSON-RPC error (-32602,[UNKNOWN_TOOL] Unknown tool: …) rather than anisErrorresult, as the specification classifies it;isError: trueis reserved for execution failures.Output schemas — every
structuredContentvalidates against the tool'soutputSchema(a 2026-07-28 MUST), includingverbosity: 'summary'andfieldsprojections: the seven read tools declare projectable schemas (all properties optional,additionalProperties: falsekept). Input schemas carry no$schemakeyword by policy (MCP ≥ 2025-11-25 defaults to JSON Schema 2020-12; some hosts forwardinputSchemato function-calling APIs that reject unknown keywords).serverInfocarrieswebsiteUrl; the resource template ispdfnative://output/{+path}.
The tools/call payload (content, structuredContent, isError) is identical between the 2026-07-28 path and the legacy path; tests/http-modern.test.ts asserts it, and tests/schema-conformance.test.ts validates structuredContent with the SDK's JSON Schema 2020-12 validator.
Client | Transport | Protocol negotiated |
Claude Desktop, Cursor, Continue, Zed, Windsurf, Cline | stdio | legacy |
ChatGPT and other Streamable HTTP hosts | HTTP | legacy stateless streamable HTTP — unchanged |
MCP 2026-07-28 clients (SDK v2 | stdio / HTTP |
|
Ontheia | stdio | legacy |
Environment variables
Variable | Purpose |
| Absolute path to the sandbox directory. Required to enable |
| (v1.8.0) Public base URL the operator serves the sandbox under (e.g. |
| (v1.8.0) Absolute directory of |
| Absolute path to enable the persistent SHA-256-keyed result cache (1 h TTL, 256 MiB LRU; key namespaced by tool API + package version + the pinned creation instant). When unset, the cache is disabled. Never caches |
| When set to a valid port (1–65535), starts an HTTP server on |
| (v1.6.0, secret) Opt-in bearer token for the HTTP transport (≥ 16 characters, no whitespace — a weaker value aborts startup). When set, every |
| (v1.6.0) Overrides the engine's 100 MiB per-stream decompression cap (zip-bomb guard): a positive integer number of bytes ≥ 1024, read once at startup — an invalid value refuses to start. Lower it on a shared host, raise it for trusted archives of large scans. A capped attachment stream fails |
| (v1.6.0) Absolute |
| (v1.6.0, secret) Optional |
| (v1.6.0) |
| (v1.6.0) Comma-separated allow-list ( |
| (v1.6.0) Per-request timeout for TSA / OCSP / CRL calls, 1000–120000 ms (default 10000). |
| (v1.7.0) ISO 8601 instant with a time zone (e.g. |
| (v1.7.0) The reproducible-builds.org convention: integer seconds since the Unix epoch, used when |
Creation-date precedence (highest first): the per-call creationDate → PDFNATIVE_MCP_CREATION_DATE → SOURCE_DATE_EPOCH → the wall clock. Dates are always written in UTC, so pinned output is byte-identical on every host and in every time zone. The pin does not cover, by design: signingTime (sign_pdf, prepare_signature_placeholder), modDate (update_metadata), the regenerated second /ID of incremental writers (annotate_pdf, fill_form), RFC 3161 timestamp tokens and online revocation data, encryption (fresh file key, salts and IVs) and ECDSA signatures (randomised by design). See docs/guides/REPRODUCIBLE.md.
🛠 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"
}The 13 block kinds: heading, paragraph, list, table, image, link, toc, barcode, svg, formField, chart, pageBreak, spacer. A composite report:
{
"title": "Quarterly report",
"blocks": [
{ "type": "toc" },
{ "type": "heading", "text": "Sales", "level": 1 },
{ "type": "table", "headers": ["Region", "Revenue"], "rows": [["EMEA", "1.2 M"], ["APAC", "0.9 M"]], "zebra": true },
{ "type": "image", "imageBase64": "<base64 JPEG>", "mimeType": "image/jpeg", "width": 300, "alt": "Revenue chart" },
{ "type": "svg", "data": "M10 10 H 90 V 90 H 10 Z", "viewBox": [0, 0, 100, 100], "fill": "#0a7e8c" },
{ "type": "barcode", "format": "qr", "data": "https://example.com/q1", "align": "center" },
{ "type": "link", "text": "Full dataset", "url": "https://example.com/data" },
{ "type": "formField", "fieldType": "text", "name": "reviewer", "label": "Reviewed by" }
],
"outline": "auto",
"pageSize": "Letter",
"headerTemplate": { "right": "{title} — page {page}/{pages}" },
"embedFonts": true
}Block rules: table, barcode, formField and chart take the same body as add_table / add_barcode / add_form / add_chart; link URLs must be http:, https: or mailto:; image blocks are capped at 12 M base64 characters each and 24 MiB decoded per call (PNG: 8-bit greyscale/RGB, non-interlaced, no alpha, no palette — otherwise VALIDATION_ERROR with a remedy); svg supports <path>, <rect>, <circle>, <ellipse>, <line>, <polyline>, <polygon>, <text>/<tspan> and silently ignores transform, <g>, <use>, <image>, gradients, opacity and CSS (no external reference is ever fetched); toc is built from the heading blocks and pairs with outline: 'auto'; formField under pdfA needs embedFonts: true so the field font is embedded too (PDFA_UNEMBEDDED_FORM_FONT otherwise; strict: true then fails); barcode has no alt. Use inspect_layout with the same inputs to preview the pagination before rendering.
Typography (v1.7.0). typography is one opt-in object (12 keys, all off by default — omitted means unchanged bytes) on the nine document tools and on inspect_layout:
{
"title": "Annual report",
"embedFonts": true,
"typography": {
"splitParagraphs": true, "orphans": 3, "widows": 3,
"keepHeadingsWithNext": { "minLines": 3 },
"opticalMargins": true, "kerning": true, "fontFeatures": ["onum", "smcp"],
"unitBinding": true, "bindShortWords": true, "punctuationSpacing": "fr"
},
"blocks": [
{ "type": "heading", "text": "Outlook", "level": 2, "keepWithNext": true },
{ "type": "paragraph", "text": "A long justified paragraph…", "align": "justify" },
{ "type": "paragraph", "text": "Figures by region:", "keepWithNext": true, "splittable": false }
]
}Keys:
splitParagraphs,orphans/widows(1–10, default 2, needsplitParagraphs),keepHeadingsWithNext(trueor{ minLines }),unitBinding(trueor{ units }),bindShortWords(trueor{ maxLength, words }),punctuationSpacing('fr','fr-CA'or an array of{ char, side, space }rules),opticalMargins,metrics('approximate'default /'exact'),fontFeatures(tnum,pnum,lnum,onum,zero,ordn,sups,subs,smcp,c2sc,case),kerning,hyphenationLanguage.Block inputs: a
paragraphtakesalign(leftdefault /right/center/justify),keepWithNextandsplittable(overridestypography.splitParagraphsfor that block); aheadingtakeskeepWithNext(overridestypography.keepHeadingsWithNextfor that block).Limits:
kerning,fontFeaturesand the'fr'narrow no-break space need an embedded font (embedFonts: true; on base-14 Helvetica'fr'degrades to'fr-CA');metrics: 'exact'acts on base-14 text only;tnum/lnumchange nothing on the bundled Noto Sans (diagnosticTYPOGRAPHY_FEATURE_INEFFECTIVE); no hyphenation dictionary is installed, sohyphenationLanguagehas no effect on this server — soft hyphens (U+00AD) in the text are honoured. Seedocs/guides/TYPOGRAPHY.mdand thetypographyprompt.
CMYK colours (v1.7.0). Every colour input keeps the form it has always accepted (hex on charts, templates, link and svg blocks; a 0–1 RGB triple on watermarks and annotate_pdf; a free string on outline entries and table cell borders) and gains DeviceCMYK beside it: an operand string 'c m y k' with components 0–1 ("1 0.6 0 0.1") and a percent tuple [c, m, y, k] with components 0–100 ([100, 60, 0, 10]). Under a PDF/A claim against the default sRGB intent a CMYK colour reports PDFA_DEVICE_CMYK_CONTENT — keep colours RGB there, or supply a CMYK outputIntent.
PDF/X-4 (v1.7.0). pdfx: 'pdfx4' on generate_basic_pdf, add_table, add_chart, add_barcode, embed_image and add_international_text writes a PDF/X-4 (ISO 15930-7) file: %PDF-1.6 header, the PDF/X-4 XMP identification, a /GTS_PDFX output intent, a TrimBox on every page and /Trapped.
{
"title": "Spring catalogue",
"pdfx": "pdfx4",
"embedFonts": true,
"outputIntent": { "iccProfileBase64": "<the printer's CMYK ICC profile, base64>", "outputConditionIdentifier": "FOGRA39" },
"metadata": { "trapped": "False" },
"print": { "bleed": 14.17, "marks": { "colourBars": true } },
"blocks": [{ "type": "paragraph", "text": "Four-colour job exchanged as PDF/X-4." }]
}It requires
outputIntentwith the ICC profile of the printing condition (device classprtr, CMYK or Gray — no press profile is bundled; ask your printer); it needsembedFonts: truefor a conformant file (PDFX_NO_FONT_ENTRIESotherwise;strict: truerefuses); it combines withpdfA: 'pdfa2b' | 'pdfa2u'since v1.8.0 (one file, both claims;pdfa1b/pdfa3brefused) and is exclusive withencrypt;metadata.trappedmust be'True'or'False'; a page carries a TrimBox or an ArtBox, not both. Incoherent requests are refused withVALIDATION_ERRORbefore any work is done. Links and form fields are reported (PDFX_ANNOTATIONS); withstrict: trueaPDFX_*diagnostic fails the call withPDF_X_COMPLIANCE_VIOLATION.outputIntentaccepts RGB, CMYK and Gray profiles (≤ 8 MiB, underpdfAorpdfx). The profile must be a real ICC file (acspsignature, consistent size field) — a hand-made stub is rejected.print.marksacceptstrueor an object;marks.colourBars(trueor{ tints, size },size4–72 pt, default 12) adds the C M Y K solids and their 50 % tints in the bleed. Off by default; it needs a bleed of about 5 mm (14.17 pt) and is skipped when the strip would not fit.Check the result with
validate_pdf { standard: 'pdf-x-4' }— a structural check, not a certified preflight. Seedocs/guides/PRINT.mdand theprint_readyprompt.
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: the 32 Unicode scripts — ar, he, th, ja, zh, ko, el, hi, bn, ta, ru, ka, hy, tr, pl, vi, te, si, bo, km, my, am, and since v1.7.0 lo (Lao), nod (Tai Tham), khb (New Tai Lue), tdd (Tai Le), cjm (Cham), and since v1.8.0 gu (Gujarati), pa (Gurmukhi), kn (Kannada), ml (Malayalam), or (Odia) — plus the utility faces latin, emoji and math. Since v1.7.0 ha (Hausa), yo (Yoruba), ig (Igbo) and sw (Swahili) are aliases of latin: the bundled Noto Sans anchors their tone marks, no extra font is embedded. Fonts are always embedded (no embedFonts input); pin creationDate for byte-identical output. The tool also accepts typography and pdfx (see generate_basic_pdf).
Tai Tham under PDF/A:
lang: 'nod'validates underpdfa2band, since 1.8.0, underpdfa2utoo — pdfnative 1.9.0 names every shaped glyph inToUnicode(the 1.7.0 "usepdfa2b" rule is lifted).
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": "<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"
}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 | openssl base64 -A # cert
openssl rsa -in key.pem -outform DER -traditional | openssl base64 -A # RSA PKCS#1
openssl pkey -in key.pem -outform DER | openssl base64 -A # ECDSAUse
prepare_signature_placeholderonly when you need to customize the placeholder (e.g. largerplaceholderBytesfor >4096-bit RSA keys,subFilter: 'ETSI.CAdES.detached',reserveTimestamp: true). Otherwise callsign_pdfdirectly.
PAdES ladder (v1.6.0). sign_pdf with profile: "pades" produces a B-B signature; add timestamp: true for B-T (needs PDFNATIVE_MCP_TSA_URL), then add_ltv (B-LT) and timestamp_pdf (B-LTA):
// 1. sign_pdf { ..., "profile": "pades", "timestamp": true, "certChainDerBase64": ["<intermediate DER>"] }
// 2. add_ltv { "pdfBase64": "<signed>", "mode": "online" } // or "offline" + certificatesDerBase64 / ocspResponsesDerBase64 / crlsDerBase64
// 3. timestamp_pdf { "pdfBase64": "<ltv>" } // re-run before the TSA certificate expires
// 4. verify_pdf { "pdfBase64": "<final>", "ltv": true } // -> ltvLevel: "B-LTA"Signer metadata (signerName, reason, location, contactInfo) is baked into the placeholder; fieldName selects one of several unsigned placeholders (PLACEHOLDER_AMBIGUOUS otherwise) and allowMultiple: true adds a further signature. See docs/guides/LTV.md.
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 },
{ "fieldType": "listbox", "name": "skills", "label": "Skills", "options": ["TypeScript", "PDF", "MCP"] },
{ "fieldType": "textarea", "name": "notes", "label": "Notes", "placeholder": "Anything we should know?" }
],
"outputMode": "base64"
}Field types: text, textarea (multi-line, /Ff 4096), checkbox, radio, dropdown, listbox; placeholder shows hint text while a field is empty. Add encrypt to produce a password-protected form that keeps its AcroForm. Under a PDF/A claim pass embedFonts: true so the field font is embedded too (since v1.7.0 such a form validates under veraPDF); without it the call reports PDFA_UNEMBEDDED_FORM_FONT (strict: true then fails).
embed_image
{
"title": "Product Photo",
"imageBase64": "<base64-encoded JPEG bytes>",
"mimeType": "image/jpeg",
"caption": "Front view of Model X",
"width": 400,
"align": "center",
"alt": "Front view of the Model X chassis",
"outputMode": "base64"
}Note: the engine's PNG decoder accepts 8-bit, non-interlaced greyscale / RGB images only. Alpha-channel (colour type 4 / 6), palette (type 3), 16-bit and interlaced PNGs are rejected at the boundary with
VALIDATION_ERRORand a remedy (flatten or re-export) — the same rule applies toimageblocks and image watermarks.embed_image.imageBase64keeps its 1.5.0 contract with no length bound; the 12 M-character cap applies to inlineimageblocks and watermark images only.
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": "<base64 PDF>",
"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', 'dss', 'docTimestamp', 'trapped', 'annotations' (the last four since v1.6.0) and 'pdfx' (since v1.7.0: the XMP claims PDF/X — the claim, not its validity; that is validate_pdf standard: 'pdf-x-4'). pdfX appears in the result only when the XMP claims PDF/X (kept by verbosity: 'summary'). checksPassed is the AND of all requested checks. signatures: true adds a per-field inventory (subFilter, isDocTimestamp, isPlaceholder, byteRange, vriKey); annotations: true adds annotations[] (every /Annots entry: 0-based page, subtype, rect, and when present contents truncated to 200 chars, title, color, quadPoints, link url) plus annotationCount; dss, docTimestampCount and trapped appear only when present; with pages: true each perPage entry also carries trimBox / bleedBox / artBox / cropBox / userUnit when set.
inspect_layout
Read-only pagination dry run — the same blocks as generate_basic_pdf plus every input that moves a block (title, footerText, pdfA, normalize, embedFonts, pageSize, margins, headerTemplate, footerTemplate, and since v1.7.0 typography). No PDF is produced; pass exactly what you will give generate_basic_pdf and totalPages matches.
{ "title": "Memo", "blocks": [{ "type": "paragraph", "text": "Short note." }], "pageSize": "Letter", "verbosity": "summary", "fields": ["totalPages"] }The full result carries pageWidth, pageHeight, margins, totalPages and pages[].blocks[] (type, page, x, top, width, height in points, rounded to two decimals). Since v1.7.0 the dry run and the build share one pagination planner, so every block kind — toc included — is measured exactly as it is laid out (in 1.6.0 a toc block was measured as 0 pt).
validate_pdf
Read-only structural conformance check. standard picks the rule set: 'pdf-ua-1' (default — PDF/UA, ISO 14289-1, for a Tagged PDF) or, since v1.7.0, 'pdf-x-4' (PDF/X-4, ISO 15930-7). Generate an accessible document with any tool using pdfA (e.g. pdfA: 'pdfa2u'), then validate the result:
{ "pdfBase64": "<tagged-pdf-base64>" }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.
PDF/X-4 (v1.7.0). { "pdfBase64": "<pdf>", "standard": "pdf-x-4" } checks the structural prerequisites of ISO 15930-7: PDF 1.6 header, no encryption, trailer /ID, the PDF/X-4 XMP identification, a /GTS_PDFX output intent with an embedded prtr ICC profile, a TrimBox or ArtBox per page nested in the BleedBox and MediaBox, every font embedded, no annotation on the printed area, no JavaScript, no embedded file, device colour consistent with the output intent. The result has the same shape plus caveats[], which states what a valid: true verdict does not establish: this is not a certified preflight, and veraPDF does not cover PDF/X — confirm a press job with callas pdfToolbox or Acrobat Preflight. The default (pdf-ua-1) response is unchanged and carries no caveats.
annotate_pdf
Overlay markup annotations on an existing PDF via incremental update. This is a visual review layer, not a redaction — the underlying content is untouched.
{
"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" }
]
}Types: text, highlight, underline, strikeout, squiggly, square, circle, line, freetext. Page indices are 0-based. color / interiorColor take a hex or operand string (including a CMYK operand string), a 0–1 RGB triple ([1, 1, 0]) or, since v1.7.0, a CMYK percent tuple ([0, 0, 100, 0]); v1.7.0 also fixes the 0–1 triple, which used to render almost black. Encrypted sources are rejected (ENCRYPTED_SOURCE) — run decrypt_pdf first (drops signatures / AcroForm), annotate, then encrypt_pdf again.
draft_governance_issue
Draft a governance-compliant GitHub issue locally for a human to review and submit. The server never contacts GitHub (its only possible egress is the operator-configured TSA / OCSP / CRL endpoints — see Network & egress); it returns the draft Markdown plus a machine-readable compliance report.
{
"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": "add_table with caption + repeatHeader over 2 pages (examples/bordered-table.json, then inspect_pdf)", "result": "Page 2 has no caption row." },
"expectedBehavior": "The caption repeats with the header on every page.",
"duplicateSearchPerformed": true
}A draft that proposes a runtime dependency, omits a reproduction, or sets duplicateSearchPerformed: false is rejected with GOVERNANCE_VIOLATION. See docs/guides/AI_GOVERNANCE.md for the full human-in-the-loop contract.
verify_pdf, add_attachment, extract_text
See the dedicated sections in docs/AI_GUIDE.md and the reference in docs/KNOWLEDGE_BASE.md. Ready-to-run examples live under examples/.
🔐 Security model
pdfnative-mcp runs inside the host process and exposes a stdio MCP server (or a loopback-only HTTP endpoint). It does not perform any I/O outside the configured sandbox.
File writes are gated by
PDFNATIVE_MCP_OUTPUT_DIR. When unset, thefileoutput mode is rejected with aSecurityError.Path resolution rejects absolute paths, traversal sequences (
..), NUL bytes, and any extension other than.pdf.Output size is capped at 50 MB per call.
Inputs are validated against strict JSON Schemas + Zod runtime checks at the boundary of every tool — unknown or misspelt keys (top-level or nested) are rejected with
VALIDATION_ERROR, and base64 / DER payloads are sanity-checked (data:prefix tolerated, PEM or double-encoded input rejected with the remedy) before any parser runs.HTTP transport (
PDFNATIVE_MCP_PORT) binds loopback only; it has no authentication unlessPDFNATIVE_MCP_HTTP_TOKENis set (then401without a valid bearer token).Operator fonts (
PDFNATIVE_MCP_FONT_DIR) are parsed by the engine before they are registered, bounded in number and size, and named by slug only — a tool argument never carries a path. The output base URL (PDFNATIVE_MCP_OUTPUT_BASE_URL) is pure string formatting: the server never requests it. Password calls are never cached.Fuzzed boundary — five ClusterFuzzLite targets (
fuzz/:tools/callarguments, base64, images, the output sandbox, the HTTP guards) run on every pull request and weekly; the same targets run againstsrc/at every gate (tests/fuzzing/).
Network & egress
The server makes no outbound network call by default. The only egress it can ever perform goes to the RFC 3161 / OCSP / CRL endpoints the operator configured in the environment for PAdES long-term validation (PDFNATIVE_MCP_TSA_URL, PDFNATIVE_MCP_REVOCATION, PDFNATIVE_MCP_NETWORK_ALLOWED_HOSTS) — never to a URL supplied by a tool argument, never to GitHub, never for telemetry. Without that configuration sign_pdf timestamp: true, timestamp_pdf and add_ltv mode: 'online' fail fast with TSA_NOT_CONFIGURED / REVOCATION_NOT_CONFIGURED before touching the document; add_ltv mode: 'offline' embeds caller-supplied material with zero network access.
OCSP / CRL URLs come from the AIA / CRL-distribution-point extensions of untrusted certificates inside the PDF, so every fetch passes an SSRF guard:
host must match the operator allow-list (
host,host:portor*.suffix; bare wildcards are rejected). Entries are hostnames, not URLs: ahost:portentry only matches URLs carrying an explicit port (the URL parser drops default:80/:443— list the bare host for those); wildcard entries cannot carry a port; IDN hostnames must be listed in punycode (xn--…); IPv6 literals in brackets ([2001:db8::1]);http:/https:only, no embedded credentials, redirects are never followed;loopback, link-local, private, unique-local, CGNAT, unspecified and multicast address literals (including decimal / octal / hex spellings and IPv4-mapped IPv6) are rejected unless that literal is allow-listed verbatim. The guard checks literals only — a listed hostname that resolves to an internal address (DNS rebinding) is not detected, since there is no resolver without adding a dependency; allow-list only hosts you control;
per-request timeout (
PDFNATIVE_MCP_NETWORK_TIMEOUT_MS) and response caps (256 KiB TSA, 1 MiB OCSP, 16 MiB CRL) enforced while streaming, so an oversized response is cut off rather than buffered;OCSP responses and CRLs returned by responders are parse-validated before
add_ltvembeds them;the TSA URL is operator-trusted (scheme + credential checks only); the
PDFNATIVE_MCP_TSA_AUTHsecret is never logged or echoed in error messages.
Providers are built per call and passed through pdfnative's per-call options — the process-wide provider setters are never used, so concurrent requests share nothing. The server/discover instructions report the current egress policy (endpoint kinds only, never secrets).
See SECURITY.md for the responsible disclosure process and docs/guides/LTV.md for the operator setup.
🧪 Local development
git clone https://github.com/Nizoka/pdfnative-mcp.git
cd pdfnative-mcp
npm ci # .npmrc sets ignore-scripts=true: nothing builds on install
npm run gate:fast # before every commit: typecheck:all, lint, test, server-json, verify:docs
npm run gate # the CI profile: build, dist checks, stdio smoke test, tool shape, pack manifest, samples, coverage, docs, corpus, validate:pdfx
npx tsx scripts/gate.ts --publish --require-all # release branches: everything incl. validate:pdfa (veraPDF); a skipped step failsnpm run gate (scripts/gate.ts) is the single definition of green — 1804 tests, the coverage thresholds of vitest.config.ts, and the built server driven over stdio, where stdout must carry JSON-RPC frames only. It prints one line per step and writes the logs to test-output/.gate/<step>.log; --only <step> runs one step and --json gives machine output (call the script directly to pass flags: npx tsx scripts/gate.ts --fast). The individual steps are ordinary npm scripts:
npm run build && npm run test:generate # drive the built server under TZ=UTC, operator variables scrubbed -> test-output/samples/
npm run verify:samples # hold the 112 samples to tests/_fixtures/samples.sha256.json (109 by bytes, 3 by a semantic projection)
npm run corpus:pdfa # write the 45-file conformance corpus (36 claim PDF/A, 6 claim PDF/X-4, 1 claims both — the PDF/X-4 + PDF/A-2 dual claim —, 2 page-tree outputs claim nothing)
npm run validate:pdfx # in-process structural PDF/X-4 check of the corpus; never skips
npm run validate:pdfa # veraPDF over the PDF/A files (VERAPDF_HOME, JAVACMD); exit 0 ok / 1 conformance / 2 infrastructure
npm run verify:docs # every count, version, tool, error code, operator variable, link and anchor in the docs vs docs/assets/ecosystem.json and src/
npx tsx scripts/tool-shape.ts --write # only after a deliberate tools/list schema change (npm run verify:tool-shape checks the fixture)
npx vitest run tests/fuzzing/targets.test.ts # the five ClusterFuzzLite targets against src/ on their seeded corpus (also part of npm test)An intended output change is rebaselined with npx tsx scripts/verify-samples.ts --update and declared in the release note — never to silence a surprise. With veraPDF 1.30.2 the corpus gives 27 PASS and 6 expected failures (negative canaries that must stay rejected). Every script, its flags and its exit codes are listed in scripts/README.md.
Smoke-test the server over stdio:
node dist/cli.js
# In another terminal, send a JSON-RPC initialize request via stdin (e.g. with mcp-inspector).Contributors: start at
AGENTS.md(the repository rules shared by every coding agent and contributor) and see docs/guides/LOCAL_TESTING.md for the full local-verification workflow — the quality gate, examples-as-tests, validating that generated PDFs are structurally correct (assertValidPdf,inspect_pdf,validate_pdf,verify_pdf), opening output in a viewer, external PDF/A checking with veraPDF, and the MCP Inspector.
📣 Release process
pdfnative-mcp follows the same release formalism as pdfnative:
One release note file per tag in
release-notes/vX.Y.Z.mdCHANGELOG.mdmirrors each release bullet listGitHub Release body is copied from
release-notes/vX.Y.Z.mdnpx tsx scripts/release-prepare.ts --version X.Y.Zapplies the mechanical part of a version bump (it never commits, tags or publishes); the version moves in lock-step acrosspackage.json,src/version.ts,server.jsonanddocs/assets/ecosystem.jsonA release branch must pass
npx tsx scripts/gate.ts --publish --require-all— every step, veraPDF included, with no skipnpm publication is handled by GitHub Actions Trusted Publishing (OIDC), without
NPM_TOKEN, from a protected environment, through the five-job pipeline of pdfnative 1.9 (publish.yml: guard refuses anything but av*tag equal to the package version before any approval → build runs the publish gate and packs once, digests recorded → publish installs nothing, fetches the npm client by SHA-512, re-verifies the tarball and publishes with--provenance→ attest fetches the bytes the registry serves, checks them against the build digests, runsnpm audit signatures, attests them with three SBOMs (CycloneDX + SPDX runtime, CycloneDX toolchain) and attaches everything plus the Sigstore bundle to the GitHub release → registry publishesserver.jsonto the MCP registry with the workflow's OIDC identity through a SHA-256- and cosign-verifiedmcp-publisher)Every Linux and Windows job starts with
step-security/harden-runner— egress blocked with an allow-list on the Linux jobs, audited with a dated reason elsewhere (Windows supports audit only; the action does not support macOS, the one documented exemption) —, checks out withpersist-credentials: false, installs withnpm ci --ignore-scripts, pins every action to a commit SHA, scopes every write permission to its job and passes event values throughenv:;workflow-lint(zizmor + checksummed actionlint) is a required check beside the gate on three operating systems and the sample baseline; CodeQL (actions+javascript-typescript, security-extended), Scorecard, Dependency Review, a weeklynpm auditand ClusterFuzzLite complete the pictureHuman-in-the-loop: coding agents prepare and verify; the maintainer pushes, opens the pull request, tags and publishes (
.github/AGENT_RULES.md)
See release-notes/TEMPLATE.md for the canonical structure and publication checklist, and CONTRIBUTING.md for the release procedure.
📚 Project structure
src/
├── cli.ts # entrypoint: stdio (default) or Streamable HTTP (PDFNATIVE_MCP_PORT)
├── http.ts # Node http <-> Web Request/Response bridge + Host/Origin loopback guard
├── auth.ts # opt-in HTTP bearer token (PDFNATIVE_MCP_HTTP_TOKEN)
├── base64.ts # base64 / DER boundary decoding with agent-facing diagnostics
├── index.ts # public library exports
├── server.ts # Server factory, tool registry, cache hints, SERVER_INSTRUCTIONS
├── network.ts # operator-configured TSA / OCSP / CRL egress + SSRF guard
├── print.ts # print-production schema (boxes, bleed, marks + colour bars, userUnit, RGB / CMYK / Gray outputIntent, metadata, creationDate)
├── pdfx.ts # pdfx: 'pdfx4' conformance target + the static conflicts refused before the build
├── color.ts # shared colour fragment: CMYK operand string / percent tuple beside each historical form, toEngineColor()
├── typography.ts # the typography fragment (12 opt-in keys) + TypographyOptions mapper
├── reproducible.ts # operator-pinned creation instant (PDFNATIVE_MCP_CREATION_DATE, SOURCE_DATE_EPOCH)
├── diagnostics.ts # engine diagnostics sink (PDFA_* / PDFX_* / TYPOGRAPHY_*), strict escalation by code, includeDiagnostics, embedFonts
├── chart.ts # charts v2 schema + ChartBlock mapper
├── blocks.ts # the 7 extended document blocks (table, image, link, toc, barcode, svg, formField)
├── layout.ts # pageSize / margins / header & footer templates / compress / debug / encrypt / typography (PdfLayoutOptions)
├── table.ts, barcode.ts, form.ts, image.ts # bodies shared by a dedicated tool and its inline block
├── watermark.ts # text and/or image watermark + position, PDF/A-1b transparency guard
├── encryption.ts # password + encrypt schema (Standard Security Handler), decrypt error mapping
├── inflate-cap.ts # PDFNATIVE_MCP_MAX_INFLATE_BYTES (engine decompression cap) + PDF_PARSE_FAILED mapping
├── 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 (+ print-dialog defaults)
├── pagetree.ts # page-tree error mapping (merge/split/extract)
├── crypto-provider.ts # node:crypto signing provider for DER keys (SHA-256/384/512); verification stays pure JS
├── projection.ts # verbosity / fields projection for the seven read tools
├── errors.ts # ToolError, SecurityError, GovernanceError
└── tools/
├── generate-basic-pdf.ts
├── inspect-layout.ts
├── add-barcode.ts
├── sign-pdf.ts
├── add-ltv.ts
├── timestamp-pdf.ts
├── update-metadata.ts
├── add-international-text.ts
├── add-table.ts
├── add-form.ts
├── read-form-fields.ts
├── fill-form.ts
├── add-chart.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
├── annotate-pdf.ts
├── encrypt-pdf.ts
├── decrypt-pdf.ts
├── draft-governance-issue.ts
└── prepare-signature-placeholder.ts
scripts/ # TypeScript run by tsx — the full table is in scripts/README.md
├── gate.ts # THE quality gate (npm run gate / gate:fast; --publish --require-all on release branches)
├── generate-samples.ts # npm run test:generate — the built server under TZ=UTC -> test-output/samples/
├── verify-samples.ts # npm run verify:samples — the byte baseline (tests/_fixtures/samples.sha256.json)
├── generate-pdfa-corpus.ts # npm run corpus:pdfa — the 41-file PDF/A + PDF/X-4 conformance corpus
├── validate-pdfa.ts # npm run validate:pdfa — veraPDF (PASS/FAIL/XFAIL/XPASS; exit 0 / 1 / 2)
├── validate-pdfx.ts # npm run validate:pdfx — in-process structural PDF/X-4 check, never skips
├── tool-shape.ts # structural tools/list fingerprint (--write refreshes tests/_fixtures/tool-shape.json)
├── verify-docs.ts # npm run verify:docs — the docs held to docs/assets/ecosystem.json and the source tree
├── release-prepare.ts # mechanical version bump (never commits, tags or publishes)
├── build-claude-rules.ts # npm run agents:rules — .github/instructions/ -> .claude/rules/
└── verify-issue.mjs # governance draft checker (npm run verify:issue)
docs/
├── AGENT_CONTRACT.md # the consumer contract for agents that USE the server (catalogue, decision tree, recipes, error codes)
├── AI_GUIDE.md, KNOWLEDGE_BASE.md, API_STABILITY.md
├── guides/ # PDFA, PRINT, TYPOGRAPHY, REPRODUCIBLE, CHARTS, FORMS, ENCRYPTION, LTV, AI_GOVERNANCE, LOCAL_TESTING
└── assets/ecosystem.json # the single source of every count and version quoted in the docs
examples/ # 43 executable tools/call sequences (npm run examples:check)
AGENTS.md, CLAUDE.md # repository rules for coding agents; .github/instructions/ holds the per-area rules
.claude/ # shared agent settings, the fail-closed guard hook, generated rules, the release-audit skill
.github/workflows/ # ci (Node 22 / 24 on Linux, plus Windows and macOS, all running the gate, all required), publish, sample-regression, verapdf (blocking),
# docs, codeql, scorecard, dependency-review, audit
.github/rulesets/ # branch and tag rulesets to import
tests/ # vitest suites (one per tool / module), _fixtures/ (tool shape, sample baseline, engine-surface matrix,
# the frozen 1.5.0 catalogue), tools/ (repository tooling)🗺 Roadmap
v1.8.0 is shipped (spot colours, right-to-left documents, 32 Unicode scripts, JPEG 2000, the PDF/X-4 + PDF/A-2 dual claim, link annotations, operator fonts, the output base URL, the pdfnative 1.9 release pipeline and fuzzing), on top of v1.7.0 (fine typography, CMYK colours, PDF/X-4, reproducible output on every host) and v1.6.0 (full engine coverage — 13 block kinds, layout options, inspect_layout — PAdES LTV ladder, print production, charts v2, update_metadata, MCP 2026-07-28). The full plan — released milestones, in-progress work, and long-term direction — lives in ROADMAP.md.
Still deferred:
redact_pdf— pdfnative has no content-removal API; an overlay-only "redaction" would create false security.HTTP page streaming — MCP 2026-07-28 still has no partial
structuredContent, so large results stay single-shot.A Thai above vowel + tone mark pair extracts in geometric order on untagged output (every other right-to-left or reordered run round-trips through
/ActualTextsince pdfnative 1.9; tagged output always does).Non-Latin-1 form values: the engine writes only the low byte of each UTF-16 code unit of a
fill_formvalue undernonWinAnsi: 'needAppearances', soΩor漢do not round-trip throughread_form_fields— pinned upstream.Fuzz corpora survive only as long as the GitHub Actions cache; a dedicated storage repository is the next step. The OpenSSF Best Practices badge needs the maintainer's registration (docs/OPENSSF_BEST_PRACTICES.md is the prepared self-assessment).
Have a feature idea? Open an issue or PR.
🧭 Client compatibility
Every tool schema is JSON Schema 2020-12 without $ref / $defs, so hosts that forward inputSchema to a function-calling API get self-contained schemas. Since v1.8.0 every array bound is 1000 or below, or exactly 5000 (the blocks, rows and pages arrays): llama.cpp's llama-server compiles the tool schemas of a request into one GBNF grammar and refused the former 2000-item bound of prepare_signature_placeholder (#65); tests/client-compat.test.ts holds the rule. The 28 schemas weigh about 83 k tokens with a Qwen tokenizer — a client that forwards every tool on every request can disable the ones it does not need (sign_pdf injects its own placeholder, so prepare_signature_placeholder is optional; inspect_layout is a dry run of generate_basic_pdf).
🌱 Ecosystem
pdfnative — the zero-dependency engine every feature here comes from.
pdfnative-cli — the terminal wrapper of the same engine, for pipelines and shell agents.
pdfnative-react — React renderer (JSX → pdfnative blocks).
zipnative and pkinative — the sibling zero-dependency engines (archives, PKI); the native family guide explains how the four fit together.
⭐ Star the project
If pdfnative-mcp is useful to you, please ⭐ this repository — and consider also starring the underlying engine Nizoka/pdfnative. Stars help others discover the project and motivate continued development.
🤝 Contributing
Contributions are very welcome. Please read CONTRIBUTING.md, check the open issues, and follow the code of conduct.
📄 License
MIT © 2026 Nizoka. Third-party material: THIRD-PARTY-NOTICES.md.
pdfnative-mcp is built on top of pdfnative and the Model Context Protocol TypeScript SDK.
Available Tools
28 toolsadd_attachmentAdd embedded file attachment (PDF/A-3, Factur-X)AIdempotent
PDF/A-3b document with embedded files — the tool for Factur-X / ZUGFeRD e-invoices (one XML attachment, relationship 'Source', mimeType application/xml) or any PDF carrying machine-readable side-files (≤ 8 MiB each). Body via blocks (same schema as generate_basic_pdf). Pair with embedFonts:true for a valid PDF/A-3 claim (strict:true fails otherwise). Read them back with extract_attachments. Print, metadata and creationDate options as on every document tool.
| Name | Required | Description | Default |
|---|---|---|---|
| debug | No | Draw margin / block / cell guide rectangles (unmarked content — not for PDF/UA output). Geometry unchanged. Default false. | |
| No | Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b), `spotColours` ink declarations. See docs/guides/PRINT.md. | ||
| title | Yes | Document title (also written to the /Info dictionary). | |
| blocks | No | Optional human-readable document body (same block schema as generate_basic_pdf). When omitted, a minimal cover paragraph is emitted so the PDF is not empty. | |
| strict | No | Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other (TYPOGRAPHY_FEATURE_INEFFECTIVE, TEXT_GLYPH_NOT_COVERED — a character no font covers, drawn as a box or '?') → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true. | |
| margins | No | Margins in points, all four required (0–200). Default 45 / 36 / 35 / 36. | |
| compress | No | FlateDecode the streams (smaller file, different bytes; PDF/A unaffected, XMP stays plain). Default false. | |
| metadata | No | /Info (+ XMP under PDF/A): author, subject, keywords, /Trapped. | |
| pageSize | No | Portrait page preset (points): A4 595.28×841.89 (default), Letter 612×792, Legal 612×1008, A3 841.89×1190.55, Tabloid 792×1224. print.* boxes must fit it. | |
| direction | No | Base text direction (UAX #9): 'auto' reads each paragraph's first strong character and right-aligns RTL ones; 'ltr' / 'rtl' force it. A paragraph's own direction overrides it. Omitted = LTR (1.7.0 bytes). | |
| actualText | No | Untagged output: wrap reordered shaped runs and RTL runs in /ActualText so extract_text returns reading order. Default true; false = bare 1.7.0 glyph runs. No effect on tagged (pdfA) output. | |
| embedFonts | No | Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A or PDF/X claim (every font embedded) and for strict=true; adds ~0.3 MiB. | |
| footerText | No | Optional footer text rendered on every page. | |
| outputMode | No | 'base64' (default) returns the PDF inline; 'file' writes it inside the PDFNATIVE_MCP_OUTPUT_DIR sandbox (SECURITY_VIOLATION when the sandbox is not configured). | base64 |
| outputPath | No | Required when outputMode='file'. Relative path inside the sandbox; must end with .pdf (no absolute paths, no '..'). | |
| typography | No | Fine typography, all opt-in (omitted = unchanged bytes). kerning and fontFeatures need embedFonts:true ('fr' works on base-14 too). No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt. | |
| attachments | Yes | One or more files to embed. Auto-enables PDF/A-3 (ISO 19005-3). Factur-X invoices use a single attachment with relationship=Source and mimeType=application/xml. | |
| creationDate | No | ISO-8601 instant for /CreationDate (+ XMP, the trailer /ID and the {date} placeholder), written in UTC. Pin it for byte-identical output across calls and hosts; omitted = wall clock, so every call differs. | |
| outputIntent | No | Custom OutputIntent (under pdfA or pdfx): an RGB, CMYK or Gray ICC profile + condition strings, replacing the built-in sRGB intent. The profile must be a real ICC file ('acsp' signature, consistent size — PRINT_ERROR otherwise); pdfx needs device class 'prtr'. Under a CMYK / Gray intent RGB content is mapped through a calibrated default space. | |
| footerTemplate | No | Running footer on every page. Replaces the default footer: footerText is then ignored and page numbers appear only via {page}/{pages}. | |
| headerTemplate | No | Running header on every page (left / center / right zones); reserves 15 pt. | |
| includeDiagnostics | No | Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*, TEXT_GLYPH_NOT_COVERED) as `diagnostics[]` (possibly empty). |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded. |
| mode | Yes | |
| summary | No | Tool-specific summary, when produced. |
| filePath | No | Sandboxed absolute path (file mode). |
| sizeBytes | Yes | |
| diagnostics | No | Engine diagnostics (when includeDiagnostics=true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnlyHint false, idempotent true, destructive false), so this is a non-destructive idempotent create. The description adds real behavioral facts beyond them: the ≤8 MiB per-attachment limit, that embedFonts:true is required for a valid PDF/A-3 claim, and that strict:true will fail otherwise. It does not mention that attachments auto-enable PDF/A-3 (that lives only in the schema) or what happens on soft failures.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four tight clauses, front-loaded with the artifact and the primary use case before secondary constraints. Dense but every sentence carries information; only the trailing 'creationDate options as on every document tool' is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 22-parameter tool with an output schema, the description correctly focuses on what the schema cannot tell the agent: the compliance envelope (embedFonts/strict interlock), the attachment size cap, and reuse of the sibling's block schema. Return values are covered by the output schema, so nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so every parameter is already documented in schema, and the baseline is 3. The description adds modest cross-reference value — blocks shares generate_basic_pdf's schema and print/metadata/creationDate behave as on other document tools — but supplies no semantics for the attachment-specific fields (filename, relationship, dataBase64) that justify the tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb and artifact: a PDF/A-3b document with embedded files, and pins the flagship use case (Factur-X / ZUGFeRD with one XML attachment, relationship 'Source', mimeType application/xml). It also distinguishes itself from siblings by delegating page content to generate_basic_pdf's block schema and pointing to extract_attachments for the inverse operation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a clear when-to-use signal: e-invoices or any PDF carrying machine-readable side-files, with a per-file size cap. It routes to extract_attachments for readback and to generate_basic_pdf for the block schema, but never states the obvious exclusion (use generate_basic_pdf if you have no attachment to embed), leaving that to the required-parameter schema.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
add_barcodeAdd barcode / QR codeAIdempotent
Single-page PDF with a barcode: qr (URLs, vCards, UTF-8 ≤ 4296 chars; ecLevel 'H' for print, 'M' default), code128 (ASCII SKUs), ean13 (12–13 digits, checksum auto), datamatrix (dense industrial marks), pdf417 (ID cards, boarding passes). data is the raw payload — never pre-encode. Typical: { format:'qr', data:'https://example.com', caption:'Scan me' }. PDF/A, print, metadata and creationDate options as on every document tool.
| Name | Required | Description | Default |
|---|---|---|---|
| data | Yes | Raw payload to encode — do NOT URL-encode. For QR/URL pass e.g. "https://example.com" verbatim. EAN-13 must be 12 or 13 digits (13th is auto-computed). Code 128 accepts ASCII alphanumerics. | |
| pdfA | No | PDF/A level: pdfa1b (simple text+images), pdfa2b/pdfa2u (richer; 2u = Unicode mapping), pdfa3b (attachments / Factur-X). Pair with embedFonts=true for a valid claim. Exclusive with encryption. See docs/guides/PDFA.md. | |
| pdfx | No | PDF/X-4 print exchange (ISO 15930-7). REQUIRES outputIntent with the printer's ICC profile (device class 'prtr'; CMYK or Gray — none is bundled); needs embedFonts:true for a conformant file (PDFX_NO_FONT_ENTRIES otherwise, strict:true refuses). Combines with pdfA:'pdfa2b' | 'pdfa2u' (dual claim) but not pdfa1b / pdfa3b; exclusive with encrypt; metadata.trapped must be 'True' or 'False'; TrimBox or ArtBox, not both. Links and form fields are reported (PDFX_ANNOTATIONS). Check with validate_pdf standard:'pdf-x-4'. See the print_ready prompt. | |
| debug | No | Draw margin / block / cell guide rectangles (unmarked content — not for PDF/UA output). Geometry unchanged. Default false. | |
| No | Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b), `spotColours` ink declarations. See docs/guides/PRINT.md. | ||
| title | No | PDF document title (also rendered as page heading). | Barcode |
| width | No | Barcode width in PDF points. | |
| format | Yes | Barcode symbology to render. | |
| height | No | Barcode height in PDF points (ignored for square symbologies like QR/Data Matrix). | |
| strict | No | Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other (TYPOGRAPHY_FEATURE_INEFFECTIVE, TEXT_GLYPH_NOT_COVERED — a character no font covers, drawn as a box or '?') → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true. | |
| caption | No | Optional caption rendered above the barcode. | |
| ecLevel | No | QR ONLY. Error correction level (L=7%, M=15%, Q=25%, H=30%). Ignored for code128/ean13/datamatrix/pdf417. Use H for printed media that may get smudged or partially covered (e.g. logo overlay). | M |
| encrypt | No | Encrypt at build time (AES-128 default / AES-256) and KEEP the AcroForm — unlike encrypt_pdf, which rebuilds the page tree. Exclusive with pdfA. Randomised output, never cached. | |
| margins | No | Margins in points, all four required (0–200). Default 45 / 36 / 35 / 36. | |
| compress | No | FlateDecode the streams (smaller file, different bytes; PDF/A unaffected, XMP stays plain). Default false. | |
| metadata | No | /Info (+ XMP under PDF/A): author, subject, keywords, /Trapped. | |
| pageSize | No | Portrait page preset (points): A4 595.28×841.89 (default), Letter 612×792, Legal 612×1008, A3 841.89×1190.55, Tabloid 792×1224. print.* boxes must fit it. | |
| direction | No | Base text direction (UAX #9): 'auto' reads each paragraph's first strong character and right-aligns RTL ones; 'ltr' / 'rtl' force it. A paragraph's own direction overrides it. Omitted = LTR (1.7.0 bytes). | |
| actualText | No | Untagged output: wrap reordered shaped runs and RTL runs in /ActualText so extract_text returns reading order. Default true; false = bare 1.7.0 glyph runs. No effect on tagged (pdfA) output. | |
| embedFonts | No | Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A or PDF/X claim (every font embedded) and for strict=true; adds ~0.3 MiB. | |
| outputMode | No | 'base64' (default) returns the PDF inline; 'file' writes it inside the PDFNATIVE_MCP_OUTPUT_DIR sandbox (SECURITY_VIOLATION when the sandbox is not configured). | base64 |
| outputPath | No | Required when outputMode='file'. Relative path inside the sandbox; must end with .pdf (no absolute paths, no '..'). | |
| typography | No | Fine typography, all opt-in (omitted = unchanged bytes). kerning and fontFeatures need embedFonts:true ('fr' works on base-14 too). No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt. | |
| creationDate | No | ISO-8601 instant for /CreationDate (+ XMP, the trailer /ID and the {date} placeholder), written in UTC. Pin it for byte-identical output across calls and hosts; omitted = wall clock, so every call differs. | |
| outputIntent | No | Custom OutputIntent (under pdfA or pdfx): an RGB, CMYK or Gray ICC profile + condition strings, replacing the built-in sRGB intent. The profile must be a real ICC file ('acsp' signature, consistent size — PRINT_ERROR otherwise); pdfx needs device class 'prtr'. Under a CMYK / Gray intent RGB content is mapped through a calibrated default space. | |
| footerTemplate | No | Running footer on every page. Replaces the default footer: footerText is then ignored and page numbers appear only via {page}/{pages}. | |
| headerTemplate | No | Running header on every page (left / center / right zones); reserves 15 pt. | |
| includeDiagnostics | No | Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*, TEXT_GLYPH_NOT_COVERED) as `diagnostics[]` (possibly empty). |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded. |
| mode | Yes | |
| summary | No | Tool-specific summary, when produced. |
| filePath | No | Sandboxed absolute path (file mode). |
| sizeBytes | Yes | |
| diagnostics | No | Engine diagnostics (when includeDiagnostics=true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the safety profile (readOnly=false, destructive=false, idempotent=true), so the description does not need to repeat it. The description adds meaningful behavior: it produces a single-page PDF, can return base64 or write into the sandbox, makes encrypt exclusive with PDF/A, and notes that omitting creationDate yields different bytes each call. It does not cover auth or rate limits, but those are unlikely to matter here.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded paragraph that moves from purpose to format details to a typical call, with no wasted sentences. The final cross-reference to PDF/A, print, metadata and creationDate options is compact and useful, though slightly vague compared with the rest.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a 28-parameter schema with full description coverage, an output schema, and annotations covering safety, the description is complete enough for an agent to invoke the tool correctly for its main purpose. It does not elaborate on every standard document option, but the schema already documents those thoroughly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description goes beyond the schema by explaining which formats suit which payloads and by reiterating that data must be raw and never pre-encoded, with a concrete example. It does not explain the many secondary print/typography parameters, but the schema handles those in detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a concrete resource ('Single-page PDF with a barcode') and enumerates the supported symbologies, so an agent can immediately tell what the tool produces. It does not explicitly distinguish itself from siblings like generate_basic_pdf or add_chart, which keeps it short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives useful format-selection guidance (qr for URLs/vCards, code128 for ASCII SKUs, ean13 for 12–13 digits, etc.) and a typical invocation example. However, it never states when to choose this tool over alternatives such as add_chart or generate_basic_pdf, nor when not to use it, so the routing guidance is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
add_chartAdd native vector chartAIdempotent
Single-page PDF with a native vector chart (pure path operators, no raster): bar, barH, stackedBar, stackedBarH, line (markers), area, scatter, pie, donut. Multi-series, legends, 'nice' ticks, gridlines, negatives; per-series xValues with xAxis.type 'linear' | 'time' (ISO-8601), secondary right axis (axis2 + yAxis:'right'), axis.scale 'log', dataLabels, labelStride / labelRotation. Pie/donut take exactly one series. Colours: hex ('#3366cc'), 'C M Y K' / [c, m, y, k] under a print intent, { spot, tint } / { inks } declared in print.spotColours; series[].colors gives one colour per value on the bar family (its length must equal values.length on every chart type — CHART_ERROR otherwise). Tagged /Figure + /Alt (auto when altText is omitted). Engine cross-field rules surface as CHART_ERROR with the remedy. Inside a longer document use a 'chart' block in generate_basic_pdf. PDF/A (pdfA + embedFonts:true), print, metadata and creationDate as on every document tool.
| Name | Required | Description | Default |
|---|---|---|---|
| axis | No | Value-axis options (bar/line only). | |
| pdfA | No | PDF/A level: pdfa1b (simple text+images), pdfa2b/pdfa2u (richer; 2u = Unicode mapping), pdfa3b (attachments / Factur-X). Pair with embedFonts=true for a valid claim. Exclusive with encryption. See docs/guides/PDFA.md. | |
| pdfx | No | PDF/X-4 print exchange (ISO 15930-7). REQUIRES outputIntent with the printer's ICC profile (device class 'prtr'; CMYK or Gray — none is bundled); needs embedFonts:true for a conformant file (PDFX_NO_FONT_ENTRIES otherwise, strict:true refuses). Combines with pdfA:'pdfa2b' | 'pdfa2u' (dual claim) but not pdfa1b / pdfa3b; exclusive with encrypt; metadata.trapped must be 'True' or 'False'; TrimBox or ArtBox, not both. Links and form fields are reported (PDFX_ANNOTATIONS). Check with validate_pdf standard:'pdf-x-4'. See the print_ready prompt. | |
| align | No | Horizontal alignment within the content width. Default 'left'. | |
| axis2 | No | Secondary RIGHT value axis (drawn only when a series sets yAxis:'right'). | |
| debug | No | Draw margin / block / cell guide rectangles (unmarked content — not for PDF/UA output). Geometry unchanged. Default false. | |
| intro | No | Optional introductory paragraph rendered above the chart. The chart `title` (if any) is also used as the PDF metadata title. | |
| No | Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b), `spotColours` ink declarations. See docs/guides/PRINT.md. | ||
| title | No | Chart title rendered above the plot. | |
| width | No | Plot width in points (clamped to content width). Default 460. | |
| xAxis | No | Horizontal axis. 'category' (default) positions points by index; 'linear' / 'time' position them by series xValues (line/area/scatter only). Time ticks are UTC-deterministic. | |
| colors | No | Palette override (per-series for bar/line, per-slice for pie/donut). | |
| height | No | Plot-area height in points. Default 240. | |
| legend | No | Legend placement. Defaults to 'bottom' for multi-series/pie, else 'none'. | |
| series | Yes | Data series. Pie/donut charts use exactly one series (each value becomes a slice). | |
| strict | No | Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other (TYPOGRAPHY_FEATURE_INEFFECTIVE, TEXT_GLYPH_NOT_COVERED — a character no font covers, drawn as a box or '?') → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true. | |
| altText | No | Alt text for the tagged-PDF /Figure /Alt. Auto-generated when omitted. | |
| encrypt | No | Encrypt at build time (AES-128 default / AES-256) and KEEP the AcroForm — unlike encrypt_pdf, which rebuilds the page tree. Exclusive with pdfA. Randomised output, never cached. | |
| margins | No | Margins in points, all four required (0–200). Default 45 / 36 / 35 / 36. | |
| markers | No | Draw point markers on line series. Default false. | |
| compress | No | FlateDecode the streams (smaller file, different bytes; PDF/A unaffected, XMP stays plain). Default false. | |
| metadata | No | /Info (+ XMP under PDF/A): author, subject, keywords, /Trapped. | |
| pageSize | No | Portrait page preset (points): A4 595.28×841.89 (default), Letter 612×792, Legal 612×1008, A3 841.89×1190.55, Tabloid 792×1224. print.* boxes must fit it. | |
| chartType | Yes | Chart kind. 'pie'/'donut' use exactly one series; 'bar'/'barH'/'stackedBar'/'stackedBarH'/'line'/'area'/'scatter' support multiple series. 'scatter' requires xValues on every series and a positional xAxis.type ('linear' or 'time'). | |
| direction | No | Base text direction (UAX #9): 'auto' reads each paragraph's first strong character and right-aligns RTL ones; 'ltr' / 'rtl' force it. A paragraph's own direction overrides it. Omitted = LTR (1.7.0 bytes). | |
| actualText | No | Untagged output: wrap reordered shaped runs and RTL runs in /ActualText so extract_text returns reading order. Default true; false = bare 1.7.0 glyph runs. No effect on tagged (pdfA) output. | |
| categories | No | Category / slice labels (x-axis). Defaults to 1-based indices when omitted. | |
| dataLabels | No | Per-point value labels: true for defaults, or an object to format them. | |
| embedFonts | No | Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A or PDF/X claim (every font embedded) and for strict=true; adds ~0.3 MiB. | |
| outputMode | No | Either 'base64' (returns the PDF inline) or 'file' (writes into the PDFNATIVE_MCP_OUTPUT_DIR sandbox). | base64 |
| outputPath | No | Required when outputMode='file'. Relative path inside the sandbox; must end with .pdf. | |
| typography | No | Fine typography, all opt-in (omitted = unchanged bytes). kerning and fontFeatures need embedFonts:true ('fr' works on base-14 too). No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt. | |
| labelStride | No | Draw every Nth category label. Default: automatic (measured non-overlap); 1 draws every label. | |
| creationDate | No | ISO-8601 instant for /CreationDate (+ XMP, the trailer /ID and the {date} placeholder), written in UTC. Pin it for byte-identical output across calls and hosts; omitted = wall clock, so every call differs. | |
| outputIntent | No | Custom OutputIntent (under pdfA or pdfx): an RGB, CMYK or Gray ICC profile + condition strings, replacing the built-in sRGB intent. The profile must be a real ICC file ('acsp' signature, consistent size — PRINT_ERROR otherwise); pdfx needs device class 'prtr'. Under a CMYK / Gray intent RGB content is mapped through a calibrated default space. | |
| labelRotation | No | Rotate category labels counter-clockwise by this many degrees (disables the automatic stride). | |
| footerTemplate | No | Running footer on every page. Replaces the default footer: footerText is then ignored and page numbers appear only via {page}/{pages}. | |
| headerTemplate | No | Running header on every page (left / center / right zones); reserves 15 pt. | |
| includeDiagnostics | No | Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*, TEXT_GLYPH_NOT_COVERED) as `diagnostics[]` (possibly empty). |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded. |
| mode | Yes | |
| summary | No | Tool-specific summary, when produced. |
| filePath | No | Sandboxed absolute path (file mode). |
| sizeBytes | Yes | |
| diagnostics | No | Engine diagnostics (when includeDiagnostics=true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations establish readOnly=false and idempotent=true for the build itself, but the description adds non-obvious behaviour the schema doesn't state: engine cross-field rules surface as CHART_ERROR with the remedy, a colours-length mismatch is a CHART_ERROR, and tagged /Figure + /Alt is auto-generated when altText is omitted. It also notes PDF/A needs embedFonts:true. Missing is any word on runtime, output size, or the practical consequence of outputMode='file'.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is front-loaded with the core purpose, which is right, but the body degenerates into a semicolon-and-slash telegraphic wall ('Multi-series, legends, \'nice\' ticks, gridlines, negatives; per-series xValues…') that is hard to scan and mixes chart semantics with PDF/A and print boilerplate. Nearly every clause carries information, yet grouping by concern rather than by punctuation would make it substantially easier to use.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 39-parameter tool with nested objects, an output schema, and print/PDF-A surface area, the description correctly covers chart-type semantics, colour model, error contract, and accessibility tagging rather than restating obvious fields. It leans on 'as on every document tool' for shared PDF plumbing, which is reasonable shorthand in this sibling set. Print-production interactions with the chart (e.g. that CMYK/spot colours require an intent) are the main thing left implicit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description does add a few cross-parameter facts beyond the schema — series[].colors length must equal values.length on every chart type, axis2 is only drawn when a series sets yAxis:'right', spotColours must be declared before { spot, tint } can be used — but most of its parameter content duplicates enum listings and format examples already in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource+scope: 'Single-page PDF with a native vector chart (pure path operators, no raster)', then enumerates the nine supported chart types. It also distinguishes itself from the sibling that overlaps most, stating 'Inside a longer document use a \'chart\' block in generate_basic_pdf', so an agent can route between the two without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives real selection guidance inside the tool: 'Pie/donut take exactly one series', scatter requires xValues plus a positional xAxis.type, and axis.scale 'log' is not available for stacked charts. The multi-page alternative (generate_basic_pdf chart block) is named. No explicit when-not to call at all, and no sibling differentiation against add_table or embed_image, so not a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
add_formAdd interactive formAIdempotent
New PDF with an interactive AcroForm: text fields, text areas, checkboxes, radio buttons, dropdowns (data capture, surveys, fillable templates). To fill or flatten an EXISTING form use read_form_fields + fill_form. PDF/A, print, metadata and creationDate options as on every document tool.
| Name | Required | Description | Default |
|---|---|---|---|
| pdfA | No | PDF/A level: pdfa1b (simple text+images), pdfa2b/pdfa2u (richer; 2u = Unicode mapping), pdfa3b (attachments / Factur-X). Pair with embedFonts=true for a valid claim. Exclusive with encryption. See docs/guides/PDFA.md. | |
| debug | No | Draw margin / block / cell guide rectangles (unmarked content — not for PDF/UA output). Geometry unchanged. Default false. | |
| No | Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b), `spotColours` ink declarations. See docs/guides/PRINT.md. | ||
| title | Yes | Form title rendered at the top of the document. | |
| fields | Yes | Ordered list of form field definitions. | |
| strict | No | Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other (TYPOGRAPHY_FEATURE_INEFFECTIVE, TEXT_GLYPH_NOT_COVERED — a character no font covers, drawn as a box or '?') → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true. | |
| encrypt | No | Encrypt at build time (AES-128 default / AES-256) and KEEP the AcroForm — unlike encrypt_pdf, which rebuilds the page tree. Exclusive with pdfA. Randomised output, never cached. | |
| margins | No | Margins in points, all four required (0–200). Default 45 / 36 / 35 / 36. | |
| compress | No | FlateDecode the streams (smaller file, different bytes; PDF/A unaffected, XMP stays plain). Default false. | |
| metadata | No | /Info (+ XMP under PDF/A): author, subject, keywords, /Trapped. | |
| pageSize | No | Portrait page preset (points): A4 595.28×841.89 (default), Letter 612×792, Legal 612×1008, A3 841.89×1190.55, Tabloid 792×1224. print.* boxes must fit it. | |
| direction | No | Base text direction (UAX #9): 'auto' reads each paragraph's first strong character and right-aligns RTL ones; 'ltr' / 'rtl' force it. A paragraph's own direction overrides it. Omitted = LTR (1.7.0 bytes). | |
| actualText | No | Untagged output: wrap reordered shaped runs and RTL runs in /ActualText so extract_text returns reading order. Default true; false = bare 1.7.0 glyph runs. No effect on tagged (pdfA) output. | |
| embedFonts | No | Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A or PDF/X claim (every font embedded) and for strict=true; adds ~0.3 MiB. | |
| footerText | No | Optional footer text rendered at the bottom of every page. | |
| outputMode | No | Either 'base64' (returns the PDF inline) or 'file' (writes to a sandboxed path inside PDFNATIVE_MCP_OUTPUT_DIR). | base64 |
| outputPath | No | Required when outputMode='file'. Relative path inside the sandbox; must end with .pdf. | |
| typography | No | Fine typography, all opt-in (omitted = unchanged bytes). kerning and fontFeatures need embedFonts:true ('fr' works on base-14 too). No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt. | |
| creationDate | No | ISO-8601 instant for /CreationDate (+ XMP, the trailer /ID and the {date} placeholder), written in UTC. Pin it for byte-identical output across calls and hosts; omitted = wall clock, so every call differs. | |
| outputIntent | No | Custom OutputIntent (under pdfA or pdfx): an RGB, CMYK or Gray ICC profile + condition strings, replacing the built-in sRGB intent. The profile must be a real ICC file ('acsp' signature, consistent size — PRINT_ERROR otherwise); pdfx needs device class 'prtr'. Under a CMYK / Gray intent RGB content is mapped through a calibrated default space. | |
| footerTemplate | No | Running footer on every page. Replaces the default footer: footerText is then ignored and page numbers appear only via {page}/{pages}. | |
| headerTemplate | No | Running header on every page (left / center / right zones); reserves 15 pt. | |
| includeDiagnostics | No | Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*, TEXT_GLYPH_NOT_COVERED) as `diagnostics[]` (possibly empty). |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded. |
| mode | Yes | |
| summary | No | Tool-specific summary, when produced. |
| filePath | No | Sandboxed absolute path (file mode). |
| sizeBytes | Yes | |
| diagnostics | No | Engine diagnostics (when includeDiagnostics=true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this non-read-only, non-destructive, idempotent and closed-world; the description adds that it builds a new interactive AcroForm and that PDF/A, print, metadata and creationDate options behave as on other document tools. It does not spell out edge behavior such as PDF/A–encryption exclusivity or output-mode mechanics, but those are covered in the schema rather than contradicting the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three compact sentences, front-loaded with the core purpose and then routing guidance. Every sentence carries weight; no repetition of schema detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex 23-parameter builder with a published output schema and full schema descriptions, the description covers the essential purpose, routing, and major option groups. It does not need to restate return values or every nested parameter, though it could mention required inputs and output mode explicitly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all 23 parameters, including field-level options. The description adds only the broad field-type list and a pointer to common PDF/A, print, metadata and creationDate options, which does not add syntax or constraints beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('New PDF with an interactive AcroForm') and enumerates the form controls it can create. It explicitly distinguishes itself from fill_form/read_form_fields, so an agent can route creation versus filling without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-not guidance: 'To fill or flatten an EXISTING form use read_form_fields + fill_form.' It also names concrete use cases (data capture, surveys, fillable templates) and identifies the common document options, leaving little inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
add_international_textAdd international textAIdempotent
PDF rendering text in 32 scripts (Arabic, Hebrew, Thai, Lao, CJK, Devanagari, Bengali, Gujarati, Gurmukhi, Kannada, Malayalam, Odia, Tamil, Telugu, Sinhala, Tibetan, Khmer, Myanmar, Tai Tham, New Tai Lue, Tai Le, Cham, Ethiopic, Cyrillic, Greek, Georgian, Armenian, Vietnamese, …; ha / yo / ig / sw are aliases of latin with anchored combining marks), COLRv1 colour emoji and mathematical symbols ('math': ∀ ∃ √ ∑ ∫ ∞). BiDi (UAX #9), Arabic joining and complex-script shaping are automatic; input is NFC-normalised; newlines split paragraphs. lang is a code or an array for mixed runs (['ar','emoji'], ['latin','math']). Fonts are always embedded, so embedFonts does not exist here. PDF/A, print, metadata and creationDate options as on every document tool.
| Name | Required | Description | Default |
|---|---|---|---|
| font | No | Operator-registered custom font (the slug of a .ttf / .otf file in PDFNATIVE_MCP_FONT_DIR, e.g. 'brand-sans'): drawn first, with the bundled faces as fallbacks. Unknown slug → FONT_NOT_FOUND listing the registered ones; always embedded, so valid under PDF/A. | |
| lang | Yes | Language / script identifier. Either a single code (e.g. 'ar'), a comma-separated list ('ar,emoji'), or an array (['ar','emoji']). Multiple codes enable multi-font run splitting (script + emoji + Latin fallback). 32 scripts (gu / pa / kn / ml / or — Gujarati, Gurmukhi, Kannada, Malayalam, Odia — since 1.8.0); ha / yo / ig / sw (Hausa, Yoruba, Igbo, Swahili) are aliases of latin, whose combining marks are anchored. | |
| pdfA | No | PDF/A level (Tagged PDF + sRGB OutputIntent + XMP). Fonts are embedded here, so the claim is valid as-is. See docs/guides/PDFA.md. | |
| pdfx | No | PDF/X-4 print exchange (ISO 15930-7). REQUIRES outputIntent with the printer's ICC profile (device class 'prtr'; CMYK or Gray — none is bundled); needs embedFonts:true for a conformant file (PDFX_NO_FONT_ENTRIES otherwise, strict:true refuses). Combines with pdfA:'pdfa2b' | 'pdfa2u' (dual claim) but not pdfa1b / pdfa3b; exclusive with encrypt; metadata.trapped must be 'True' or 'False'; TrimBox or ArtBox, not both. Links and form fields are reported (PDFX_ANNOTATIONS). Check with validate_pdf standard:'pdf-x-4'. See the print_ready prompt. | |
| debug | No | Draw margin / block / cell guide rectangles (unmarked content — not for PDF/UA output). Geometry unchanged. Default false. | |
| No | Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b), `spotColours` ink declarations. See docs/guides/PRINT.md. | ||
| title | Yes | PDF title (rendered as page heading and stored as document metadata). | |
| strict | No | Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other (TYPOGRAPHY_FEATURE_INEFFECTIVE, TEXT_GLYPH_NOT_COVERED — a character no font covers, drawn as a box or '?') → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true. | |
| encrypt | No | Encrypt at build time (AES-128 default / AES-256) and KEEP the AcroForm — unlike encrypt_pdf, which rebuilds the page tree. Exclusive with pdfA. Randomised output, never cached. | |
| margins | No | Margins in points, all four required (0–200). Default 45 / 36 / 35 / 36. | |
| compress | No | FlateDecode the streams (smaller file, different bytes; PDF/A unaffected, XMP stays plain). Default false. | |
| metadata | No | /Info (+ XMP under PDF/A): author, subject, keywords, /Trapped. | |
| pageSize | No | Portrait page preset (points): A4 595.28×841.89 (default), Letter 612×792, Legal 612×1008, A3 841.89×1190.55, Tabloid 792×1224. print.* boxes must fit it. | |
| direction | No | Base text direction (UAX #9): 'auto' reads each paragraph's first strong character and right-aligns RTL ones; 'ltr' / 'rtl' force it. A paragraph's own direction overrides it. Omitted = LTR (1.7.0 bytes). | |
| normalize | No | Unicode normalization before shaping. Default 'NFC' (widest glyph coverage); NFD/NFKC/NFKD or false for special needs. | |
| actualText | No | Untagged output: wrap reordered shaped runs and RTL runs in /ActualText so extract_text returns reading order. Default true; false = bare 1.7.0 glyph runs. No effect on tagged (pdfA) output. | |
| outputMode | No | 'base64' (default) returns the PDF inline; 'file' writes it inside the PDFNATIVE_MCP_OUTPUT_DIR sandbox (SECURITY_VIOLATION when the sandbox is not configured). | base64 |
| outputPath | No | Required when outputMode='file'. Relative path inside the sandbox; must end with .pdf (no absolute paths, no '..'). | |
| paragraphs | Yes | Ordered list of paragraphs to render in the chosen script. | |
| typography | No | Fine typography, all opt-in (omitted = unchanged bytes). kerning and fontFeatures need embedFonts:true ('fr' works on base-14 too). No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt. | |
| creationDate | No | ISO-8601 instant for /CreationDate (+ XMP, the trailer /ID and the {date} placeholder), written in UTC. Pin it for byte-identical output across calls and hosts; omitted = wall clock, so every call differs. | |
| outputIntent | No | Custom OutputIntent (under pdfA or pdfx): an RGB, CMYK or Gray ICC profile + condition strings, replacing the built-in sRGB intent. The profile must be a real ICC file ('acsp' signature, consistent size — PRINT_ERROR otherwise); pdfx needs device class 'prtr'. Under a CMYK / Gray intent RGB content is mapped through a calibrated default space. | |
| footerTemplate | No | Running footer on every page. Replaces the default footer: footerText is then ignored and page numbers appear only via {page}/{pages}. | |
| headerTemplate | No | Running header on every page (left / center / right zones); reserves 15 pt. | |
| viewerPreferences | No | Reader presentation hints (catalog /PageLayout, /PageMode, /ViewerPreferences). PDF/A-safe; all optional. | |
| includeDiagnostics | No | Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*, TEXT_GLYPH_NOT_COVERED) as `diagnostics[]` (possibly empty). |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded. |
| mode | Yes | |
| summary | No | Tool-specific summary, when produced. |
| filePath | No | Sandboxed absolute path (file mode). |
| sizeBytes | Yes | |
| diagnostics | No | Engine diagnostics (when includeDiagnostics=true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only mark this as a non-read-only, idempotent, non-destructive build, so the description carries real weight and does: fonts are always embedded and embedFonts deliberately does not exist here, BiDi and Arabic joining are automatic, input is NFC-normalised, and newlines split paragraphs. It does not cover output defaults or common failure modes, but the key behavioral exception versus sibling document tools is disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The capability is front-loaded, which is good, but the opening sentence is a long run-on with a 32-script parenthetical that bulks it out. The trailing 'PDF/A, print, metadata and creationDate options as on every document tool' is efficient, but overall the block is denser than it needs to be.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 26-parameter, deeply nested tool with an output schema, the description correctly stays on the distinctive surface — scripts, automatic shaping, embedded fonts, lang mixing — and leaves the rest to the rich schema. Nothing essential for a correct first call is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents every parameter and the baseline is 3. The description adds a little meaning — lang accepts a single code, comma list or array for mixed runs, and the ha/yo/ig/sw aliases — but most of that is repeated in the lang schema description, so the marginal value is modest.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: renders PDF text in 32 scripts, COLRv1 emoji and math symbols, with automatic BiDi and shaping. It is clear what this tool produces, but it never names how it differs from the closest sibling, generate_basic_pdf, so the agent must infer the split from the script coverage alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: an agent should pick this when text is non-Latin, emoji or math. There is no explicit when-not or any named alternative, and the only routing hint is 'as on every document tool', which assumes the agent knows the sibling set.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
add_ltvEmbed LTV validation material (PAdES B-LT)A
PAdES B-LT: embed a Document Security Store (/DSS + per-signature /VRI) with the certificates and OCSP/CRL material future verifiers need ('LTV enabled' in Adobe Reader once the root is trusted). Ladder step 3: sign_pdf (profile:'pades', timestamp:true) → add_ltv → timestamp_pdf. mode 'online' (default) fetches through the OPERATOR revocation provider (PDFNATIVE_MCP_REVOCATION + PDFNATIVE_MCP_NETWORK_ALLOWED_HOSTS; REVOCATION_NOT_CONFIGURED otherwise — no network without it); mode 'offline' embeds caller-supplied DER certificates / OCSP responses / CRLs with zero network. Incremental (existing /DSS merged). Needs ≥ 1 signed signature; unencrypted PDFs only.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | 'online': fetch OCSP/CRL through the operator provider (PDFNATIVE_MCP_REVOCATION + allow-list; REVOCATION_NOT_CONFIGURED otherwise). 'offline': embed the caller-supplied DER material, zero network. | online |
| match | No | offline: what each signature's /VRI references. 'all' (default): every item (Adobe-tolerant superset). 'chain': only the material that validates that signature (its certificates and issuers, the OCSP responses naming them, their issuers' CRLs); the rest still ships in /DSS. | all |
| pdfBase64 | Yes | Base64-encoded SIGNED PDF (unencrypted). Sign with sign_pdf (profile=pades recommended) first. | |
| outputMode | No | 'base64' (default) returns the PDF inline; 'file' writes it inside the PDFNATIVE_MCP_OUTPUT_DIR sandbox (SECURITY_VIOLATION when the sandbox is not configured). | base64 |
| outputPath | No | Relative path inside PDFNATIVE_MCP_OUTPUT_DIR (required when outputMode='file'). | |
| preferOcsp | No | online: try OCSP before CRL for each certificate (default true). | |
| crlsDerBase64 | No | offline: DER CertificateList (RFC 5280) blobs to embed in /DSS /CRLs. | |
| certificatesDerBase64 | No | offline: DER X.509 certificates to embed in /DSS /Certs. | |
| ocspResponsesDerBase64 | No | offline: DER OCSPResponse (RFC 6960) blobs to embed in /DSS /OCSPs. | |
| extraCertificatesDerBase64 | No | online: additional DER certificates (intermediates / roots) to complete chains the CMS does not carry. |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded. |
| mode | Yes | |
| summary | No | Tool-specific summary, when produced. |
| filePath | No | Sandboxed absolute path (file mode). |
| sizeBytes | Yes | |
| diagnostics | No | Engine diagnostics (when includeDiagnostics=true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations, it discloses network gating via PDFNATIVE_MCP_REVOCATION and PDFNATIVE_MCP_NETWORK_ALLOWED_HOSTS, the REVOCATION_NOT_CONFIGURED failure, offline zero-network behavior, incremental merging of existing /DSS, and prerequisites (at least one signed signature, unencrypted PDFs only). These details materially help an agent predict behavior and failure modes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Despite its density, the description is front-loaded with the core operation, then the ladder position, then mode/network details. Every sentence carries operational information about prerequisites, environment variables, or side effects; there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex mutation tool with ten parameters, network dependencies, and a defined workflow position, the description covers prerequisites, mode behavior, environment gating, output handling hints, and incremental merging. An output schema exists, so return-value explanation is not needed here.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the input schema already documents all ten parameters, including mode, match, outputMode, and the DER material arrays. The description reinforces mode semantics and offline caller-supplied material but does not add much beyond the schema for parameters such as match or outputPath.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource — embed a PAdES B-LT Document Security Store (/DSS + /VRI) — and states exactly what material is added for future verifiers. It distinguishes itself from siblings by placing the tool in the signing ladder between sign_pdf and timestamp_pdf.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit ordered workflow: sign_pdf with profile:'pades' and timestamp:true, then add_ltv, then timestamp_pdf. It also explains when to use each mode: online for operator-provider fetching, offline for caller-supplied DER material with zero network.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
add_tableAdd table / reportAIdempotent
Tabular PDF report from headers + rows (every row the same length). Smart-table options: wrap, repeatHeader (header on every page), zebra, caption (tagged for PDF/A), minRowHeight, cellPadding, cellBorders, cellVAlign, autoFitColumns, clipCells. Inside a longer document use a 'table' block of generate_basic_pdf instead. PDF/A (pdfA + embedFonts:true), print, metadata, watermark and creationDate options as on every document tool.
| Name | Required | Description | Default |
|---|---|---|---|
| pdfA | No | PDF/A level: pdfa1b (simple text+images), pdfa2b/pdfa2u (richer; 2u = Unicode mapping), pdfa3b (attachments / Factur-X). Pair with embedFonts=true for a valid claim. Exclusive with encryption. See docs/guides/PDFA.md. | |
| pdfx | No | PDF/X-4 print exchange (ISO 15930-7). REQUIRES outputIntent with the printer's ICC profile (device class 'prtr'; CMYK or Gray — none is bundled); needs embedFonts:true for a conformant file (PDFX_NO_FONT_ENTRIES otherwise, strict:true refuses). Combines with pdfA:'pdfa2b' | 'pdfa2u' (dual claim) but not pdfa1b / pdfa3b; exclusive with encrypt; metadata.trapped must be 'True' or 'False'; TrimBox or ArtBox, not both. Links and form fields are reported (PDFX_ANNOTATIONS). Check with validate_pdf standard:'pdf-x-4'. See the print_ready prompt. | |
| rows | Yes | Data rows. Each row is an array of cell strings with the same length as `headers`. | |
| wrap | No | Cell wrap policy: 'auto' (default) wraps only overflowing cells; 'always' wraps every cell; 'never' truncates. | |
| debug | No | Draw margin / block / cell guide rectangles (unmarked content — not for PDF/UA output). Geometry unchanged. Default false. | |
| No | Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b), `spotColours` ink declarations. See docs/guides/PRINT.md. | ||
| title | Yes | Report title rendered at the top of the document and used as PDF metadata title. | |
| zebra | No | Alternate-row light tint (static fill, PDF/A-1b safe). | |
| strict | No | Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other (TYPOGRAPHY_FEATURE_INEFFECTIVE, TEXT_GLYPH_NOT_COVERED — a character no font covers, drawn as a box or '?') → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true. | |
| caption | No | Caption rendered above the table (tagged as /Caption under PDF/A). | |
| encrypt | No | Encrypt at build time (AES-128 default / AES-256) and KEEP the AcroForm — unlike encrypt_pdf, which rebuilds the page tree. Exclusive with pdfA. Randomised output, never cached. | |
| headers | Yes | Column header labels. Must have the same length as each row in `rows`. | |
| margins | No | Margins in points, all four required (0–200). Default 45 / 36 / 35 / 36. | |
| compress | No | FlateDecode the streams (smaller file, different bytes; PDF/A unaffected, XMP stays plain). Default false. | |
| metadata | No | /Info (+ XMP under PDF/A): author, subject, keywords, /Trapped. | |
| pageSize | No | Portrait page preset (points): A4 595.28×841.89 (default), Letter 612×792, Legal 612×1008, A3 841.89×1190.55, Tabloid 792×1224. print.* boxes must fit it. | |
| clipCells | No | Clip cell contents to the column bounds (PDF clip operators). Recommended for PDF/A and visual safety. | |
| direction | No | Base text direction (UAX #9): 'auto' reads each paragraph's first strong character and right-aligns RTL ones; 'ltr' / 'rtl' force it. A paragraph's own direction overrides it. Omitted = LTR (1.7.0 bytes). | |
| infoItems | No | Optional key-value metadata rows rendered below the title (e.g. date, author). | |
| watermark | No | Optional semi-transparent watermark rendered centred on every page: `text` (e.g. 'DRAFT'), `image` (JPEG/PNG/JPEG 2000), or both combined. At least one of text / image is required. opacity < 1.0 (text or image, including the defaults) is rejected under pdfA='pdfa1b' (ISO 19005-1 forbids transparency). | |
| actualText | No | Untagged output: wrap reordered shaped runs and RTL runs in /ActualText so extract_text returns reading order. Default true; false = bare 1.7.0 glyph runs. No effect on tagged (pdfA) output. | |
| cellVAlign | No | Vertical alignment of cell content. | |
| embedFonts | No | Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A or PDF/X claim (every font embedded) and for strict=true; adds ~0.3 MiB. | |
| footerText | No | Optional text rendered at the bottom of every page. | |
| outputMode | No | Either 'base64' (returns the PDF inline) or 'file' (writes to a sandboxed path inside PDFNATIVE_MCP_OUTPUT_DIR). | base64 |
| outputPath | No | Required when outputMode='file'. Relative path inside the sandbox; must end with .pdf. | |
| typography | No | Fine typography, all opt-in (omitted = unchanged bytes). kerning and fontFeatures need embedFonts:true ('fr' works on base-14 too). No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt. | |
| cellBorders | No | Per-cell vector borders (pure strokes, PDF/A-safe). Choose individual sides or `all`. | |
| cellPadding | No | Horizontal cell padding in points (default 3). | |
| creationDate | No | ISO-8601 instant for /CreationDate (+ XMP, the trailer /ID and the {date} placeholder), written in UTC. Pin it for byte-identical output across calls and hosts; omitted = wall clock, so every call differs. | |
| minRowHeight | No | Minimum row height in points (default 12). | |
| outputIntent | No | Custom OutputIntent (under pdfA or pdfx): an RGB, CMYK or Gray ICC profile + condition strings, replacing the built-in sRGB intent. The profile must be a real ICC file ('acsp' signature, consistent size — PRINT_ERROR otherwise); pdfx needs device class 'prtr'. Under a CMYK / Gray intent RGB content is mapped through a calibrated default space. | |
| repeatHeader | No | Repeat the header row on every continuation page (default true). | |
| autoFitColumns | No | Auto-fit column widths to content. Output bytes then depend on text metrics (not byte-deterministic across content changes). | |
| footerTemplate | No | Running footer on every page. Replaces the default footer: footerText is then ignored and page numbers appear only via {page}/{pages}. | |
| headerTemplate | No | Running header on every page (left / center / right zones); reserves 15 pt. | |
| viewerPreferences | No | Reader presentation hints (catalog /PageLayout, /PageMode, /ViewerPreferences). PDF/A-safe; all optional. | |
| includeDiagnostics | No | Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*, TEXT_GLYPH_NOT_COVERED) as `diagnostics[]` (possibly empty). |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded. |
| mode | Yes | |
| summary | No | Tool-specific summary, when produced. |
| filePath | No | Sandboxed absolute path (file mode). |
| sizeBytes | Yes | |
| diagnostics | No | Engine diagnostics (when includeDiagnostics=true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly=false, destructive=false, idempotent=true and openWorld=false, so the safety profile is covered; the description adds the non-obvious constraint that a PDF/A claim requires pdfA plus embedFonts:true. It does not restate contradictions or hidden side effects, and it delegates print/metadata/watermark/creationDate semantics to the shared document-tool conventions rather than spelling them out.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with purpose, then the option map, then the sibling routing rule — no filler. The middle enumeration is long but functions as a navigational index into a very large schema, so it earns its space; it could be trimmed slightly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 38 parameters, a rich schema and an output schema present, the description correctly focuses on purpose, the table-specific subset, and the sibling alternative while delegating the shared document options ('as on every document tool') and return values to structured fields. Nothing essential for a correct first call is missing, though outputMode/file-writing behavior is only implicitly covered by the delegation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description earns more by grouping the table-specific knobs (wrap, repeatHeader, zebra, caption, minRowHeight, cellPadding, cellBorders, cellVAlign, autoFitColumns, clipCells) so the agent knows which of the 38 parameters actually govern table layout. It also flags the cross-parameter pairing 'pdfA + embedFonts:true', which is semantic rather than schema restatement.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific output (a tabular PDF report) built from named inputs (`headers` + `rows`, equal-length rows), which is a concrete verb+resource+shape. It also distinguishes itself from the sibling `generate_basic_pdf` by pointing to that tool's 'table' block for tables inside longer documents.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit when-not plus the alternative: 'Inside a longer document use a table block of generate_basic_pdf instead.' That is exactly the routing decision an agent needs between the two document-producing tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
annotate_pdfAnnotate PDF (markup / drawing)AIdempotent
Append markup annotations (ISO 32000-1 §12.5) to an existing PDF as a non-destructive incremental update (original bytes preserved). Types: text (sticky note), highlight | underline | strikeout | squiggly, square | circle, line (needs start/end), freetext, link (needs url — http:, https: or mailto:; the rect is the clickable area). Each needs a 0-based page and rect [x1,y1,x2,y2]; optional contents, color, opacity, title and type-specific fields. VISUAL OVERLAY ONLY — nothing is removed or redacted (covered text stays extractable). Encrypted sources → ENCRYPTED_SOURCE (decrypt_pdf first).
| Name | Required | Description | Default |
|---|---|---|---|
| pdfBase64 | Yes | Base64-encoded source PDF to annotate. | |
| outputMode | No | 'base64' (default) returns the PDF inline; 'file' writes it inside the PDFNATIVE_MCP_OUTPUT_DIR sandbox (SECURITY_VIOLATION when the sandbox is not configured). | base64 |
| outputPath | No | Required when outputMode='file'. Relative path inside the sandbox; must end with .pdf (no absolute paths, no '..'). | |
| annotations | Yes | Markup / drawing annotations to add. Each is attached to a 0-based page index. |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded. |
| mode | Yes | |
| summary | No | Tool-specific summary, when produced. |
| filePath | No | Sandboxed absolute path (file mode). |
| sizeBytes | Yes | |
| diagnostics | No | Engine diagnostics (when includeDiagnostics=true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the safety profile (readOnly=false, destructive=false, idempotent=true), and the description reinforces it with valuable detail: incremental update with original bytes preserved, covered text stays extractable, and link rects draw no visible appearance. Minor tension: 'append' semantics mean repeat calls would stack duplicate annotations, which sits awkwardly with idempotentHint=true, though the description never claims call-level idempotence.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The key constraint (non-destructive, original bytes preserved) is front-loaded and the type list is compact. The middle run-on sentence packing types, requirements, and encodings is dense but every clause carries information; only light reformatting would improve scanning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, all four parameters are documented, and annotations cover the safety profile, so the description's job is to cover behavior — which it does: mutation semantics, byte preservation, redaction limitation, and prerequisite decryption. Nothing an agent needs before calling is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds useful cross-parameter meaning by tying fields to types ('line (needs start/end)', 'link (needs url — http:, https: or mailto:)', 'rect is the clickable area') and restating the 0-based page and [x1,y1,x2,y2] rect conventions. It stops short of explaining quadPoints geometry or colour format trade-offs beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Append markup annotations') and resource ('an existing PDF') plus the exact annotation types supported, which no sibling tool covers. An agent can tell immediately this adds markup rather than editing content, forms, or metadata.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the encrypted-input case: 'Encrypted sources → ENCRYPTED_SOURCE (decrypt_pdf first)', naming the sibling to run first. It also warns that this is a visual overlay only, so it implicitly excludes redaction-style use, but no other exclusions or alternatives are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
decrypt_pdfDecrypt a PDFAIdempotent
Emit an UNENCRYPTED copy of an encrypted PDF (RC4 V1–V4, AES-128, AES-256) given password (user or owner; empty user password needs none). CAVEAT: the page tree is rebuilt — signatures and AcroForm are DROPPED. To merely READ an encrypted PDF pass password to inspect_pdf / extract_text / extract_attachments / read_form_fields instead. Never cached.
| Name | Required | Description | Default |
|---|---|---|---|
| password | No | Password to open the encrypted source (user or owner). Omit only for documents with an empty user password. | |
| pdfBase64 | Yes | Base64-encoded encrypted PDF to decrypt. NOTE: signatures and AcroForm are dropped (page-tree rebuild). | |
| outputMode | No | 'base64' (default) returns the PDF inline; 'file' writes it inside the PDFNATIVE_MCP_OUTPUT_DIR sandbox (SECURITY_VIOLATION when the sandbox is not configured). | base64 |
| outputPath | No | Required when outputMode='file'. Relative path inside the sandbox; must end with .pdf. |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded. |
| mode | Yes | |
| summary | No | Tool-specific summary, when produced. |
| filePath | No | Sandboxed absolute path (file mode). |
| sizeBytes | Yes | |
| diagnostics | No | Engine diagnostics (when includeDiagnostics=true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing that the page tree is rebuilt and signatures and AcroForm are DROPPED from the output copy, which is exactly the kind of lossiness an agent must know before calling. It also discloses 'Never cached,' a behavioral trait set by neither the annotations nor the schema. The dropped-content caveat does not contradict destructiveHint=false, since the source file is untouched and a new copy is emitted.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences: format/scope first, the destructive caveat second (flagged with CAVEAT), the alternative routing third. Every clause carries information and the most decision-relevant constraint is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a four-parameter mutation tool with full schema coverage, annotations, and an output schema, the description covers everything else an agent needs: supported cipher versions, password semantics, output fidelity loss, and the correct sibling for read-only use. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents password (user or owner, omit for empty user password), outputMode, and outputPath in detail. The description's parenthetical about password types largely restates the schema rather than adding new semantics. Baseline 3 is appropriate where the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Emit an UNENCRYPTED copy of an encrypted PDF') and even enumerates the supported encryption schemes (RC4 V1-V4, AES-128, AES-256). This cleanly distinguishes it from encrypt_pdf, inspect_pdf, and the other siblings without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says when NOT to use it and names the four alternatives: 'To merely READ an encrypted PDF pass `password` to inspect_pdf / extract_text / extract_attachments / read_form_fields instead.' It also states the condition (empty user password needs none) for when a password can be omitted.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
draft_governance_issueDraft a governance-compliant GitHub issue (HITL)AIdempotent
Produce a LOCAL GitHub issue draft + compliance report for pdfnative / pdfnative-mcp and NEVER submit it — the agent drafts, a human reviews and files it under their own identity (Human-In-The-Loop contract, .github/AGENT_RULES.md). No GitHub write path exists. The draft is checked against the zero-dependency + reproduction policy; a violation (new runtime dependency, missing reproduction, duplicateSearchPerformed:false) throws GOVERNANCE_VIOLATION. Returns markdown inline (outputMode:'file' also writes a .md). Present the draft AND the report to the user, then STOP.
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | Concise issue title (imperative, no trailing period). | |
| summary | Yes | One or two paragraphs describing the problem or proposal. | |
| issueType | Yes | Issue category: 'bug' | 'feature' | 'security' | 'docs' | 'performance'. | |
| outputMode | No | 'inline' (default) returns the draft markdown in the response. 'file' additionally writes it to the sandbox (requires PDFNATIVE_MCP_OUTPUT_DIR); outputPath must be a relative .md path. | inline |
| outputPath | No | Relative .md path inside the sandbox (only when outputMode='file'). | |
| targetRepo | No | Destination repository label for the draft (documentation only — the server never contacts it). Typically 'pdfnative-mcp' or 'pdfnative'. | pdfnative-mcp |
| reproduction | Yes | The minimal, locally-executed reproduction that justifies this issue. | |
| actualBehavior | No | What actually happened (defaults to the reproduction result when omitted). | |
| affectedPackages | No | Packages impacted by this issue (e.g. ["pdfnative-mcp"], ["pdfnative"]). | |
| expectedBehavior | Yes | What you expected to happen instead. | |
| duplicateSearchPerformed | Yes | MUST be true: confirms you searched open AND closed issues/PRs for duplicates before drafting. |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | Public URL of the draft (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set). |
| title | Yes | |
| filePath | No | Sandboxed absolute path (when outputMode='file'). |
| warnings | Yes | |
| issueType | Yes | |
| sizeBytes | Yes | |
| compliance | Yes | |
| outputMode | Yes | |
| targetRepo | Yes | |
| draftMarkdown | Yes | The full draft, ready for a human to review and submit. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnly=false, idempotent=true, destructive=false; the description adds substantive behavior the agent could not infer: validation against zero-dependency and reproduction policy, a thrown GOVERNANCE_VIOLATION on specific violations, and the file-mode requirement for PDFNATIVE_MCP_OUTPUT_DIR. It also resolves the apparent contradiction between 'draft' and a non-destructive write by clarifying nothing is ever submitted.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core contract in the first clause and ends with a crisp stop instruction. It is dense—multiple policy references (AGENT_RULES.md, zero-dependency, reproduction policy, duplicateSearchPerformed) are packed into two long sentences—but nearly every clause carries decision-relevant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 11 parameters (6 required, one nested object), an output schema, and full annotation coverage, the description supplies the missing behavioral layer: no external write happens, validation can throw, and output goes inline or to a sandbox file. An agent has everything needed to call it correctly and to know what to do with the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3; the description earns above that by tying specific parameters to behavior—outputMode:'file' writing a .md, and duplicateSearchPerformed:false being a violation trigger. Only targetRepo's documentation-only nature and these hints are restated from the schema rather than adding wholly new meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and artifact: 'Produce a LOCAL GitHub issue draft + compliance report' for a named repo, and explicitly negates the confusing action ('NEVER submit it'). The purpose is unmistakable and clearly disjoint from the PDF-manipulation siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear operating context (Human-In-The-Loop contract, .github/AGENT_RULES.md, 'No GitHub write path exists') and a terminal instruction ('Present the draft AND the report to the user, then STOP'). It stops short of naming when to prefer this over alternatives or prerequisites like searching duplicates first, but with no real sibling overlap the guidance is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
embed_imageEmbed image in PDFAIdempotent
PDF with one embedded JPEG, PNG or JPEG 2000 image (base64; PNG without alpha channel; JPEG 2000 passed through as /JPXDecode) plus optional caption and render width/height. Inside a longer document use an 'image' block of generate_basic_pdf instead. PDF/A, print, metadata and creationDate options as on every document tool.
| Name | Required | Description | Default |
|---|---|---|---|
| alt | No | Accessible description of the image (tagged /Figure /Alt). Provide it for non-decorative images under PDF/A or PDF/UA. | |
| pdfA | No | PDF/A level: pdfa1b (simple text+images), pdfa2b/pdfa2u (richer; 2u = Unicode mapping), pdfa3b (attachments / Factur-X). Pair with embedFonts=true for a valid claim. Exclusive with encryption. See docs/guides/PDFA.md. | |
| pdfx | No | PDF/X-4 print exchange (ISO 15930-7). REQUIRES outputIntent with the printer's ICC profile (device class 'prtr'; CMYK or Gray — none is bundled); needs embedFonts:true for a conformant file (PDFX_NO_FONT_ENTRIES otherwise, strict:true refuses). Combines with pdfA:'pdfa2b' | 'pdfa2u' (dual claim) but not pdfa1b / pdfa3b; exclusive with encrypt; metadata.trapped must be 'True' or 'False'; TrimBox or ArtBox, not both. Links and form fields are reported (PDFX_ANNOTATIONS). Check with validate_pdf standard:'pdf-x-4'. See the print_ready prompt. | |
| align | No | Horizontal placement of the image inside the content width. | left |
| debug | No | Draw margin / block / cell guide rectangles (unmarked content — not for PDF/UA output). Geometry unchanged. Default false. | |
| No | Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b), `spotColours` ink declarations. See docs/guides/PRINT.md. | ||
| title | Yes | Document title rendered at the top and used as PDF metadata title. | |
| width | No | Render width in points. If omitted, the image is auto-sized to fit the page. | |
| height | No | Render height in points. If omitted, aspect ratio is preserved. | |
| strict | No | Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other (TYPOGRAPHY_FEATURE_INEFFECTIVE, TEXT_GLYPH_NOT_COVERED — a character no font covers, drawn as a box or '?') → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true. | |
| caption | No | Optional caption rendered below the image. | |
| encrypt | No | Encrypt at build time (AES-128 default / AES-256) and KEEP the AcroForm — unlike encrypt_pdf, which rebuilds the page tree. Exclusive with pdfA. Randomised output, never cached. | |
| margins | No | Margins in points, all four required (0–200). Default 45 / 36 / 35 / 36. | |
| compress | No | FlateDecode the streams (smaller file, different bytes; PDF/A unaffected, XMP stays plain). Default false. | |
| metadata | No | /Info (+ XMP under PDF/A): author, subject, keywords, /Trapped. | |
| mimeType | Yes | MIME type of the image. Must match the actual encoding of imageBase64 (magic bytes are checked). 'image/jp2' accepts a JP2 file (.jp2/.jpx) or a raw JPEG 2000 codestream (.j2k/.j2c). | |
| pageSize | No | Portrait page preset (points): A4 595.28×841.89 (default), Letter 612×792, Legal 612×1008, A3 841.89×1190.55, Tabloid 792×1224. print.* boxes must fit it. | |
| direction | No | Base text direction (UAX #9): 'auto' reads each paragraph's first strong character and right-aligns RTL ones; 'ltr' / 'rtl' force it. A paragraph's own direction overrides it. Omitted = LTR (1.7.0 bytes). | |
| actualText | No | Untagged output: wrap reordered shaped runs and RTL runs in /ActualText so extract_text returns reading order. Default true; false = bare 1.7.0 glyph runs. No effect on tagged (pdfA) output. | |
| embedFonts | No | Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A or PDF/X claim (every font embedded) and for strict=true; adds ~0.3 MiB. | |
| outputMode | No | Either 'base64' (returns the PDF inline) or 'file' (writes to a sandboxed path inside PDFNATIVE_MCP_OUTPUT_DIR). | base64 |
| outputPath | No | Required when outputMode='file'. Relative path inside the sandbox; must end with .pdf. | |
| typography | No | Fine typography, all opt-in (omitted = unchanged bytes). kerning and fontFeatures need embedFonts:true ('fr' works on base-14 too). No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt. | |
| imageBase64 | Yes | Base64 image bytes. JPEG (baseline; 1, 3 or 4 components — CMYK raises PDFA_DEVICE_CMYK_IMAGE under PDF/A), PNG (8-bit greyscale/RGB, non-interlaced; alpha-channel and palette PNGs are rejected with a remedy) or JPEG 2000 (JP2 file or raw .j2k codestream, passed through as /JPXDecode; PDF 1.5+, so PDFA1_JPX_IMAGE under pdfa1b). No data: URI. | |
| creationDate | No | ISO-8601 instant for /CreationDate (+ XMP, the trailer /ID and the {date} placeholder), written in UTC. Pin it for byte-identical output across calls and hosts; omitted = wall clock, so every call differs. | |
| outputIntent | No | Custom OutputIntent (under pdfA or pdfx): an RGB, CMYK or Gray ICC profile + condition strings, replacing the built-in sRGB intent. The profile must be a real ICC file ('acsp' signature, consistent size — PRINT_ERROR otherwise); pdfx needs device class 'prtr'. Under a CMYK / Gray intent RGB content is mapped through a calibrated default space. | |
| footerTemplate | No | Running footer on every page. Replaces the default footer: footerText is then ignored and page numbers appear only via {page}/{pages}. | |
| headerTemplate | No | Running header on every page (left / center / right zones); reserves 15 pt. | |
| includeDiagnostics | No | Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*, TEXT_GLYPH_NOT_COVERED) as `diagnostics[]` (possibly empty). |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded. |
| mode | Yes | |
| summary | No | Tool-specific summary, when produced. |
| filePath | No | Sandboxed absolute path (file mode). |
| sizeBytes | Yes | |
| diagnostics | No | Engine diagnostics (when includeDiagnostics=true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare mutation (readOnlyHint false), non-destructiveness, idempotency and closed-world behavior. Beyond that, the description discloses format-handling behavior an agent would otherwise discover only by error: PNG without alpha, JPEG 2000 passed through as /JPXDecode, and that PDF/A, print and metadata options are shared with all document tools.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three compact sentences, front-loaded with the core output and its image-format constraints. The parenthetical format details and the reference to shared options are dense but earn their place; nothing is redundant with the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 29-parameter document builder, the description covers the distinctive parts (image input constraints, placement, the longer-document alternative) and deliberately delegates shared PDF/A, print and metadata options to the documented convention. With an output schema present, return-value explanation is unnecessary.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and 29 parameters are individually documented, so the schema carries nearly all parameter meaning. The description adds only a top-level summary (caption, render width/height, shared PDF/A and print options), which is baseline-level value over the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a specific output (a PDF with one embedded JPEG, PNG or JPEG 2000 image) and names the accepted encodings. It also distinguishes itself from the closest sibling by telling the agent to use generate_basic_pdf's image block for longer documents.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The routing sentence gives a clear when-to-use-else rule: single image now, embedded image block when the image belongs in a longer document. It doesn't add an explicit exclusion list, but the primary alternative is named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
encrypt_pdfEncrypt / re-secure a PDFA
Encrypt an existing PDF with the Standard Security Handler: AES-128 (default) or AES-256; RC4 is never emitted. ownerPassword required; optional userPassword (open password), permissions { print, copy, modify, extractText }. Rotate the password of an already-encrypted source by passing its current password. CAVEAT: the page tree is rebuilt — signatures and AcroForm are DROPPED, only URI links kept; encrypt BEFORE signing. Never cached.
| Name | Required | Description | Default |
|---|---|---|---|
| password | No | Current password of an already-encrypted source (enables password rotation). Omit for an unencrypted source. | |
| algorithm | No | aes128 (V4/R4, widest compatibility) or aes256 (V5/R6). | aes128 |
| pdfBase64 | Yes | Base64-encoded source PDF to encrypt. NOTE: existing signatures and AcroForm are dropped (page-tree rebuild). | |
| outputMode | No | 'base64' (default) returns the PDF inline; 'file' writes it inside the PDFNATIVE_MCP_OUTPUT_DIR sandbox (SECURITY_VIOLATION when the sandbox is not configured). | base64 |
| outputPath | No | Required when outputMode='file'. Relative path inside the sandbox; must end with .pdf. | |
| permissions | No | Permission flags; each defaults to allowed. | |
| userPassword | No | Open password; omitted/empty = opens without a prompt. | |
| ownerPassword | Yes | Owner password (full access). |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded. |
| mode | Yes | |
| summary | No | Tool-specific summary, when produced. |
| filePath | No | Sandboxed absolute path (file mode). |
| sizeBytes | Yes | |
| diagnostics | No | Engine diagnostics (when includeDiagnostics=true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing the lossy side effect — the page tree is rebuilt, signatures and AcroForm are dropped, only URI links survive — plus that the result is never cached and RC4 is never emitted. This is exactly the pre-call warning an agent needs, since destructiveHint=false alone would not prepare it for losing signatures and form fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but front-loaded: the operation and algorithm come first, then required/optional credentials, then the destructive caveat in a clearly labeled CAVEAT clause. Nearly every clause carries information; only the permissions enumeration lightly duplicates the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter tool with a nested permissions object and an output schema, the description covers the operation, credential model, security caveat, and ordering constraint against signing. Output routing (base64 vs sandboxed file) is left entirely to the schema, which is acceptable given outputMode/outputPath are fully described there.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents every parameter, including the password-rotation meaning and the AES variants. The description mostly restates that structure (ownerPassword required, userPassword optional, permission flag list) rather than adding syntax or edge-case meaning, so the baseline applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Encrypt an existing PDF") plus the exact handler family (Standard Security Handler) and the algorithm set it can and cannot emit. Its scope is also delineated against the closest siblings: password rotation covers the encrypted-source case that otherwise belongs to decrypt_pdf, and "encrypt BEFORE signing" positions it relative to sign_pdf.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear when-to-use conditions: pass `password` to rotate an already-encrypted source, omit it for a plain source, and encrypt before signing. It does not explicitly name decrypt_pdf as the alternative for removing protection, so the exclusion is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
extract_attachmentsExtract embedded files from PDFARead-onlyIdempotent
Read-only extraction of embedded files (PDF/A-3, Factur-X, ZUGFeRD): name, mimeType, AFRelationship, description, sizeBytes and (by default) the payload as dataBase64. filename selects one file; includeData:false probes metadata only. Encrypted sources: pass password. Token-frugal: verbosity:'summary'.
| Name | Required | Description | Default |
|---|---|---|---|
| fields | No | Optional dot-path projection applied to the structured result (e.g. ['attachments.name']). Composes after verbosity. Unknown paths are omitted. | |
| filename | No | Optional exact attachment name to extract. When omitted, every embedded file is returned. | |
| password | No | Password (user or owner) of an encrypted source. Never logged or echoed. | |
| pdfBase64 | Yes | Base64-encoded PDF bytes to read embedded files from. | |
| verbosity | No | Response verbosity. 'full' (default) returns the attachments[] array; 'summary' returns a token-frugal { attachmentCount } and drops the array. | full |
| includeData | No | When true (default) each attachment carries its decoded payload as dataBase64. Set false for a metadata-only probe (names, sizes, relationships) with no payload bytes. |
Output Schema
| Name | Required | Description |
|---|---|---|
| attachments | No | |
| attachmentCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, and the description reinforces this with 'Read-only extraction'. It adds valuable behavioral details beyond annotations: default payload inclusion, metadata-only probing, password handling, and token-frugal summary mode. These add meaningful context without contradicting the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three tightly-worded sentences with no fluff. The core action is front-loaded (read-only extraction), key formats are named in the first sentence, and the remaining sentences efficiently cover optional behaviors and parameter interactions.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has a high-quality output schema, rich parameter descriptions, and complete annotations, the description covers the necessary behavioral context: file selection, payload vs metadata probing, encrypted sources, and response verbosity. Nothing appears missing for an agent to correctly invoke this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides 100% parameter coverage with detailed descriptions, so the baseline is 3. The description adds concise semantic layer by explaining the practical intent of includeData:false as metadata-only probing and verbosity:'summary' as token-frugal. It also hints at the relationship between filename and single-file selection, complementing the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies a specific verb-object pair ('Read-only extraction') targeting embedded files in PDFs, including recognizable formats like PDF/A-3 and ZUGFeRD. This distinguishes it from sibling tools such as add_attachment and extract_text without ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear usage context: extracting embedded files from a PDF, including how to select a single file, probe metadata only, handle encrypted sources, and save tokens. It stops short of explicitly naming alternative tools or stating when not to use this tool, but the context is strong enough for an agent to route correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
extract_pagesExtract pages into one PDFAIdempotent
Keep an arbitrary pages[] subset (0-based, in the given order) in ONE fresh PDF. Same page-tree caveats as merge_pdfs (signatures/AcroForm/XMP dropped; boxes kept; URI links unless dropAnnotations). Encrypted sources: password; output unencrypted unless encrypt. Need several documents? Use split_pdf.
| Name | Required | Description | Default |
|---|---|---|---|
| pages | Yes | 0-based page indices to keep, in output order. Duplicates and out-of-range indices are rejected. | |
| encrypt | No | Re-encrypt the output (Standard Security Handler; AES-128 default or AES-256; RC4 never emitted). | |
| password | No | Password (user or owner) of an encrypted source. Never logged or echoed. | |
| pdfBase64 | Yes | Base64-encoded source PDF. Pass `password` for an encrypted source. | |
| outputMode | No | 'base64' (default) returns the PDF inline; 'file' writes it inside the PDFNATIVE_MCP_OUTPUT_DIR sandbox (SECURITY_VIOLATION when the sandbox is not configured). | base64 |
| outputPath | No | Required when outputMode='file'. Relative path inside the sandbox; must end with .pdf (no absolute paths, no '..'). | |
| dropAnnotations | No | When true, drop ALL annotations. Default keeps self-contained URI link annotations. | |
| maxOutputSizeBytes | No | Maximum size, in bytes, of the produced PDF. Defaults to 268435456 (256 MiB). |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded. |
| mode | Yes | |
| summary | No | Tool-specific summary, when produced. |
| filePath | No | Sandboxed absolute path (file mode). |
| sizeBytes | Yes | |
| diagnostics | No | Engine diagnostics (when includeDiagnostics=true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say readOnly=false, destructive=false, idempotent=true; the description goes well beyond them by disclosing that signatures/AcroForm/XMP are dropped, boxes are kept, URI link annotations survive unless dropAnnotations, and the output is unencrypted by default. These are exactly the lossy side effects an agent needs before committing a mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with the core operation, then caveats, then alternative routing. No filler, and the parenthetical detail is dense rather than padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter mutation tool with a nested encrypt object and an output schema, the description covers the important behavior (lossy conversion, encryption defaults, sandbox-free base64 default). The one weakness is the 'Same page-tree caveats as merge_pdfs' cross-reference, which forces reliance on another tool's description even though the caveats are partially enumerated inline.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents pages, password, encrypt, dropAnnotations, outputMode and maxOutputSizeBytes in detail. The description's mentions of `pages`, `password`, and `encrypt` largely restate that, adding no syntax or constraint beyond the schema's existing notes. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a specific verb-plus-resource with scope: keep an arbitrary `pages[]` subset (0-based, in the given order) in ONE fresh PDF. That immediately distinguishes it from merge_pdfs (combining documents) and split_pdf (producing several files), so an agent can pick it without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear routing context: encrypted sources require `password`, output stays unencrypted unless `encrypt` is supplied, and 'Need several documents? Use split_pdf' names an alternative with its selecting condition. It does not explicitly state when NOT to use it relative to merge_pdfs or inspect_pdf, but the positive guidance is strong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
extract_textExtract plain text from PDFARead-onlyIdempotent
Plain-text extraction: decodes Tj/TJ operands through each font's /ToUnicode CMap, /Encoding /Differences or base encoding and returns pages[] + fullText (positioned runs with includeRuns:true; pages selects 0-based pages). extractable is false only when a page decoded ENTIRELY to U+FFFD (a font with no usable mapping — expected for some subset fonts, not an error; extractableReason explains). Tagged content carrying /ActualText (every pdfA document this server writes) returns that SOURCE text, in logical order; untagged right-to-left and reordered shaped runs (Arabic, Hebrew, Indic, Khmer, Myanmar, …) carry /ActualText since pdfnative 1.9 and come back in logical order too — only a Thai above-vowel + tone-mark pair still reads in drawn order untagged. onStreamError: 'limit' (default) fails only on a stream over the decompression cap (PDF_PARSE_FAILED), 'throw' fails on any undecodable stream, 'skip' returns the page without that stream's text. Encrypted sources: pass password (PASSWORD_REQUIRED / PASSWORD_INVALID otherwise). Token-frugal: verbosity:'summary', fields:[…].
| Name | Required | Description | Default |
|---|---|---|---|
| pages | No | Optional 0-based page indices to extract. When omitted, every page is extracted. | |
| fields | No | Optional dot-path projection applied to the structured result (e.g. ['fullText'] or ['extractable']). Composes after verbosity. Unknown paths are omitted. | |
| password | No | Password (user or owner) of an encrypted source. Never logged or echoed. | |
| pdfBase64 | Yes | Base64-encoded PDF bytes. | |
| verbosity | No | Response verbosity. 'full' (default) returns the per-page pages[] array and fullText; 'summary' returns a token-frugal { pageCount, extractedPageCount, extractable, charCount } and drops the text payloads. | full |
| includeRuns | No | When true, each page also carries `runs[]` — positioned text-showing operations `{ text, x, y, fontSize, fontName }` in device space (content-stream order). Useful for layout-aware extraction; larger responses. | |
| maxTextLength | No | Hard cap on total extracted characters across all pages (memory bound for adversarial input). Default 16000000. Exceeding it fails with OUTPUT_TOO_LARGE. | |
| onStreamError | No | 'limit' (default): a stream over the decompression cap (PDFNATIVE_MCP_MAX_INFLATE_BYTES) fails with PDF_PARSE_FAILED; other damaged streams are skipped. 'throw': any undecodable stream fails the call (PDF_PARSE_FAILED). 'skip': skip the over-cap stream too and read the rest (1.7.0 behaviour — that page reads as empty). | limit |
Output Schema
| Name | Required | Description |
|---|---|---|
| pages | No | |
| fullText | No | |
| charCount | No | summary only: length of fullText. |
| pageCount | No | |
| extractable | No | False when one or more requested pages produced text that is entirely U+FFFD replacement characters — a font with no usable /ToUnicode CMap or base encoding. Blank pages are still considered extractable. |
| extractableReason | No | Present when extractable is false: why no text could be decoded. |
| extractedPageCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description is unusually rich about semantics the annotations do not cover: `extractable` is false only when a page decoded ENTIRELY to U+FFFD, extractableReason explains it, /ActualText source-text handling, logical-order behavior for RTL/shaped scripts with the one Thai above-vowel caveat, and per-mode onStreamError outcomes with error codes. That is genuine behavioral context beyond the readOnly/idempotent hints, though the CMap/encoding internals are more implementation trivia than agent-relevant behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose, and most sentences carry real information, but it is a single dense paragraph thick with backticks, parentheticals, and low-value internals (Tj/TJ operands, /Encoding /Differences, pdfnative 1.9 version trivia). Splitting the font-decoding internals from the parameter/behavior notes would improve scannability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter extraction tool with an output schema, the description covers the failure modes (PDF_PARSE_FAILED, OUTPUT_TOO_LARGE, PASSWORD_REQUIRED/PASSWORD_INVALID), the partial-success case (extractable=false), encoding/ordering edge cases, and the token-frugal path. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already defines every parameter including the onStreamError enum and verbosity modes; the description largely restates these. The only marginal additions are the framing of runs as "positioned runs" for includeRuns and the note that `pages` is 0-based, both of which the schema also carries.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ("Plain-text extraction") and immediately names the mechanism (decoding Tj/TJ operands via /ToUnicode CMap) plus the outputs (pages[] + fullText). It is clearly distinguishable from mutating siblings like sign_pdf or add_table, though it never explicitly names the closest logical sibling, inspect_layout, even while mentioning positioned runs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: "includeRuns:true ... Useful for layout-aware extraction" hints at a layout use case, and "Encrypted sources: pass `password`" is a precondition. There is no explicit when-to-use-this-vs-alternatives routing (e.g. vs inspect_layout or inspect_pdf), so the agent must infer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fill_formFill / flatten an existing AcroFormAIdempotent
Fill and/or flatten the AcroForm of an EXISTING PDF (add_form creates one) as an incremental update — prior signatures stay valid for their revision. values: fully-qualified name → string (array for multi-select), boolean or export state for checkbox/radio. flatten:true stamps appearances and drops the interactive layer (with no values = pure flatten). Unknown names → FORM_FIELD_NOT_FOUND unless onUnknownField:'ignore'; signature fields cannot be filled (FORM_UNSUPPORTED). Encrypted sources: password.
| Name | Required | Description | Default |
|---|---|---|---|
| values | No | Map of fully-qualified field name → value. Text/choice: a string (array of strings for multi-select listboxes). Checkbox/radio: a boolean or the export-state string. Omit (or pass {}) with flatten:true for a pure flatten. | |
| flatten | No | When true, stamp appearances into page content and remove the interactive fields after filling. | |
| password | No | Password (user or owner) of an encrypted source. Never logged or echoed. | |
| pdfBase64 | Yes | Base64-encoded source PDF containing the AcroForm to fill. Use read_form_fields first to discover field names. | |
| nonWinAnsi | No | Behaviour when a value contains non-WinAnsi characters (appearance font is Helvetica/WinAnsi). 'throw' (default) rejects it; 'needAppearances' writes the value and sets /NeedAppearances so the viewer regenerates the appearance. | throw |
| outputMode | No | 'base64' (default) returns the PDF inline; 'file' writes it inside the PDFNATIVE_MCP_OUTPUT_DIR sandbox (SECURITY_VIOLATION when the sandbox is not configured). | base64 |
| outputPath | No | Required when outputMode='file'. Relative path inside the sandbox; must end with .pdf. | |
| onUnknownField | No | Behaviour for a value key that matches no field. 'throw' (default) → FORM_FIELD_NOT_FOUND; 'ignore' skips it. | throw |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded. |
| mode | Yes | |
| summary | No | Tool-specific summary, when produced. |
| filePath | No | Sandboxed absolute path (file mode). |
| sizeBytes | Yes | |
| diagnostics | No | Engine diagnostics (when includeDiagnostics=true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false and idempotentHint=true, and the description adds real context beyond them: incremental update semantics that preserve prior signatures for their revision, the error codes FORM_FIELD_NOT_FOUND and FORM_UNSUPPORTED, the signature-field restriction, and password handling for encrypted sources. However, flatten:true 'drops the interactive layer', which is an irreversible effect not reflected in destructiveHint=false; the description discloses it, so the agent is not misled, but the tension between the stated effect and the annotation is left unaddressed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single front-loaded paragraph that leads with the verb, the resource and the sibling contrast before dropping into parameter notes. The terse `key`: meaning notation is dense but scannable, and no sentence is filler; only the stacking of many short clauses makes it slightly harder to parse than it needs to be.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter mutation tool with an output schema, the description covers the non-obvious risks an agent needs: signature preservation, flatten irreversibility, unknown-field policy, signature-field rejection and encryption. Return values need no explanation given the output schema, though outputMode/outputPath sandbox behavior is left entirely to the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, and the description's parameter notes (string/array/boolean value typing, pure-flatten with empty values, password for encrypted sources) largely restate what the schema already documents. It adds a little by tying onUnknownField and the FORM_FIELD_NOT_FOUND code together, but nonWinAnsi, outputMode and outputPath are not mentioned at all in the description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb pair (fill/flatten) against a specific resource (the AcroForm of an EXISTING PDF) and explicitly contrasts with the sibling add_form, which creates one. An agent can distinguish this from add_form and read_form_fields without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The parenthetical '(add_form creates one)' makes the use case explicit: existing forms with fields already present. It also notes 'with no values = pure flatten' as a distinct invocation mode. It stops short of naming read_form_fields as the required discovery step (that hint lives only in the pdfBase64 schema description), so it is clear but not fully routed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_basic_pdfGenerate basic PDFAIdempotent
Multi-page PDF composed from ordered blocks: heading, paragraph, list, table, image (JPEG/PNG/JPEG 2000), link, toc (printed table of contents), barcode, svg, formField, chart, pageBreak, spacer — every block kind the engine offers, each sharing its body with the dedicated tool (add_table, embed_image, add_barcode, add_form, add_chart). DEFAULT for any document; use the dedicated tools only for a standalone artefact, add_attachment for embedded files and add_international_text for non-Latin scripts. pdfA + embedFonts:true for a valid PDF/A-1b/2b/2u/3b claim; outline / pageLabels / viewerPreferences / watermark for navigation and presentation; print, metadata, outputIntent, creationDate as on every document tool. The 'chart' block takes the same body as add_chart.
| Name | Required | Description | Default |
|---|---|---|---|
| font | No | Operator-registered custom font (the slug of a .ttf / .otf file in PDFNATIVE_MCP_FONT_DIR, e.g. 'brand-sans'): drawn first, with the bundled faces as fallbacks. Unknown slug → FONT_NOT_FOUND listing the registered ones; always embedded, so valid under PDF/A. | |
| pdfA | No | PDF/A level: pdfa1b (simple text+images), pdfa2b/pdfa2u (richer; 2u = Unicode mapping), pdfa3b (attachments / Factur-X). Pair with embedFonts=true for a valid claim. Exclusive with encryption. See docs/guides/PDFA.md. | |
| pdfx | No | PDF/X-4 print exchange (ISO 15930-7). REQUIRES outputIntent with the printer's ICC profile (device class 'prtr'; CMYK or Gray — none is bundled); needs embedFonts:true for a conformant file (PDFX_NO_FONT_ENTRIES otherwise, strict:true refuses). Combines with pdfA:'pdfa2b' | 'pdfa2u' (dual claim) but not pdfa1b / pdfa3b; exclusive with encrypt; metadata.trapped must be 'True' or 'False'; TrimBox or ArtBox, not both. Links and form fields are reported (PDFX_ANNOTATIONS). Check with validate_pdf standard:'pdf-x-4'. See the print_ready prompt. | |
| debug | No | Draw margin / block / cell guide rectangles (unmarked content — not for PDF/UA output). Geometry unchanged. Default false. | |
| No | Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b), `spotColours` ink declarations. See docs/guides/PRINT.md. | ||
| title | Yes | Document title (rendered at top of page 1 and used as PDF metadata title). | |
| blocks | Yes | Ordered list of content blocks composing the document body. | |
| strict | No | Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other (TYPOGRAPHY_FEATURE_INEFFECTIVE, TEXT_GLYPH_NOT_COVERED — a character no font covers, drawn as a box or '?') → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true. | |
| encrypt | No | Encrypt at build time (AES-128 default / AES-256) and KEEP the AcroForm — unlike encrypt_pdf, which rebuilds the page tree. Exclusive with pdfA. Randomised output, never cached. | |
| margins | No | Margins in points, all four required (0–200). Default 45 / 36 / 35 / 36. | |
| outline | No | Document outline (bookmarks panel). Either 'auto' (derive a flat outline from heading blocks) or an explicit nested bookmark tree. | |
| compress | No | FlateDecode the streams (smaller file, different bytes; PDF/A unaffected, XMP stays plain). Default false. | |
| metadata | No | /Info (+ XMP under PDF/A): author, subject, keywords, /Trapped. | |
| pageSize | No | Portrait page preset (points): A4 595.28×841.89 (default), Letter 612×792, Legal 612×1008, A3 841.89×1190.55, Tabloid 792×1224. print.* boxes must fit it. | |
| direction | No | Base text direction (UAX #9): 'auto' reads each paragraph's first strong character and right-aligns RTL ones; 'ltr' / 'rtl' force it. A paragraph's own direction overrides it. Omitted = LTR (1.7.0 bytes). | |
| normalize | No | Unicode normalization before shaping ('NFC' recommended for glyph coverage; NFD/NFKC/NFKD accepted). Omit = none. | |
| watermark | No | Optional semi-transparent watermark rendered centred on every page: `text` (e.g. 'DRAFT'), `image` (JPEG/PNG/JPEG 2000), or both combined. At least one of text / image is required. opacity < 1.0 (text or image, including the defaults) is rejected under pdfA='pdfa1b' (ISO 19005-1 forbids transparency). | |
| actualText | No | Untagged output: wrap reordered shaped runs and RTL runs in /ActualText so extract_text returns reading order. Default true; false = bare 1.7.0 glyph runs. No effect on tagged (pdfA) output. | |
| embedFonts | No | Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A or PDF/X claim (every font embedded) and for strict=true; adds ~0.3 MiB. | |
| footerText | No | Optional footer text rendered at the bottom of every page. | |
| outputMode | No | Either 'base64' (returns the PDF inline as a base64 string) or 'file' (writes to a path inside the configured PDFNATIVE_MCP_OUTPUT_DIR sandbox). | base64 |
| outputPath | No | Required when outputMode='file'. Relative path inside the sandbox; must end with .pdf. | |
| pageLabels | No | Page-label ranges (the visible page numbers in the viewer, e.g. roman front-matter then decimal body). startPage values must be unique and strictly increasing. | |
| typography | No | Fine typography, all opt-in (omitted = unchanged bytes). kerning and fontFeatures need embedFonts:true ('fr' works on base-14 too). No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt. | |
| creationDate | No | ISO-8601 instant for /CreationDate (+ XMP, the trailer /ID and the {date} placeholder), written in UTC. Pin it for byte-identical output across calls and hosts; omitted = wall clock, so every call differs. | |
| outputIntent | No | Custom OutputIntent (under pdfA or pdfx): an RGB, CMYK or Gray ICC profile + condition strings, replacing the built-in sRGB intent. The profile must be a real ICC file ('acsp' signature, consistent size — PRINT_ERROR otherwise); pdfx needs device class 'prtr'. Under a CMYK / Gray intent RGB content is mapped through a calibrated default space. | |
| footerTemplate | No | Running footer on every page. Replaces the default footer: footerText is then ignored and page numbers appear only via {page}/{pages}. | |
| headerTemplate | No | Running header on every page (left / center / right zones); reserves 15 pt. | |
| viewerPreferences | No | Reader presentation hints (catalog /PageLayout, /PageMode, /ViewerPreferences). PDF/A-safe; all optional. | |
| includeDiagnostics | No | Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*, TEXT_GLYPH_NOT_COVERED) as `diagnostics[]` (possibly empty). |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded. |
| mode | Yes | |
| summary | No | Tool-specific summary, when produced. |
| filePath | No | Sandboxed absolute path (file mode). |
| sizeBytes | Yes | |
| diagnostics | No | Engine diagnostics (when includeDiagnostics=true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly=false, destructive=false and openWorld=false; the description adds substantive context on compliance behavior — the PDF/A + embedFonts pairing, PDF/X prerequisites, and the exclusivity of encryption with pdfA. It also discloses that bytes vary across calls unless creationDate is pinned, and that encryption produces randomised, never-cached output, which goes beyond the safety hints. Minor gap: outputMode sandboxing and diagnostics behavior live only in the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with what the tool does and its routing guidance before the compliance clauses. It is dense and semicolon-heavy — a bulleted block-kind list would scan faster — but with a 30-parameter tool the length is largely earned.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool this large, the description covers the decision-critical parts: default routing, block coverage, and compliance pairings. Remaining detail (outputMode, print boxes, typography, encryption internals) is fully documented in the schema, and an output schema exists, so no return-value explanation is needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% across all 30 parameters, so the schema carries the parameter semantics and the baseline of 3 applies. The description does add real value by noting that the chart block takes the same body as add_chart and that each block kind mirrors a dedicated tool, which helps the agent reuse known shapes.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — a multi-page PDF composed from ordered blocks — and enumerates the supported block kinds, so an agent knows exactly what it can build. It also explicitly positions itself against siblings: 'DEFAULT for any document; use the dedicated tools only for a standalone artefact', naming add_table, embed_image, add_barcode, add_form and add_chart.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit routing rules: use this for any full document, use dedicated tools only for standalone artefacts, add_attachment for embedded files and add_international_text for non-Latin scripts. It also states when to reach for pdfA + embedFonts, outline/pageLabels/viewerPreferences/watermark, and points to the shared document-level parameters.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
inspect_layoutInspect document layout (dry run)ARead-onlyIdempotent
Pagination preview WITHOUT generating a PDF: page count and where every block lands (page, x, top, width, height in points). Same blocks as generate_basic_pdf plus every input that moves a block (title, footerText, pdfA, normalize, embedFonts, pageSize, margins, headerTemplate, footerTemplate): pass what you will give generate_basic_pdf and the page count matches — the dry run shares the pagination planner of the builder, toc blocks included. Read-only, deterministic. Token-frugal: verbosity:'summary', fields:['totalPages'].
| Name | Required | Description | Default |
|---|---|---|---|
| font | No | Operator-registered custom font (the slug of a .ttf / .otf file in PDFNATIVE_MCP_FONT_DIR, e.g. 'brand-sans'): drawn first, with the bundled faces as fallbacks. Unknown slug → FONT_NOT_FOUND listing the registered ones; always embedded, so valid under PDF/A. | |
| pdfA | No | Tagged (PDF/A) layout mode, as you would pass it to generate_basic_pdf. PDF/A level: pdfa1b (simple text+images), pdfa2b/pdfa2u (richer; 2u = Unicode mapping), pdfa3b (attachments / Factur-X). Pair with embedFonts=true for a valid claim. Exclusive with encryption. See docs/guides/PDFA.md. | |
| title | Yes | Document title — reserves the title band on page 1 exactly as generate_basic_pdf does. | |
| blocks | Yes | Ordered list of content blocks composing the document body. | |
| fields | No | Optional dot-path projection applied to the structured result (e.g. ['totalPages'] or ['pages.blocks.type']). Composes after verbosity. Unknown paths are omitted. | |
| margins | No | Margins in points, all four required (0–200). Default 45 / 36 / 35 / 36. | |
| pageSize | No | Portrait page preset (points): A4 595.28×841.89 (default), Letter 612×792, Legal 612×1008, A3 841.89×1190.55, Tabloid 792×1224. print.* boxes must fit it. | |
| direction | No | Base text direction (UAX #9): 'auto' reads each paragraph's first strong character and right-aligns RTL ones; 'ltr' / 'rtl' force it. A paragraph's own direction overrides it. Omitted = LTR (1.7.0 bytes). | |
| normalize | No | Unicode normalization before shaping ('NFC' recommended for glyph coverage; NFD/NFKC/NFKD accepted). Omit = none. | |
| verbosity | No | 'full' (default) or 'summary' (scalars only: pageWidth, pageHeight, totalPages, blockCount; pages[] and margins dropped). | full |
| actualText | No | Untagged output: wrap reordered shaped runs and RTL runs in /ActualText so extract_text returns reading order. Default true; false = bare 1.7.0 glyph runs. No effect on tagged (pdfA) output. | |
| embedFonts | No | Measure with the embedded Noto Sans Latin metrics instead of Helvetica — pass the same value you will give generate_basic_pdf. (Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A or PDF/X claim (every font embedded) and for strict=true; adds ~0.3 MiB.) | |
| footerText | No | Footer text as you would pass it to generate_basic_pdf (reserves the footer band). | |
| typography | No | Fine typography, all opt-in (omitted = unchanged bytes). kerning and fontFeatures need embedFonts:true ('fr' works on base-14 too). No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt. | |
| footerTemplate | No | Running footer on every page. Replaces the default footer: footerText is then ignored and page numbers appear only via {page}/{pages}. | |
| headerTemplate | No | Running header on every page (left / center / right zones); reserves 15 pt. |
Output Schema
| Name | Required | Description |
|---|---|---|
| pages | No | Per-page block placement, in render order. A table that spans pages appears once per slice. |
| margins | No | Page margins { top, right, bottom, left } in points. |
| pageWidth | No | Page width in points (595.28 = A4). |
| blockCount | No | summary only: number of placed blocks (table slices count once each). |
| pageHeight | No | Page height in points (841.89 = A4). |
| totalPages | No | Number of pages the blocks paginate into. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so the description's marginal value is the fidelity guarantee: the dry run shares the builder's pagination planner, including toc blocks, and is deterministic. It could have gone further on limits (image byte caps, chart measurement behavior) but the behavioral profile is well beyond what annotations alone convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the differentiator, then the contract, then the token-saving tip. Dense but essentially waste-free. Slightly telegraphic phrasing ("Read-only, deterministic." as a fragment) costs a little readability but conveys real information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 16-parameter, nested-schema tool with an output schema, this covers what matters: purpose, fidelity contract, and a cheap output mode. Return-shape detail is correctly delegated to the output schema. Minor gap: no mention of cost/latency or upper bound on blocks when previewing very large documents.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description earns a step above by explaining the semantic invariant tying the parameters together: any input that moves a block (title, footerText, pdfA, normalize, embedFonts, pageSize, margins, header/footer templates) must be mirrored from generate_basic_pdf or the preview diverges. It also names the projection knobs (verbosity:'summary', fields:['totalPages']), which is an efficient-usage cue rather than a restatement.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
"Pagination preview WITHOUT generating a PDF" names a specific verb (preview/inspect) and resource (pagination/layout), and immediately disambiguates from the sibling generate_basic_pdf by stating no PDF is produced. The concrete output promise (page count plus page/x/top/width/height per block) lets an agent know exactly what it gets.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a clear operating rule: pass the same arguments you will give generate_basic_pdf so the page count matches. That tells the agent when this tool is appropriate (pre-flight check before building). It stops short of an explicit "do not call this to produce a file, call generate_basic_pdf for that" exclusion statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
inspect_pdfInspect PDF metadataARead-onlyIdempotent
Read-only facts about a PDF: version, pageCount, encryption, pdfA claim (the claim, not its validity — use veraPDF for that), signatureCount, hasSignaturePlaceholder, attachments[], info; presence-gated dss / docTimestampCount / trapped; signatures:true lists every field (subFilter, isDocTimestamp, isPlaceholder, byteRange, vriKey); pages:true adds per-page sizes and boxes. check:[…] turns it into a CI assertion ('pdfa','signed','encrypted','placeholder','attachments','dss','docTimestamp','trapped') → checks (requested keys only) + checksPassed. Encrypted sources: pass password. Token-frugal: verbosity:'summary', fields:[…].
| Name | Required | Description | Default |
|---|---|---|---|
| check | No | CI assertions → checks (requested keys only) + checksPassed (all hold). 'signed' = a signature field with signed content exists (structural; validity is verify_pdf's job), 'placeholder' = an unsigned placeholder exists, 'dss' = /DSS present, 'docTimestamp' = a /DocTimeStamp exists, 'trapped' = /Info /Trapped set, 'annotations' = at least one page annotation exists, 'pdfx' = the XMP claims PDF/X (the claim, not its validity — validate_pdf standard:'pdf-x-4'). | |
| pages | No | When true, include per-page metadata in the response. | |
| fields | No | Optional dot-path projection applied to the structured result (e.g. ['pageCount','signatureCount']). Composes after verbosity. Unknown paths are omitted. | |
| password | No | Password (user or owner) of an encrypted source. Never logged or echoed. | |
| pdfBase64 | Yes | Base64-encoded PDF bytes to inspect. | |
| verbosity | No | 'full' (default) or 'summary' (scalars only: version, pageCount, encryption, pdfA, signatureCount, hasSignaturePlaceholder, attachmentCount, + docTimestampCount / trapped / pdfX / checksPassed when present; arrays and dss dropped). | full |
| signatures | No | When true, include a signatures[] array describing every signature field (field name, SubFilter, document-timestamp flag, placeholder flag, ByteRange, /Contents length, /VRI key). Off by default to keep responses compact. | |
| annotations | No | When true, include an annotations[] array listing every page annotation (/Annots: links, text notes, highlights, shapes, widgets…) with its 0-based page, subtype, rect and, when present, contents (truncated to 200 chars), title, color, quadPoints and link url. Off by default to keep responses compact. |
Output Schema
| Name | Required | Description |
|---|---|---|
| dss | No | Document Security Store summary (ISO 32000-2 §12.8.4.3), present only when the catalog has a /DSS. |
| info | No | Document /Info dictionary entries decoded as strings. |
| pdfA | No | Detected PDF/A claim (e.g. '1B', '2B', '2U', '3B') from XMP metadata, or null when absent. |
| pdfX | No | PDF/X claim from XMP (pdfxid:GTS_PDFXVersion, e.g. 'PDF/X-4'), present only when the document makes one. A claim, not a verdict: validate_pdf standard:'pdf-x-4' checks it. |
| checks | No | One boolean per REQUESTED check (keys = the check[] you passed, nothing else). |
| perPage | No | |
| trapped | No | /Info /Trapped flag, present only when the document carries one. |
| version | No | PDF version (e.g. "1.7"). |
| pageCount | No | |
| encryption | No | |
| pageLabels | No | Logical page-numbering ranges from the /PageLabels number tree (ISO 32000-1 §12.4.2), or absent when the document has none. Each range gives the 0-based first page, numbering style, optional prefix and start value. |
| signatures | No | Signature fields (opt-in via the `signatures` input). Document timestamps are listed inline with isDocTimestamp=true. |
| annotations | No | Page annotations (opt-in via the `annotations` input), in page order then /Annots order. Only the keys the annotation actually carries are emitted. |
| attachments | No | Embedded files exposed via /Names → /EmbeddedFiles (PDF/A-3, Factur-X). |
| checksPassed | No | Present when check[] was supplied: true when every requested check holds. |
| encryptionInfo | No | Precise Standard Security Handler details (pdfnative v1.6.0), present only when the document is encrypted and was opened successfully. Objects served by the reader are already decrypted. |
| signatureCount | No | |
| annotationCount | No | Total number of page annotations (opt-in via the `annotations` input). |
| attachmentCount | No | summary only: number of embedded files. |
| docTimestampCount | No | Number of /DocTimeStamp signature fields, present only when at least one exists. |
| hasSignaturePlaceholder | No | True when at least one signature widget exists with empty /Contents — i.e. an unsigned placeholder awaiting `sign_pdf`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so the safety profile is covered. The description adds genuinely non-obvious behavior: encrypted sources require a `password`, `check` returns only requested keys plus a `checksPassed` aggregate, and the tool is deliberately token-frugal via verbosity/fields. Nothing about failure modes or limits beyond that, hence not a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but front-loaded: the core output shape comes first, optional flags next, encryption and token notes last. Backtick-heavy jargon makes it terse rather than skim-friendly, but every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter inspection tool with an output schema, the description covers everything an agent needs: scope, field/claim distinction, CI-mode behavior, password handling and compactness controls. Return values are also briefly mapped even though the output schema carries them.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the description largely restates what the schema already documents (check semantics, signatures/pages flags, verbosity contents). It adds little parameter meaning beyond the schema, though the 'composes after verbosity' projection ordering and token-frugal framing have some value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a precise verb+resource ('Read-only facts about a PDF') and enumerates exactly which facts are returned, then explicitly separates what it does NOT judge ('the claim, not its validity — use veraPDF for that'). This lets an agent distinguish it from validate_pdf and verify_pdf without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clear about context: it routes validity questions to veraPDF/verify_pdf and frames the `check` option as a CI assertion workflow. It does not, however, give an explicit when-to-use-this-instead-of-verify_pdf/Sibling routing sentence for the common 'is this signed and valid?' question, which the schema partially covers.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
merge_pdfsMerge PDFsAIdempotent
Concatenate 2–50 PDFs (pdfsBase64[]) into one fresh, self-contained document. Page-tree rebuild: signatures and AcroForm are dropped, XMP (and thus a PDF/A claim) does not survive — re-declare PDF/A on the generating tools; page boxes and /UserUnit do survive; URI links kept unless dropAnnotations:true. Encrypted sources open with one password (PASSWORD_REQUIRED / PASSWORD_INVALID); output unencrypted unless encrypt. Guards: 256 MiB assembly (maxOutputSizeBytes), 50 MiB output (OUTPUT_TOO_LARGE).
| Name | Required | Description | Default |
|---|---|---|---|
| encrypt | No | Re-encrypt the output (Standard Security Handler; AES-128 default or AES-256; RC4 never emitted). | |
| password | No | Password applied to every encrypted source (pdfnative v1.6.0). Sources with an empty user password open without it. The merged output is unencrypted unless `encrypt` is set. | |
| outputMode | No | 'base64' (default) returns the PDF inline; 'file' writes it inside the PDFNATIVE_MCP_OUTPUT_DIR sandbox (SECURITY_VIOLATION when the sandbox is not configured). | base64 |
| outputPath | No | Required when outputMode='file'. Relative path inside the sandbox; must end with .pdf (no absolute paths, no '..'). | |
| pdfsBase64 | Yes | Base64-encoded source PDFs to concatenate, in order. 2–50 documents. Signatures and AcroForms are dropped (a page-tree edit invalidates them); encrypted PDFs are rejected. | |
| dropAnnotations | No | When true, drop ALL annotations. Default (false) keeps self-contained URI link annotations and drops cross-document/widget annotations. | |
| maxOutputSizeBytes | No | In-memory assembly guard (pdfnative maxOutputSize): the merge throws before materialising an object graph larger than this. Defaults to 268435456 (256 MiB). Note the emitted PDF is separately capped at 50 MiB by the output layer. |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded. |
| mode | Yes | |
| summary | No | Tool-specific summary, when produced. |
| filePath | No | Sandboxed absolute path (file mode). |
| sizeBytes | Yes | |
| diagnostics | No | Engine diagnostics (when includeDiagnostics=true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes far beyond the annotations by disclosing page-tree rebuild consequences (signatures and AcroForm dropped, XMP/PDF-A claim lost, page boxes and /UserUnit preserved, URI links retained), the PASSWORD_REQUIRED/PASSWORD_INVALID codes, and two separate size guards (256 MiB assembly, 50 MiB OUTPUT_TOO_LARGE). This is exactly the lossy-side-effect context an agent needs before committing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and dense with useful facts; nearly every clause carries information. The telegraphic, parenthetical style (fragment sentences, inline error codes) is compact but slightly harder to parse than plain prose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter, nested-schema merge tool with an output schema already available, the description covers the critical unknowns: lossiness of the page-tree rebuild, encryption/password behavior, output destination safety, and both size limits with error names. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3; the description still adds value by tying `password` to all encrypted sources, clarifying that output stays unencrypted unless `encrypt` is set, and explaining dropAnnotations' selective URI-link retention and the assembly-vs-output cap distinction. Remaining nested permission flags are left entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource with scope: 'Concatenate 2–50 PDFs into one fresh, self-contained document.' The operation is unambiguous and easily distinguished from siblings like split_pdf or extract_pages, and the required input is named inline.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear conditional context for how to use it correctly: encrypted sources need the single `password`, output is unencrypted unless `encrypt`, and outputMode selects inline vs sandboxed file. It does not explicitly name alternatives or exclusions (e.g., when to extract/insert pages instead of merging), so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
prepare_signature_placeholderPrepare signature placeholderAIdempotent
New PDF carrying an unsigned /Sig placeholder for a LATER sign_pdf call. OPTIONAL — sign_pdf auto-injects one. Use it to size the placeholder (placeholderBytes for > 4096-bit keys, reserveTimestamp for an RFC 3161 token), to pin the widget page (pageIndex), to choose subFilter 'ETSI.CAdES.detached' (PAdES), or to ship the placeholder separately. signerName/reason/location/contactInfo/signingTime are frozen into /Sig here — sign_pdf cannot rewrite them later. NOTE: the unsigned file is not yet a conformant PDF/A (empty /Contents); it becomes one once signed. PDF/A, print, metadata and creationDate options as on every document tool.
| Name | Required | Description | Default |
|---|---|---|---|
| pdfA | No | PDF/A level: pdfa1b (simple text+images), pdfa2b/pdfa2u (richer; 2u = Unicode mapping), pdfa3b (attachments / Factur-X). Pair with embedFonts=true for a valid claim. Exclusive with encryption. See docs/guides/PDFA.md. The unsigned placeholder is NOT yet conformant (empty /Contents, ISO 19005-2 §6.4.3); it is once signed with sign_pdf profile:'pades'. | |
| debug | No | Draw margin / block / cell guide rectangles (unmarked content — not for PDF/UA output). Geometry unchanged. Default false. | |
| No | Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b), `spotColours` ink declarations. See docs/guides/PRINT.md. | ||
| title | Yes | Document title. Used as the PDF metadata title and rendered at the top of page 1. | |
| blocks | No | Optional document body blocks rendered before the signature field. | |
| reason | No | Reason for signing (e.g. "Approved", "I agree to the terms"). | |
| strict | No | Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other (TYPOGRAPHY_FEATURE_INEFFECTIVE, TEXT_GLYPH_NOT_COVERED — a character no font covers, drawn as a box or '?') → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true. | |
| margins | No | Margins in points, all four required (0–200). Default 45 / 36 / 35 / 36. | |
| compress | No | FlateDecode the streams (smaller file, different bytes; PDF/A unaffected, XMP stays plain). Default false. | |
| location | No | Signing location (city / country). | |
| metadata | No | /Info (+ XMP under PDF/A): author, subject, keywords, /Trapped. | |
| pageSize | No | Portrait page preset (points): A4 595.28×841.89 (default), Letter 612×792, Legal 612×1008, A3 841.89×1190.55, Tabloid 792×1224. print.* boxes must fit it. | |
| direction | No | Base text direction (UAX #9): 'auto' reads each paragraph's first strong character and right-aligns RTL ones; 'ltr' / 'rtl' force it. A paragraph's own direction overrides it. Omitted = LTR (1.7.0 bytes). | |
| fieldName | No | Optional AcroForm field name for the signature widget (default 'Signature1'). | |
| pageIndex | No | Zero-based page index the (invisible) widget attaches to (default 0). | |
| subFilter | No | Signature SubFilter baked into the /Sig dictionary (frozen at placeholder time). Use 'ETSI.CAdES.detached' for PAdES baseline signatures (sign_pdf profile='pades'). Default 'adbe.pkcs7.detached'. | |
| actualText | No | Untagged output: wrap reordered shaped runs and RTL runs in /ActualText so extract_text returns reading order. Default true; false = bare 1.7.0 glyph runs. No effect on tagged (pdfA) output. | |
| embedFonts | No | Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A or PDF/X claim (every font embedded) and for strict=true; adds ~0.3 MiB. | |
| outputMode | No | Either 'base64' (returns the PDF inline) or 'file' (writes to a sandboxed path inside PDFNATIVE_MCP_OUTPUT_DIR). | base64 |
| outputPath | No | Required when outputMode='file'. Relative path inside the sandbox; must end with .pdf. | |
| signerName | No | Name of the intended signer, embedded in the /Sig dictionary. | |
| typography | No | Fine typography, all opt-in (omitted = unchanged bytes). kerning and fontFeatures need embedFonts:true ('fr' works on base-14 too). No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt. | |
| contactInfo | No | Contact information for the signer. | |
| signingTime | No | /Sig /M — the claimed signing instant (ISO-8601), frozen into the placeholder dictionary. Omitted: the wall clock at placeholder time. Pin it (with creationDate) for byte-identical output across calls. | |
| creationDate | No | ISO-8601 instant for /CreationDate (+ XMP, the trailer /ID and the {date} placeholder), written in UTC. Pin it for byte-identical output across calls and hosts; omitted = wall clock, so every call differs. | |
| outputIntent | No | Custom OutputIntent (under pdfA or pdfx): an RGB, CMYK or Gray ICC profile + condition strings, replacing the built-in sRGB intent. The profile must be a real ICC file ('acsp' signature, consistent size — PRINT_ERROR otherwise); pdfx needs device class 'prtr'. Under a CMYK / Gray intent RGB content is mapped through a calibrated default space. | |
| footerTemplate | No | Running footer on every page. Replaces the default footer: footerText is then ignored and page numbers appear only via {page}/{pages}. | |
| headerTemplate | No | Running header on every page (left / center / right zones); reserves 15 pt. | |
| placeholderBytes | No | Reserved bytes for the future CMS /Contents blob (default 16384; 24576 when reserveTimestamp=true). Increase only for >4096-bit RSA, long chains or large TSA tokens. | |
| reserveTimestamp | No | Reserve room for an RFC 3161 signature timestamp (sign_pdf timestamp=true): adds 8 KiB to the default placeholder size. Ignored when placeholderBytes is set explicitly. | |
| includeDiagnostics | No | Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*, TEXT_GLYPH_NOT_COVERED) as `diagnostics[]` (possibly empty). |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded. |
| mode | Yes | |
| summary | No | Tool-specific summary, when produced. |
| filePath | No | Sandboxed absolute path (file mode). |
| sizeBytes | Yes | |
| diagnostics | No | Engine diagnostics (when includeDiagnostics=true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint=false, idempotentHint=true), the description discloses the critical irreversible behavior: signerName/reason/location/contactInfo/signingTime are frozen into /Sig here and "sign_pdf cannot rewrite them later." It also warns that the unsigned output is not yet conformant PDF/A because of the empty /Contents — a behavioral caveat no annotation or schema field conveys.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is front-loaded with the optionality and the sibling relationship, and every clause carries distinct information. It is dense and parenthetical-heavy in the middle, but nothing is genuinely redundant; it is one long chain rather than a fully structured breakdown.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 31-parameter tool with full schema coverage and an output schema, the description covers the two-step workflow, the irreversible field-freezing, the PDF/A non-conformance window, and defers common document options to a shared reference. The only omission is any hint about outputMode defaults or payload size, which the schema itself handles.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema description coverage the baseline is 3, but the description adds intent-level mapping the schema does not: placeholderBytes for >4096-bit keys, reserveTimestamp for an RFC 3161 token, pageIndex for widget pinning, and subFilter 'ETSI.CAdES.detached' for PAdES. It also points to the shared PDF/A, print, metadata and creationDate options rather than restating them.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first clause gives a specific verb and resource — "New PDF carrying an unsigned /Sig placeholder" — and immediately positions it relative to the sibling that consumes it ("for a LATER sign_pdf call"). An agent can distinguish it from sign_pdf, generate_basic_pdf and add_form without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states the default path first ("OPTIONAL — sign_pdf auto-injects one") and then enumerates the concrete conditions that justify calling it: sizing the placeholder, pinning the widget page, choosing PAdES subFilter, or shipping the placeholder separately. This is explicit when-to-use and when-not guidance with the alternative named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_form_fieldsRead AcroForm fieldsARead-onlyIdempotent
Read-only list of an existing PDF's AcroForm fields: fully-qualified name, type (text | checkbox | radio | dropdown | listbox | button | signature | unknown), value, flags (readOnly / required / multiline), options, widget placements. Call it BEFORE fill_form to learn the names. Encrypted sources: password. Token-frugal: verbosity:'summary' → { fieldCount }.
| Name | Required | Description | Default |
|---|---|---|---|
| fields | No | Optional dot-path projection applied to the structured result (e.g. ['fields.name','fields.type']). Composes after verbosity. Unknown paths are omitted. | |
| password | No | Password (user or owner) of an encrypted source. Never logged or echoed. | |
| pdfBase64 | Yes | Base64-encoded PDF bytes whose AcroForm fields should be enumerated. | |
| verbosity | No | Response verbosity. 'full' (default) returns the fields[] array; 'summary' returns a token-frugal { fieldCount } and drops the array. | full |
Output Schema
| Name | Required | Description |
|---|---|---|
| fields | No | |
| fieldCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark it as read-only and idempotent, and the description adds useful behavior details: password handling for encrypted PDFs and a token-frugal 'summary' response mode that returns only fieldCount. It does not disclose every edge case, but the core behavioral traits are well covered by the annotations and description together.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded, and every sentence earns a place. The long first sentence packs critical output attributes efficiently, followed by short, actionable notes about fill_form, password, and verbosity. There is no excess filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the annotations, the rich parameter schema, and the presence of an output schema, the description covers the remaining necessary context. It tells the agent when to call it, how to handle encrypted files, and how to customise response size, which is complete for a read-only enumeration tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All four parameters already have thorough schema descriptions, so the baseline is met regardless. The description briefly mentions password and verbosity behavior, but those details are largely restating what is already in the schema. It adds little beyond what the input schema conveys.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a read-only list of AcroForm fields and enumerates what is returned: name, type, value, flags, options, and widget placements. It also ties the operation to the sibling fill_form tool, so its role in the workflow is unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Call it BEFORE fill_form to learn the names,' giving the agent a concrete, actionable use case and emphasizing that this tool is a prerequisite for fill_form. It does not mention when not to use it or provide other alternative tools, so it lacks full exclusionary guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sign_pdfSign PDF (RSA / ECDSA, PAdES)A
CMS / PAdES signature in ONE call: a missing /Sig placeholder is auto-injected (prepare_signature_placeholder is optional). Inputs: pdfBase64, algorithm (rsa-sha256/384/512, ecdsa-sha256 P-256), certDerBase64 (+ certChainDerBase64 intermediates) and the DER key (rsaKeyPkcs1DerBase64 for rsa-*, ecPrivateKeyDerBase64 or ecPrivateScalarHex for ECDSA; PEM is rejected with the openssl remedy). profile:'pades' (ETSI EN 319 142-1 baseline) is the right choice when add_ltv / timestamp_pdf follow; timestamp:true = PAdES B-T through the operator TSA (TSA_NOT_CONFIGURED otherwise, no network without it). signerName/reason/location/contactInfo/signingTime are baked into the placeholder THIS call injects (a pre-built placeholder keeps its own). Several unsigned placeholders → pass fieldName (PLACEHOLDER_AMBIGUOUS); allowMultiple:true + a new fieldName adds a further signature. Verify with verify_pdf.
| Name | Required | Description | Default |
|---|---|---|---|
| reason | No | /Sig /Reason — baked into the placeholder when this call injects it. | |
| profile | No | 'pkcs7' (default, adbe.pkcs7.detached) or 'pades' (ETSI EN 319 142-1 baseline; ETSI.CAdES.detached when the placeholder is injected here). Use 'pades' before timestamp / add_ltv / timestamp_pdf. | pkcs7 |
| location | No | /Sig /Location — baked into the placeholder when this call injects it. | |
| algorithm | Yes | Signature algorithm. 'rsa-sha384' / 'rsa-sha512' (pdfnative 1.7) upgrade the whole CMS digest chain. ECDSA only supports P-256 with SHA-256. | |
| fieldName | No | Name of the signature field to sign (required when several unsigned placeholders exist) and of the placeholder injected by this call. | |
| pdfBase64 | Yes | Base64-encoded PDF bytes. When the PDF already contains an unsigned /Sig placeholder it is signed in place; otherwise the placeholder is auto-injected (set autoInjectPlaceholder=false to opt out). | |
| timestamp | No | PAdES B-T: request an RFC 3161 signature timestamp from the operator-configured TSA (PDFNATIVE_MCP_TSA_URL). Fails with TSA_NOT_CONFIGURED when no TSA is configured — the server never contacts the network otherwise. | |
| outputMode | No | 'base64' (default) returns the PDF inline; 'file' writes it inside the PDFNATIVE_MCP_OUTPUT_DIR sandbox (SECURITY_VIOLATION when the sandbox is not configured). | base64 |
| outputPath | No | Required when outputMode='file'. Relative path inside the sandbox; must end with .pdf (no absolute paths, no '..'). | |
| signerName | No | /Sig /Name — baked into the placeholder when this call injects it. | |
| contactInfo | No | /Sig /ContactInfo — baked into the placeholder when this call injects it. | |
| signingTime | No | ISO-8601 signing instant → /Sig /M (only when THIS call injects the placeholder) and the CMS signing-time (pkcs7 profile). Default: now. Not trusted time — use timestamp:true for that. | |
| allowMultiple | No | Add a NEW signature next to existing (already signed) fields instead of signing the first placeholder. Requires fieldName. Each signature is an incremental revision; earlier signatures stay valid. | |
| certDerBase64 | Yes | Base64 of the signer X.509 certificate in DER form. Convert from PEM with: openssl x509 -in cert.pem -outform DER | openssl base64 -A | |
| certChainDerBase64 | No | Optional intermediate CA certificates (DER base64) embedded in the CMS so verifiers and add_ltv can build the chain without fetching caIssuers. | |
| ecPrivateScalarHex | No | Hex-encoded P-256 private scalar `d` (exactly 64 lowercase or uppercase hex chars, no 0x prefix). Mutually exclusive with ecPrivateKeyDerBase64; either is accepted for ECDSA. | |
| rsaKeyPkcs1DerBase64 | No | Base64 of the RSA private key in DER form — PKCS#1 RSAPrivateKey (openssl rsa -in key.pem -outform DER -traditional | openssl base64 -A) or PKCS#8 PrivateKeyInfo (openssl pkey -in key.pem -outform DER | openssl base64 -A). NOT PEM. Required for the rsa-* algorithms. | |
| autoInjectPlaceholder | No | When true (default) and the input PDF has no /Sig widget, pdfnative.addSignaturePlaceholder is called before signing — enabling single-call signing of any PDF. | |
| ecPrivateKeyDerBase64 | No | Base64 of an ECDSA P-256 private key in SEC1 (RFC 5915) or PKCS#8 (RFC 5208) DER form. Convert from PEM with: openssl pkey -in key.pem -outform DER | openssl base64 -A Mutually exclusive with ecPrivateScalarHex. |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded. |
| mode | Yes | |
| summary | No | Tool-specific summary, when produced. |
| filePath | No | Sandboxed absolute path (file mode). |
| sizeBytes | Yes | |
| diagnostics | No | Engine diagnostics (when includeDiagnostics=true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag a non-read-only, non-idempotent, open-world write, and the description adds genuinely useful context beyond them: TSA_NOT_CONFIGURED when no TSA is set, 'the server never contacts the network otherwise' (narrowing the open-world scope), PEM rejection with an openssl remedy, and that earlier signatures survive as incremental revisions. It does not, however, discuss permission/auth requirements for the private key material or what happens to the input PDF on failure. Solid but not exhaustive for a signing operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the single most important fact ('ONE call', auto-injection) and then packed with actionable detail justified by a 19-parameter tool. It is dense to the point of being a wall of parentheticals and semicolons, and the PEM rejection is stated twice (description and schema), which costs a little readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex crypto tool it covers the full call path: key material formats, placeholder injection vs. reuse, profile choice for downstream LTV/timestamp steps, failure modes, and the verify_pdf handoff. An output schema exists, so return-value explanation is correctly omitted.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 19 parameters thoroughly, making 3 the baseline. The description adds a decision-level mapping (rsaKeyPkcs1DerBase64 for rsa-*, ec* variants for ECDSA) and reinforces the PEM rejection, but most of that is already in the schema text, so the added value is marginal rather than transformative.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (CMS/PAdES signature) and its key scope claim ('in ONE call'), then immediately positions prepare_signature_placeholder as optional and names verify_pdf as the follow-up. An agent can distinguish it from the sibling placeholder and verification tools without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit routing rules: use profile:'pades' when add_ltv / timestamp_pdf follow, pass fieldName when several unsigned placeholders exist (with the PLACEHOLDER_AMBIGUOUS condition), and use allowMultiple + a new fieldName for an additional signature. It also names the alternative workflow (prepare_signature_placeholder) and states when it can be skipped.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
split_pdfSplit PDF into rangesAIdempotent
Split one PDF into several documents, one per ranges[] entry ({ start, end? }, 0-based inclusive; end defaults to start). Multi-output result: base64 mode returns one embedded resource per part; file mode writes indexed siblings ('out.pdf' → 'out-1.pdf', 'out-2.pdf', …). Same page-tree caveats as merge_pdfs (signatures/AcroForm/XMP dropped; boxes kept). Encrypted sources: password. Need ONE document from a page subset? Use extract_pages.
| Name | Required | Description | Default |
|---|---|---|---|
| ranges | Yes | Page ranges to extract, one output PDF per range. 0-based, inclusive; `end` defaults to `start` (a single page). | |
| encrypt | No | Re-encrypt the output (Standard Security Handler; AES-128 default or AES-256; RC4 never emitted). Applied to every produced range. | |
| password | No | Password (user or owner) of an encrypted source. Never logged or echoed. | |
| pdfBase64 | Yes | Base64-encoded source PDF. Pass `password` for an encrypted source. | |
| outputMode | No | 'base64' (default) returns the PDF inline; 'file' writes it inside the PDFNATIVE_MCP_OUTPUT_DIR sandbox (SECURITY_VIOLATION when the sandbox is not configured). | base64 |
| outputPath | No | Base output path (file mode). Each PDF is written to an indexed sibling: 'out.pdf' → 'out-1.pdf', 'out-2.pdf', … | |
| dropAnnotations | No | When true, drop ALL annotations. Default keeps self-contained URI link annotations. | |
| maxOutputSizeBytes | No | Maximum size, in bytes, of each produced PDF. Defaults to 268435456 (256 MiB). |
Output Schema
| Name | Required | Description |
|---|---|---|
| mode | Yes | |
| count | Yes | |
| parts | Yes | |
| totalBytes | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations' safety and idempotency signals, the description discloses multi-output behavior, base64 resource handling, indexed file naming, and encrypted-source support. Crucially, it warns that signatures, AcroForm data, and XMP are dropped while boxes are retained.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but efficient, front-loading the core operation and then covering outputs, preservation caveats, encryption, and sibling routing. Every sentence provides actionable information without filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex multi-output transformation, it supplies the essential operational behavior, important output-side data-loss caveats, and guidance for encrypted inputs and alternative tool selection. The fully documented input schema and presence of an output schema adequately cover the remaining details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description usefully consolidates range indexing, end defaults, password usage, and output naming, but these details are already documented in the schema rather than adding substantial new parameter-specific meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence precisely states the operation and scope: splitting one PDF into multiple documents, with one output per ranges[] entry. It also distinguishes the tool from extract_pages, which produces one document from a page subset.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The closing sentence gives an explicit selection rule and alternative: use extract_pages when only one document is needed from a page subset. This directly addresses the most likely sibling-tool confusion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
timestamp_pdfAdd a document timestamp (PAdES B-LTA)A
PAdES B-LTA: append an RFC 3161 document timestamp (/DocTimeStamp, ETSI.RFC3161) over the whole document. Ladder step 4 after add_ltv; re-run before the TSA certificate expires. fieldName omitted → DocTimeStamp1, 2, …; a fieldName colliding with a signed field fails. Uses the OPERATOR TSA (PDFNATIVE_MCP_TSA_URL; TSA_NOT_CONFIGURED otherwise, no network without it). The token's status, imprint and nonce are checked before embedding (its own signature is verified by verify_pdf). Unencrypted PDFs only.
| Name | Required | Description | Default |
|---|---|---|---|
| fieldName | No | Signature field name for the timestamp. Omit it to get 'DocTimeStamp1', 'DocTimeStamp2', … auto-suffixed on each re-timestamp; an explicit name that collides with an existing signed field fails. | |
| pdfBase64 | Yes | Base64-encoded PDF (unencrypted). Typically already signed (+ add_ltv) — a document timestamp on an unsigned PDF is allowed but proves only existence at that time. | |
| outputMode | No | 'base64' (default) returns the PDF inline; 'file' writes it inside the PDFNATIVE_MCP_OUTPUT_DIR sandbox (SECURITY_VIOLATION when the sandbox is not configured). | base64 |
| outputPath | No | Relative path inside PDFNATIVE_MCP_OUTPUT_DIR (required when outputMode='file'). | |
| placeholderBytes | No | Room reserved for the TimeStampToken (default 12288). Raise it for TSAs that return large certificate chains. |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded. |
| mode | Yes | |
| summary | No | Tool-specific summary, when produced. |
| filePath | No | Sandboxed absolute path (file mode). |
| sizeBytes | Yes | |
| diagnostics | No | Engine diagnostics (when includeDiagnostics=true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial context beyond the annotations: dependence on the OPERATOR TSA via PDFNATIVE_MCP_TSA_URL, the TSA_NOT_CONFIGURED failure and 'no network without it' (explaining openWorldHint), pre-embedding validation of token status, imprint and nonce, delegation of signature verification to verify_pdf, and the collision-with-signed-field failure. These are real operational traits the annotations alone cannot convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Tight and front-loaded: format, ladder position, naming rule, TSA dependency, validation, and constraint in that order, with no filler. The semicolon-chained telegraphic style is dense but each clause carries distinct information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description need not explain returns, and it covers everything else an agent needs: prerequisite step, repeat cadence, TSA configuration source, pre-embedding checks, naming behavior, and the encryption constraint. Nothing material to correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline applies. The description largely restates the schema for fieldName (auto-suffix naming, signed-field collision) rather than adding meaning, and says nothing about placeholderBytes sizing or outputMode/outputPath interactions, so it does not exceed what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('append an RFC 3161 document timestamp (/DocTimeStamp, ETSI.RFC3161) over the whole document') and names the exact ladder position relative to a sibling ('Ladder step 4 after add_ltv'). An agent can distinguish this from add_ltv, sign_pdf and verify_pdf without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear ordering and lifecycle guidance ('step 4 after add_ltv; re-run before the TSA certificate expires') and a hard precondition ('Unencrypted PDFs only'). It stops short of naming the alternatives it should not be used in place of (sign_pdf for a first signature) or what to do when a timestamp is not required, so it is strong but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_metadataUpdate document metadataA
Rewrite /Info (title, author, subject, keywords) of an EXISTING PDF as an incremental update; XMP stays in sync on PDF/A documents; /ModDate is refreshed (pin modDate for reproducible bytes). Earlier revisions and signatures stay byte-identical — the new revision is unsigned (sign_pdf / timestamp_pdf again if needed). Encrypted sources → ENCRYPTED_SOURCE. For metadata at generation time use the metadata option of the document tools.
| Name | Required | Description | Default |
|---|---|---|---|
| title | No | New /Info /Title (mirrored to XMP dc:title when the document carries XMP). | |
| author | No | New /Info /Author (XMP dc:creator). | |
| modDate | No | ISO-8601 modification instant for /ModDate and xmp:ModifyDate. Defaults to now; pin it for reproducible output. | |
| subject | No | New /Info /Subject (XMP dc:description). | |
| keywords | No | New /Info /Keywords (XMP pdf:Keywords). | |
| pdfBase64 | Yes | Base64-encoded PDF to update (unencrypted). | |
| outputMode | No | 'base64' (default) returns the PDF inline; 'file' writes it inside the PDFNATIVE_MCP_OUTPUT_DIR sandbox (SECURITY_VIOLATION when the sandbox is not configured). | base64 |
| outputPath | No | Relative path inside PDFNATIVE_MCP_OUTPUT_DIR (required when outputMode='file'). |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded. |
| mode | Yes | |
| summary | No | Tool-specific summary, when produced. |
| filePath | No | Sandboxed absolute path (file mode). |
| sizeBytes | Yes | |
| diagnostics | No | Engine diagnostics (when includeDiagnostics=true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, it discloses incremental-update semantics, preservation of earlier revisions and signatures, the unsigned status of the new revision, PDF/A XMP synchronization, ModDate refresh behavior, and the ENCRYPTED_SOURCE failure. These details directly affect reproducibility, safety expectations, and post-call workflows.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but efficient, with the core operation front-loaded and constraints, consequences, and alternatives compressed into clear clauses. There is no filler, and each statement provides actionable information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an eight-parameter mutation with complete input and output schemas, this supplies the important operational context: input restrictions, revision and signature effects, reproducibility, failure behavior, and the generation-time alternative. Output routing and sandbox requirements are already covered by the schema, so their absence from the description is not a gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and the description largely restates information already present there: the metadata fields, unencrypted input, and pinning `modDate` for reproducibility. It adds little parameter-specific meaning beyond the schema, so the high-coverage baseline applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening clause precisely identifies the operation, resource, and scope: rewriting /Info fields of an existing PDF as an incremental update. It also distinguishes this from setting metadata during document generation, making selection among sibling tools straightforward.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly routes generation-time metadata to the document tools' `metadata` option and directs the agent to `sign_pdf` or `timestamp_pdf` again when needed. The existing-PDF requirement and encrypted-source error further clarify when the tool is unsuitable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_pdfValidate PDF structure (PDF/UA, PDF/X-4)ARead-onlyIdempotent
Read-only structural gate; standard picks the rule set. 'pdf-ua-1' (default, ISO 14289-1) for Tagged PDF: /MarkInfo /Marked, /StructTreeRoot (+ /ParentTree), XMP /Metadata, /Lang, per-page MCID uniqueness — generate tagged input with pdfA (e.g. 'pdfa2u') first. 'pdf-x-4' (ISO 15930-7) for print exchange: /GTS_PDFX OutputIntent with a prtr ICC profile, TrimBox or ArtBox, every font embedded, no annotation / JavaScript / embedded file / transfer function — generate it with pdfx:'pdfx4'. Result { standard, valid, errors[], warnings[], summary } (+ caveats[] for PDF/X). Fast and structural only — NOT a reference validator or a certified preflight: fonts, colour and rendering are not checked (veraPDF for PDF/A and PDF/UA; callas pdfToolbox or Acrobat Preflight for PDF/X). Unparsable input → PDF_PARSE_FAILED.
| Name | Required | Description | Default |
|---|---|---|---|
| fields | No | Optional dot-path projection applied to the structured result (e.g. ['valid']). Composes after verbosity. Unknown paths are omitted. | |
| standard | No | Rule set. 'pdf-ua-1' (default): PDF/UA accessibility structure (ISO 14289-1). 'pdf-x-4': PDF/X-4 print exchange (ISO 15930-7) — OutputIntent + prtr ICC profile, TrimBox, embedded fonts, no annotations / JavaScript / embedded files; structural prerequisites only, not a certified preflight (see caveats[]). | pdf-ua-1 |
| pdfBase64 | Yes | Base64-encoded PDF bytes to validate for structural conformance. | |
| verbosity | No | Response verbosity. 'full' (default) returns errors[] and warnings[]; 'summary' returns a token-frugal verdict { standard, valid, errorCount, warningCount, summary } and drops the message arrays. | full |
Output Schema
| Name | Required | Description |
|---|---|---|
| valid | No | True when no blocking structural violations were found. |
| errors | No | Blocking conformance violations. Empty when valid is true. |
| caveats | No | standard 'pdf-x-4' only: what a valid verdict does NOT establish. |
| summary | No | Human-readable one-line summary of the result. |
| standard | No | Conformance standard checked (ISO 14289-1 or ISO 15930-7). |
| warnings | No | Non-blocking best-practice recommendations. |
| errorCount | No | summary only: number of errors. |
| warningCount | No | summary only: number of warnings. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only/idempotent/non-destructive, but the description adds substantial behavior beyond them: what is deliberately not checked (fonts, colour, rendering), the caveats[] return for PDF/X, and the concrete failure mode 'PDF_PARSE_FAILED' for unparsable input.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but front-loaded: the core role and the standard switch come first, followed by per-standard detail, result shape, and limitations. Every clause carries information, though the single block is heavy enough that some trimming or line breaks would improve scanability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema exists, the description need not explain returns, yet it still summarizes the result shape and caveats[]. Combined with coverage of both standards, generation prerequisites, limitations, and the parse-failure code, an agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description still adds value by spelling out the ISO numbers and the exact rule contents behind each 'standard' enum value, plus the default. It does not add much beyond the schema for 'fields' or 'verbosity', keeping it at a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ('structural gate') and enumerates exactly what each standard validates (PDF/UA tags, PDF/X-4 OutputIntent/fonts/annotations). It is clearly distinguishable from siblings like inspect_pdf or verify_pdf, which are not described in these structural-conformance terms.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States when to pick each standard, that input should be generated first with the pdfA/pdfx tools (e.g. 'pdfa2u', 'pdfx4'), and explicitly routes agents needing deeper validation to veraPDF/callas/Acrobat. It also bounds scope with 'NOT a reference validator or a certified preflight'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
verify_pdfVerify PDF signaturesARead-onlyIdempotent
Read-only verification of every signature: ByteRange digest vs CMS messageDigest (integrity), CMS signatureValue vs the embedded signer certificate (RSA-SHA256/384/512, ECDSA P-256), chain trust when trustedRootsDerBase64 is given ('self-signed' | 'unverified' | 'trusted' otherwise). /DocTimeStamp entries are verified as RFC 3161 tokens and count in allValid like any signature. Result: { allValid, signatureCount, summary, signatures:[{ valid, integrity, signerSubject, signingTime, chainTrust, errors[] }] }. ltv:true adds the PAdES view: per-signature profile, timestamp, revocation (read from embedded /DSS only — responder signatures are not re-verified) and ltvLevel B-B / B-T / B-LT / B-LTA with explicit caveats. Token-frugal: verbosity:'summary', fields:['allValid'].
| Name | Required | Description | Default |
|---|---|---|---|
| ltv | No | Add the PAdES view: per signature profile, timestamp, revocation (embedded /DSS only), ltvLevel (B-B / B-T / B-LT / B-LTA); document-level dss, ltvLevel, caveats. | |
| fields | No | Optional dot-path projection applied to the structured result (e.g. ['allValid'] or ['signatures.valid']). Composes after verbosity. Unknown paths are omitted. | |
| password | No | Password (user or owner) of an encrypted source. Never logged or echoed. | |
| pdfBase64 | Yes | Base64-encoded PDF bytes to verify. | |
| verbosity | No | Response verbosity. 'full' (default) returns the per-signature signatures[] array; 'summary' returns a token-frugal verdict { signatureCount, allValid, invalid, summary } (+ ltvLevel when ltv:true) and drops signatures[], dss and caveats. | full |
| trustedRootsDerBase64 | No | Optional list of base64-encoded X.509 root certificates (DER). When supplied, each signer certificate is validated against these roots; otherwise chainTrust is reported as self-signed or unverified. |
Output Schema
| Name | Required | Description |
|---|---|---|
| dss | No | ltv only. Document Security Store summary, or null when the catalog has no /DSS. |
| caveats | No | ltv only. Fixed statements about what the LTV evaluation does not cover. |
| invalid | No | summary only: number of invalid signatures. |
| summary | No | |
| allValid | No | true when the document carries at least one signature and every entry of signatures[] — CMS signatures and /DocTimeStamp tokens alike — is valid (integrity + signature check + chain trust when trustedRootsDerBase64 is given). A tampered document timestamp fails the verdict; a sound one never does. |
| ltvLevel | No | ltv only. Minimum level across non-timestamp signatures ('B-B' when there are none). |
| signatures | No | |
| signatureCount | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond the readOnlyHint and idempotentHint annotations by explaining exactly what is verified, how chainTrust is determined, how /DocTimeStamp is treated, and what ltv:true does. It also includes important caveats such as embedded /DSS-only revocation data and the fact that responder signatures are not re-verified. This gives the agent a strong model of the tool's behavior before invoking it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well structured, front-loading the core verification purpose and then layering optional modes. Every sentence adds meaningful information, and the structured result shape and token-frugal guidance are presented in compact, scannable form.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, the input schema, annotations, and output schema, the description covers the essential semantic, behavioral, and output-critical details. It explains verification scope, trust behavior, timestamp handling, LTV caveats, and result shapes well enough for an agent to decide whether to call it and what to expect.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents all six parameters with high coverage, so the baseline is solid. The description adds genuine semantic value by explaining the effect of trustedRootsDerBase64, the LTV behavior tied to ltv:true, and the token-frugal interaction between verbosity and fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a precise operation: read-only verification of every PDF signature, including integrity, signature value, chain trust, timestamps, and PAdES LTV behavior. It clearly distinguishes the tool's scope from generic PDF validation by enumerating specific verification mechanics and output fields.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description makes the tool's purpose and behavior easy to infer: it is for signature-specific verification, with optional LTV analysis. However, it does not explicitly tell the agent when to choose verify_pdf over sibling tools like validate_pdf or inspect_pdf, nor does it state any exclusions. Usage context is implied rather than directly described.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
23 tool updates
v1.8.0- Changed
add_attachment12 fields changed- added
Input schema / properties / actualTextAdded value: +{ + "description": "Untagged output: wrap reordered shaped runs and RTL runs in /ActualText so extract_text returns reading order. Default true; false = bare 1.7.0 glyph runs. No effect on tagged (pdfA) output.", + "type": "boolean" +} - added
Input schema / properties / directionAdded value: +{ + "description": "Base text direction (UAX #9): 'auto' reads each paragraph's first strong character and right-aligns RTL ones; 'ltr' / 'rtl' force it. A paragraph's own direction overrides it. Omitted = LTR (1.7.0 bytes).", + "enum": [ + "auto", + "ltr", + "rtl" + ], + "type": "string" +} - changed
Input schema / properties / footerTemplate / properties / color / anyOfPrevious value: -[ - { - "pattern": "^#[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - changed
Input schema / properties / headerTemplate / properties / color / anyOfPrevious value: -[ - { - "pattern": "^#[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - changed
Input schema / properties / includeDiagnostics / descriptionPrevious value: -"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*) as `diagnostics[]` (possibly empty)."New value: +"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*, TEXT_GLYPH_NOT_COVERED) as `diagnostics[]` (possibly empty)." - changed
Input schema / properties / print / descriptionPrevious value: -"Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b). See docs/guides/PRINT.md."New value: +"Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b), `spotColours` ink declarations. See docs/guides/PRINT.md." - added
Input schema / properties / print / properties / spotColoursAdded value: +{ + "description": "Spot inks (/Separation plates) the document may paint with { spot:'name', tint } or { inks:{ name: tint } } anywhere a colour is accepted. Undeclared ink → VALIDATION_ERROR; blank or duplicate name → PRINT_ERROR (an empty string is VALIDATION_ERROR).", + "items": { + "additionalProperties": false, + "properties": { + "alternate": { + "anyOf": [ + { + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "items": { + "maximum": 255, + "minimum": 0, + "type": "number" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" + } + ], + "description": "Process alternate for proofing: [c, m, y, k] 0–100 or [r, g, b] 0–255." + }, + "name": { + "description": "'PANTONE 300 C', 'Varnish', …", + "maxLength": 100, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "name", + "alternate" + ], + "type": "object" + }, + "maxItems": 32, + "minItems": 1, + "type": "array" +} - changed
Input schema / properties / strict / descriptionPrevious value: -"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true."New value: +"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other (TYPOGRAPHY_FEATURE_INEFFECTIVE, TEXT_GLYPH_NOT_COVERED — a character no font covers, drawn as a box or '?') → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true." - changed
Input schema / properties / typography / descriptionPrevious value: -"Fine typography, all opt-in (omitted = unchanged bytes). kerning, fontFeatures and the 'fr' narrow space need embedFonts:true. No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt."New value: +"Fine typography, all opt-in (omitted = unchanged bytes). kerning and fontFeatures need embedFonts:true ('fr' works on base-14 too). No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt." - changed
Input schema / properties / typography / properties / punctuationSpacing / anyOfPrevious value: -[ - { - "enum": [ - "fr", - "fr-CA" - ], - "type": "string" - }, - { - "items": { - "additionalProperties": false, - "properties": { - "char": { - "maxLength": 2, - "minLength": 1, - "type": "string" - }, - "side": { - "enum": [ - "before", - "after" - ], - "type": "string" - }, - "space": { - "description": "U+00A0 / U+202F (narrow needs embedFonts).", - "enum": [ - "nbsp", - "narrow" - ], - "type": "string" - } - }, - "required": [ - "char", - "side", - "space" - ], - "type": "object" - }, - "maxItems": 32, - "type": "array" - } -]New value: +[ + { + "enum": [ + "fr", + "fr-CA" + ], + "type": "string" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "char": { + "maxLength": 2, + "minLength": 1, + "type": "string" + }, + "side": { + "enum": [ + "before", + "after" + ], + "type": "string" + }, + "space": { + "description": "U+00A0 / U+202F (narrow: a TJ adjustment on base-14, the glyph on an embedded font).", + "enum": [ + "nbsp", + "narrow" + ], + "type": "string" + } + }, + "required": [ + "char", + "side", + "space" + ], + "type": "object" + }, + "maxItems": 32, + "type": "array" + } +] - changed
Output schema / descriptionPrevious value: -"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath` (and `url` when the operator maps the sandbox to a public base URL)." - added
Output schema / properties / urlAdded value: +{ + "description": "Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded.", + "type": "string" +}
- Changed
add_barcode13 fields changed- added
Input schema / properties / actualTextAdded value: +{ + "description": "Untagged output: wrap reordered shaped runs and RTL runs in /ActualText so extract_text returns reading order. Default true; false = bare 1.7.0 glyph runs. No effect on tagged (pdfA) output.", + "type": "boolean" +} - added
Input schema / properties / directionAdded value: +{ + "description": "Base text direction (UAX #9): 'auto' reads each paragraph's first strong character and right-aligns RTL ones; 'ltr' / 'rtl' force it. A paragraph's own direction overrides it. Omitted = LTR (1.7.0 bytes).", + "enum": [ + "auto", + "ltr", + "rtl" + ], + "type": "string" +} - changed
Input schema / properties / footerTemplate / properties / color / anyOfPrevious value: -[ - { - "pattern": "^#[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - changed
Input schema / properties / headerTemplate / properties / color / anyOfPrevious value: -[ - { - "pattern": "^#[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - changed
Input schema / properties / includeDiagnostics / descriptionPrevious value: -"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*) as `diagnostics[]` (possibly empty)."New value: +"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*, TEXT_GLYPH_NOT_COVERED) as `diagnostics[]` (possibly empty)." - changed
Input schema / properties / pdfx / descriptionPrevious value: -"PDF/X-4 print exchange (ISO 15930-7). REQUIRES outputIntent with the printer's ICC profile (device class 'prtr'; CMYK or Gray — none is bundled); needs embedFonts:true for a conformant file (PDFX_NO_FONT_ENTRIES otherwise, strict:true refuses). Exclusive with pdfA and encrypt; metadata.trapped must be 'True' or 'False'; TrimBox or ArtBox, not both. Links and form fields are reported (PDFX_ANNOTATIONS). Check with validate_pdf standard:'pdf-x-4'. See the print_ready prompt."New value: +"PDF/X-4 print exchange (ISO 15930-7). REQUIRES outputIntent with the printer's ICC profile (device class 'prtr'; CMYK or Gray — none is bundled); needs embedFonts:true for a conformant file (PDFX_NO_FONT_ENTRIES otherwise, strict:true refuses). Combines with pdfA:'pdfa2b' | 'pdfa2u' (dual claim) but not pdfa1b / pdfa3b; exclusive with encrypt; metadata.trapped must be 'True' or 'False'; TrimBox or ArtBox, not both. Links and form fields are reported (PDFX_ANNOTATIONS). Check with validate_pdf standard:'pdf-x-4'. See the print_ready prompt." - changed
Input schema / properties / print / descriptionPrevious value: -"Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b). See docs/guides/PRINT.md."New value: +"Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b), `spotColours` ink declarations. See docs/guides/PRINT.md." - added
Input schema / properties / print / properties / spotColoursAdded value: +{ + "description": "Spot inks (/Separation plates) the document may paint with { spot:'name', tint } or { inks:{ name: tint } } anywhere a colour is accepted. Undeclared ink → VALIDATION_ERROR; blank or duplicate name → PRINT_ERROR (an empty string is VALIDATION_ERROR).", + "items": { + "additionalProperties": false, + "properties": { + "alternate": { + "anyOf": [ + { + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "items": { + "maximum": 255, + "minimum": 0, + "type": "number" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" + } + ], + "description": "Process alternate for proofing: [c, m, y, k] 0–100 or [r, g, b] 0–255." + }, + "name": { + "description": "'PANTONE 300 C', 'Varnish', …", + "maxLength": 100, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "name", + "alternate" + ], + "type": "object" + }, + "maxItems": 32, + "minItems": 1, + "type": "array" +} - changed
Input schema / properties / strict / descriptionPrevious value: -"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true."New value: +"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other (TYPOGRAPHY_FEATURE_INEFFECTIVE, TEXT_GLYPH_NOT_COVERED — a character no font covers, drawn as a box or '?') → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true." - changed
Input schema / properties / typography / descriptionPrevious value: -"Fine typography, all opt-in (omitted = unchanged bytes). kerning, fontFeatures and the 'fr' narrow space need embedFonts:true. No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt."New value: +"Fine typography, all opt-in (omitted = unchanged bytes). kerning and fontFeatures need embedFonts:true ('fr' works on base-14 too). No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt." - changed
Input schema / properties / typography / properties / punctuationSpacing / anyOfPrevious value: -[ - { - "enum": [ - "fr", - "fr-CA" - ], - "type": "string" - }, - { - "items": { - "additionalProperties": false, - "properties": { - "char": { - "maxLength": 2, - "minLength": 1, - "type": "string" - }, - "side": { - "enum": [ - "before", - "after" - ], - "type": "string" - }, - "space": { - "description": "U+00A0 / U+202F (narrow needs embedFonts).", - "enum": [ - "nbsp", - "narrow" - ], - "type": "string" - } - }, - "required": [ - "char", - "side", - "space" - ], - "type": "object" - }, - "maxItems": 32, - "type": "array" - } -]New value: +[ + { + "enum": [ + "fr", + "fr-CA" + ], + "type": "string" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "char": { + "maxLength": 2, + "minLength": 1, + "type": "string" + }, + "side": { + "enum": [ + "before", + "after" + ], + "type": "string" + }, + "space": { + "description": "U+00A0 / U+202F (narrow: a TJ adjustment on base-14, the glyph on an embedded font).", + "enum": [ + "nbsp", + "narrow" + ], + "type": "string" + } + }, + "required": [ + "char", + "side", + "space" + ], + "type": "object" + }, + "maxItems": 32, + "type": "array" + } +] - changed
Output schema / descriptionPrevious value: -"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath` (and `url` when the operator maps the sandbox to a public base URL)." - added
Output schema / properties / urlAdded value: +{ + "description": "Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded.", + "type": "string" +}
- Changed
add_chart18 fields changed- added
Input schema / properties / actualTextAdded value: +{ + "description": "Untagged output: wrap reordered shaped runs and RTL runs in /ActualText so extract_text returns reading order. Default true; false = bare 1.7.0 glyph runs. No effect on tagged (pdfA) output.", + "type": "boolean" +} - changed
Input schema / properties / colors / items / anyOfPrevious value: -[ - { - "pattern": "^#?[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "pattern": "^#?[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - added
Input schema / properties / directionAdded value: +{ + "description": "Base text direction (UAX #9): 'auto' reads each paragraph's first strong character and right-aligns RTL ones; 'ltr' / 'rtl' force it. A paragraph's own direction overrides it. Omitted = LTR (1.7.0 bytes).", + "enum": [ + "auto", + "ltr", + "rtl" + ], + "type": "string" +} - changed
Input schema / properties / footerTemplate / properties / color / anyOfPrevious value: -[ - { - "pattern": "^#[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - changed
Input schema / properties / headerTemplate / properties / color / anyOfPrevious value: -[ - { - "pattern": "^#[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - changed
Input schema / properties / includeDiagnostics / descriptionPrevious value: -"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*) as `diagnostics[]` (possibly empty)."New value: +"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*, TEXT_GLYPH_NOT_COVERED) as `diagnostics[]` (possibly empty)." - changed
Input schema / properties / pdfx / descriptionPrevious value: -"PDF/X-4 print exchange (ISO 15930-7). REQUIRES outputIntent with the printer's ICC profile (device class 'prtr'; CMYK or Gray — none is bundled); needs embedFonts:true for a conformant file (PDFX_NO_FONT_ENTRIES otherwise, strict:true refuses). Exclusive with pdfA and encrypt; metadata.trapped must be 'True' or 'False'; TrimBox or ArtBox, not both. Links and form fields are reported (PDFX_ANNOTATIONS). Check with validate_pdf standard:'pdf-x-4'. See the print_ready prompt."New value: +"PDF/X-4 print exchange (ISO 15930-7). REQUIRES outputIntent with the printer's ICC profile (device class 'prtr'; CMYK or Gray — none is bundled); needs embedFonts:true for a conformant file (PDFX_NO_FONT_ENTRIES otherwise, strict:true refuses). Combines with pdfA:'pdfa2b' | 'pdfa2u' (dual claim) but not pdfa1b / pdfa3b; exclusive with encrypt; metadata.trapped must be 'True' or 'False'; TrimBox or ArtBox, not both. Links and form fields are reported (PDFX_ANNOTATIONS). Check with validate_pdf standard:'pdf-x-4'. See the print_ready prompt." - changed
Input schema / properties / print / descriptionPrevious value: -"Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b). See docs/guides/PRINT.md."New value: +"Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b), `spotColours` ink declarations. See docs/guides/PRINT.md." - added
Input schema / properties / print / properties / spotColoursAdded value: +{ + "description": "Spot inks (/Separation plates) the document may paint with { spot:'name', tint } or { inks:{ name: tint } } anywhere a colour is accepted. Undeclared ink → VALIDATION_ERROR; blank or duplicate name → PRINT_ERROR (an empty string is VALIDATION_ERROR).", + "items": { + "additionalProperties": false, + "properties": { + "alternate": { + "anyOf": [ + { + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "items": { + "maximum": 255, + "minimum": 0, + "type": "number" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" + } + ], + "description": "Process alternate for proofing: [c, m, y, k] 0–100 or [r, g, b] 0–255." + }, + "name": { + "description": "'PANTONE 300 C', 'Varnish', …", + "maxLength": 100, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "name", + "alternate" + ], + "type": "object" + }, + "maxItems": 32, + "minItems": 1, + "type": "array" +} - changed
Input schema / properties / series / items / properties / color / anyOfPrevious value: -[ - { - "pattern": "^#?[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "pattern": "^#?[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - added
Input schema / properties / series / items / properties / colorsAdded value: +{ + "description": "One colour per value, painted on bar, barH, stackedBar and stackedBarH; the length must equal values.length on every chart type (CHART_ERROR otherwise). The legend swatch keeps 'color'; line, area, scatter, pie and donut paint 'color' only.", + "items": { + "anyOf": [ + { + "pattern": "^#?[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } + ], + "description": "CSS-style hex colour, e.g. \"#3366cc\"." + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" +} - changed
Input schema / properties / series / items / properties / label / descriptionPrevious value: -"Series label (shown in the legend)."New value: +"Series label (shown in the legend). Optional since 1.8.0: an unlabelled series is listed as 'Series N'." - changed
Input schema / properties / series / items / requiredPrevious value: -[ - "label", - "values" -]New value: +[ + "values" +] - changed
Input schema / properties / strict / descriptionPrevious value: -"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true."New value: +"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other (TYPOGRAPHY_FEATURE_INEFFECTIVE, TEXT_GLYPH_NOT_COVERED — a character no font covers, drawn as a box or '?') → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true." - changed
Input schema / properties / typography / descriptionPrevious value: -"Fine typography, all opt-in (omitted = unchanged bytes). kerning, fontFeatures and the 'fr' narrow space need embedFonts:true. No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt."New value: +"Fine typography, all opt-in (omitted = unchanged bytes). kerning and fontFeatures need embedFonts:true ('fr' works on base-14 too). No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt." - changed
Input schema / properties / typography / properties / punctuationSpacing / anyOfPrevious value: -[ - { - "enum": [ - "fr", - "fr-CA" - ], - "type": "string" - }, - { - "items": { - "additionalProperties": false, - "properties": { - "char": { - "maxLength": 2, - "minLength": 1, - "type": "string" - }, - "side": { - "enum": [ - "before", - "after" - ], - "type": "string" - }, - "space": { - "description": "U+00A0 / U+202F (narrow needs embedFonts).", - "enum": [ - "nbsp", - "narrow" - ], - "type": "string" - } - }, - "required": [ - "char", - "side", - "space" - ], - "type": "object" - }, - "maxItems": 32, - "type": "array" - } -]New value: +[ + { + "enum": [ + "fr", + "fr-CA" + ], + "type": "string" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "char": { + "maxLength": 2, + "minLength": 1, + "type": "string" + }, + "side": { + "enum": [ + "before", + "after" + ], + "type": "string" + }, + "space": { + "description": "U+00A0 / U+202F (narrow: a TJ adjustment on base-14, the glyph on an embedded font).", + "enum": [ + "nbsp", + "narrow" + ], + "type": "string" + } + }, + "required": [ + "char", + "side", + "space" + ], + "type": "object" + }, + "maxItems": 32, + "type": "array" + } +] - changed
Output schema / descriptionPrevious value: -"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath` (and `url` when the operator maps the sandbox to a public base URL)." - added
Output schema / properties / urlAdded value: +{ + "description": "Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded.", + "type": "string" +}
- Changed
add_form12 fields changed- added
Input schema / properties / actualTextAdded value: +{ + "description": "Untagged output: wrap reordered shaped runs and RTL runs in /ActualText so extract_text returns reading order. Default true; false = bare 1.7.0 glyph runs. No effect on tagged (pdfA) output.", + "type": "boolean" +} - added
Input schema / properties / directionAdded value: +{ + "description": "Base text direction (UAX #9): 'auto' reads each paragraph's first strong character and right-aligns RTL ones; 'ltr' / 'rtl' force it. A paragraph's own direction overrides it. Omitted = LTR (1.7.0 bytes).", + "enum": [ + "auto", + "ltr", + "rtl" + ], + "type": "string" +} - changed
Input schema / properties / footerTemplate / properties / color / anyOfPrevious value: -[ - { - "pattern": "^#[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - changed
Input schema / properties / headerTemplate / properties / color / anyOfPrevious value: -[ - { - "pattern": "^#[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - changed
Input schema / properties / includeDiagnostics / descriptionPrevious value: -"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*) as `diagnostics[]` (possibly empty)."New value: +"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*, TEXT_GLYPH_NOT_COVERED) as `diagnostics[]` (possibly empty)." - changed
Input schema / properties / print / descriptionPrevious value: -"Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b). See docs/guides/PRINT.md."New value: +"Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b), `spotColours` ink declarations. See docs/guides/PRINT.md." - added
Input schema / properties / print / properties / spotColoursAdded value: +{ + "description": "Spot inks (/Separation plates) the document may paint with { spot:'name', tint } or { inks:{ name: tint } } anywhere a colour is accepted. Undeclared ink → VALIDATION_ERROR; blank or duplicate name → PRINT_ERROR (an empty string is VALIDATION_ERROR).", + "items": { + "additionalProperties": false, + "properties": { + "alternate": { + "anyOf": [ + { + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "items": { + "maximum": 255, + "minimum": 0, + "type": "number" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" + } + ], + "description": "Process alternate for proofing: [c, m, y, k] 0–100 or [r, g, b] 0–255." + }, + "name": { + "description": "'PANTONE 300 C', 'Varnish', …", + "maxLength": 100, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "name", + "alternate" + ], + "type": "object" + }, + "maxItems": 32, + "minItems": 1, + "type": "array" +} - changed
Input schema / properties / strict / descriptionPrevious value: -"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true."New value: +"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other (TYPOGRAPHY_FEATURE_INEFFECTIVE, TEXT_GLYPH_NOT_COVERED — a character no font covers, drawn as a box or '?') → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true." - changed
Input schema / properties / typography / descriptionPrevious value: -"Fine typography, all opt-in (omitted = unchanged bytes). kerning, fontFeatures and the 'fr' narrow space need embedFonts:true. No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt."New value: +"Fine typography, all opt-in (omitted = unchanged bytes). kerning and fontFeatures need embedFonts:true ('fr' works on base-14 too). No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt." - changed
Input schema / properties / typography / properties / punctuationSpacing / anyOfPrevious value: -[ - { - "enum": [ - "fr", - "fr-CA" - ], - "type": "string" - }, - { - "items": { - "additionalProperties": false, - "properties": { - "char": { - "maxLength": 2, - "minLength": 1, - "type": "string" - }, - "side": { - "enum": [ - "before", - "after" - ], - "type": "string" - }, - "space": { - "description": "U+00A0 / U+202F (narrow needs embedFonts).", - "enum": [ - "nbsp", - "narrow" - ], - "type": "string" - } - }, - "required": [ - "char", - "side", - "space" - ], - "type": "object" - }, - "maxItems": 32, - "type": "array" - } -]New value: +[ + { + "enum": [ + "fr", + "fr-CA" + ], + "type": "string" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "char": { + "maxLength": 2, + "minLength": 1, + "type": "string" + }, + "side": { + "enum": [ + "before", + "after" + ], + "type": "string" + }, + "space": { + "description": "U+00A0 / U+202F (narrow: a TJ adjustment on base-14, the glyph on an embedded font).", + "enum": [ + "nbsp", + "narrow" + ], + "type": "string" + } + }, + "required": [ + "char", + "side", + "space" + ], + "type": "object" + }, + "maxItems": 32, + "type": "array" + } +] - changed
Output schema / descriptionPrevious value: -"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath` (and `url` when the operator maps the sandbox to a public base URL)." - added
Output schema / properties / urlAdded value: +{ + "description": "Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded.", + "type": "string" +}
- Changed
add_international_text16 fields changed- added
Input schema / properties / actualTextAdded value: +{ + "description": "Untagged output: wrap reordered shaped runs and RTL runs in /ActualText so extract_text returns reading order. Default true; false = bare 1.7.0 glyph runs. No effect on tagged (pdfA) output.", + "type": "boolean" +} - added
Input schema / properties / directionAdded value: +{ + "description": "Base text direction (UAX #9): 'auto' reads each paragraph's first strong character and right-aligns RTL ones; 'ltr' / 'rtl' force it. A paragraph's own direction overrides it. Omitted = LTR (1.7.0 bytes).", + "enum": [ + "auto", + "ltr", + "rtl" + ], + "type": "string" +} - added
Input schema / properties / fontAdded value: +{ + "description": "Operator-registered custom font (the slug of a .ttf / .otf file in PDFNATIVE_MCP_FONT_DIR, e.g. 'brand-sans'): drawn first, with the bundled faces as fallbacks. Unknown slug → FONT_NOT_FOUND listing the registered ones; always embedded, so valid under PDF/A.", + "maxLength": 64, + "pattern": "^[a-z0-9][a-z0-9-]{0,63}$", + "type": "string" +} - changed
Input schema / properties / footerTemplate / properties / color / anyOfPrevious value: -[ - { - "pattern": "^#[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - changed
Input schema / properties / headerTemplate / properties / color / anyOfPrevious value: -[ - { - "pattern": "^#[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - changed
Input schema / properties / includeDiagnostics / descriptionPrevious value: -"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*) as `diagnostics[]` (possibly empty)."New value: +"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*, TEXT_GLYPH_NOT_COVERED) as `diagnostics[]` (possibly empty)." - changed
Input schema / properties / lang / anyOfPrevious value: -[ - { - "enum": [ - "ar", - "he", - "th", - "ja", - "zh", - "ko", - "el", - "hi", - "bn", - "ta", - "ru", - "ka", - "hy", - "tr", - "pl", - "vi", - "latin", - "te", - "si", - "bo", - "km", - "my", - "am", - "emoji", - "math", - "lo", - "nod", - "khb", - "tdd", - "cjm", - "ha", - "yo", - "ig", - "sw" - ], - "type": "string" - }, - { - "items": { - "enum": [ - "ar", - "he", - "th", - "ja", - "zh", - "ko", - "el", - "hi", - "bn", - "ta", - "ru", - "ka", - "hy", - "tr", - "pl", - "vi", - "latin", - "te", - "si", - "bo", - "km", - "my", - "am", - "emoji", - "math", - "lo", - "nod", - "khb", - "tdd", - "cjm", - "ha", - "yo", - "ig", - "sw" - ], - "type": "string" - }, - "maxItems": 34, - "minItems": 1, - "type": "array" - }, - { - "description": "Comma-separated list of supported codes.", - "maxLength": 80, - "minLength": 2, - "type": "string" - } -]New value: +[ + { + "enum": [ + "ar", + "he", + "th", + "ja", + "zh", + "ko", + "el", + "hi", + "bn", + "ta", + "ru", + "ka", + "hy", + "tr", + "pl", + "vi", + "latin", + "te", + "si", + "bo", + "km", + "my", + "am", + "gu", + "pa", + "kn", + "ml", + "or", + "emoji", + "math", + "lo", + "nod", + "khb", + "tdd", + "cjm", + "ha", + "yo", + "ig", + "sw" + ], + "type": "string" + }, + { + "items": { + "enum": [ + "ar", + "he", + "th", + "ja", + "zh", + "ko", + "el", + "hi", + "bn", + "ta", + "ru", + "ka", + "hy", + "tr", + "pl", + "vi", + "latin", + "te", + "si", + "bo", + "km", + "my", + "am", + "gu", + "pa", + "kn", + "ml", + "or", + "emoji", + "math", + "lo", + "nod", + "khb", + "tdd", + "cjm", + "ha", + "yo", + "ig", + "sw" + ], + "type": "string" + }, + "maxItems": 39, + "minItems": 1, + "type": "array" + }, + { + "description": "Comma-separated list of supported codes.", + "maxLength": 80, + "minLength": 2, + "type": "string" + } +] - changed
Input schema / properties / lang / descriptionPrevious value: -"Language / script identifier. Either a single code (e.g. 'ar'), a comma-separated list ('ar,emoji'), or an array (['ar','emoji']). Multiple codes enable multi-font run splitting (script + emoji + Latin fallback). 27 scripts; ha / yo / ig / sw (Hausa, Yoruba, Igbo, Swahili) are aliases of latin, whose combining marks are anchored."New value: +"Language / script identifier. Either a single code (e.g. 'ar'), a comma-separated list ('ar,emoji'), or an array (['ar','emoji']). Multiple codes enable multi-font run splitting (script + emoji + Latin fallback). 32 scripts (gu / pa / kn / ml / or — Gujarati, Gurmukhi, Kannada, Malayalam, Odia — since 1.8.0); ha / yo / ig / sw (Hausa, Yoruba, Igbo, Swahili) are aliases of latin, whose combining marks are anchored." - changed
Input schema / properties / pdfx / descriptionPrevious value: -"PDF/X-4 print exchange (ISO 15930-7). REQUIRES outputIntent with the printer's ICC profile (device class 'prtr'; CMYK or Gray — none is bundled); needs embedFonts:true for a conformant file (PDFX_NO_FONT_ENTRIES otherwise, strict:true refuses). Exclusive with pdfA and encrypt; metadata.trapped must be 'True' or 'False'; TrimBox or ArtBox, not both. Links and form fields are reported (PDFX_ANNOTATIONS). Check with validate_pdf standard:'pdf-x-4'. See the print_ready prompt."New value: +"PDF/X-4 print exchange (ISO 15930-7). REQUIRES outputIntent with the printer's ICC profile (device class 'prtr'; CMYK or Gray — none is bundled); needs embedFonts:true for a conformant file (PDFX_NO_FONT_ENTRIES otherwise, strict:true refuses). Combines with pdfA:'pdfa2b' | 'pdfa2u' (dual claim) but not pdfa1b / pdfa3b; exclusive with encrypt; metadata.trapped must be 'True' or 'False'; TrimBox or ArtBox, not both. Links and form fields are reported (PDFX_ANNOTATIONS). Check with validate_pdf standard:'pdf-x-4'. See the print_ready prompt." - changed
Input schema / properties / print / descriptionPrevious value: -"Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b). See docs/guides/PRINT.md."New value: +"Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b), `spotColours` ink declarations. See docs/guides/PRINT.md." - added
Input schema / properties / print / properties / spotColoursAdded value: +{ + "description": "Spot inks (/Separation plates) the document may paint with { spot:'name', tint } or { inks:{ name: tint } } anywhere a colour is accepted. Undeclared ink → VALIDATION_ERROR; blank or duplicate name → PRINT_ERROR (an empty string is VALIDATION_ERROR).", + "items": { + "additionalProperties": false, + "properties": { + "alternate": { + "anyOf": [ + { + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "items": { + "maximum": 255, + "minimum": 0, + "type": "number" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" + } + ], + "description": "Process alternate for proofing: [c, m, y, k] 0–100 or [r, g, b] 0–255." + }, + "name": { + "description": "'PANTONE 300 C', 'Varnish', …", + "maxLength": 100, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "name", + "alternate" + ], + "type": "object" + }, + "maxItems": 32, + "minItems": 1, + "type": "array" +} - changed
Input schema / properties / strict / descriptionPrevious value: -"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true."New value: +"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other (TYPOGRAPHY_FEATURE_INEFFECTIVE, TEXT_GLYPH_NOT_COVERED — a character no font covers, drawn as a box or '?') → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true." - changed
Input schema / properties / typography / descriptionPrevious value: -"Fine typography, all opt-in (omitted = unchanged bytes). kerning, fontFeatures and the 'fr' narrow space need embedFonts:true. No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt."New value: +"Fine typography, all opt-in (omitted = unchanged bytes). kerning and fontFeatures need embedFonts:true ('fr' works on base-14 too). No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt." - changed
Input schema / properties / typography / properties / punctuationSpacing / anyOfPrevious value: -[ - { - "enum": [ - "fr", - "fr-CA" - ], - "type": "string" - }, - { - "items": { - "additionalProperties": false, - "properties": { - "char": { - "maxLength": 2, - "minLength": 1, - "type": "string" - }, - "side": { - "enum": [ - "before", - "after" - ], - "type": "string" - }, - "space": { - "description": "U+00A0 / U+202F (narrow needs embedFonts).", - "enum": [ - "nbsp", - "narrow" - ], - "type": "string" - } - }, - "required": [ - "char", - "side", - "space" - ], - "type": "object" - }, - "maxItems": 32, - "type": "array" - } -]New value: +[ + { + "enum": [ + "fr", + "fr-CA" + ], + "type": "string" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "char": { + "maxLength": 2, + "minLength": 1, + "type": "string" + }, + "side": { + "enum": [ + "before", + "after" + ], + "type": "string" + }, + "space": { + "description": "U+00A0 / U+202F (narrow: a TJ adjustment on base-14, the glyph on an embedded font).", + "enum": [ + "nbsp", + "narrow" + ], + "type": "string" + } + }, + "required": [ + "char", + "side", + "space" + ], + "type": "object" + }, + "maxItems": 32, + "type": "array" + } +] - changed
Output schema / descriptionPrevious value: -"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath` (and `url` when the operator maps the sandbox to a public base URL)." - added
Output schema / properties / urlAdded value: +{ + "description": "Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded.", + "type": "string" +}
- Changed
add_ltv3 fields changed- added
Input schema / properties / matchAdded value: +{ + "default": "all", + "description": "offline: what each signature's /VRI references. 'all' (default): every item (Adobe-tolerant superset). 'chain': only the material that validates that signature (its certificates and issuers, the OCSP responses naming them, their issuers' CRLs); the rest still ships in /DSS.", + "enum": [ + "all", + "chain" + ], + "type": "string" +} - changed
Output schema / descriptionPrevious value: -"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath` (and `url` when the operator maps the sandbox to a public base URL)." - added
Output schema / properties / urlAdded value: +{ + "description": "Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded.", + "type": "string" +}
- Changed
add_table20 fields changed- added
Input schema / properties / actualTextAdded value: +{ + "description": "Untagged output: wrap reordered shaped runs and RTL runs in /ActualText so extract_text returns reading order. Default true; false = bare 1.7.0 glyph runs. No effect on tagged (pdfA) output.", + "type": "boolean" +} - changed
Input schema / properties / cellBorders / properties / color / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - added
Input schema / properties / directionAdded value: +{ + "description": "Base text direction (UAX #9): 'auto' reads each paragraph's first strong character and right-aligns RTL ones; 'ltr' / 'rtl' force it. A paragraph's own direction overrides it. Omitted = LTR (1.7.0 bytes).", + "enum": [ + "auto", + "ltr", + "rtl" + ], + "type": "string" +} - changed
Input schema / properties / footerTemplate / properties / color / anyOfPrevious value: -[ - { - "pattern": "^#[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - changed
Input schema / properties / headerTemplate / properties / color / anyOfPrevious value: -[ - { - "pattern": "^#[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - changed
Input schema / properties / includeDiagnostics / descriptionPrevious value: -"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*) as `diagnostics[]` (possibly empty)."New value: +"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*, TEXT_GLYPH_NOT_COVERED) as `diagnostics[]` (possibly empty)." - changed
Input schema / properties / pdfx / descriptionPrevious value: -"PDF/X-4 print exchange (ISO 15930-7). REQUIRES outputIntent with the printer's ICC profile (device class 'prtr'; CMYK or Gray — none is bundled); needs embedFonts:true for a conformant file (PDFX_NO_FONT_ENTRIES otherwise, strict:true refuses). Exclusive with pdfA and encrypt; metadata.trapped must be 'True' or 'False'; TrimBox or ArtBox, not both. Links and form fields are reported (PDFX_ANNOTATIONS). Check with validate_pdf standard:'pdf-x-4'. See the print_ready prompt."New value: +"PDF/X-4 print exchange (ISO 15930-7). REQUIRES outputIntent with the printer's ICC profile (device class 'prtr'; CMYK or Gray — none is bundled); needs embedFonts:true for a conformant file (PDFX_NO_FONT_ENTRIES otherwise, strict:true refuses). Combines with pdfA:'pdfa2b' | 'pdfa2u' (dual claim) but not pdfa1b / pdfa3b; exclusive with encrypt; metadata.trapped must be 'True' or 'False'; TrimBox or ArtBox, not both. Links and form fields are reported (PDFX_ANNOTATIONS). Check with validate_pdf standard:'pdf-x-4'. See the print_ready prompt." - changed
Input schema / properties / print / descriptionPrevious value: -"Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b). See docs/guides/PRINT.md."New value: +"Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b), `spotColours` ink declarations. See docs/guides/PRINT.md." - added
Input schema / properties / print / properties / spotColoursAdded value: +{ + "description": "Spot inks (/Separation plates) the document may paint with { spot:'name', tint } or { inks:{ name: tint } } anywhere a colour is accepted. Undeclared ink → VALIDATION_ERROR; blank or duplicate name → PRINT_ERROR (an empty string is VALIDATION_ERROR).", + "items": { + "additionalProperties": false, + "properties": { + "alternate": { + "anyOf": [ + { + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "items": { + "maximum": 255, + "minimum": 0, + "type": "number" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" + } + ], + "description": "Process alternate for proofing: [c, m, y, k] 0–100 or [r, g, b] 0–255." + }, + "name": { + "description": "'PANTONE 300 C', 'Varnish', …", + "maxLength": 100, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "name", + "alternate" + ], + "type": "object" + }, + "maxItems": 32, + "minItems": 1, + "type": "array" +} - changed
Input schema / properties / strict / descriptionPrevious value: -"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true."New value: +"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other (TYPOGRAPHY_FEATURE_INEFFECTIVE, TEXT_GLYPH_NOT_COVERED — a character no font covers, drawn as a box or '?') → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true." - changed
Input schema / properties / typography / descriptionPrevious value: -"Fine typography, all opt-in (omitted = unchanged bytes). kerning, fontFeatures and the 'fr' narrow space need embedFonts:true. No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt."New value: +"Fine typography, all opt-in (omitted = unchanged bytes). kerning and fontFeatures need embedFonts:true ('fr' works on base-14 too). No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt." - changed
Input schema / properties / typography / properties / punctuationSpacing / anyOfPrevious value: -[ - { - "enum": [ - "fr", - "fr-CA" - ], - "type": "string" - }, - { - "items": { - "additionalProperties": false, - "properties": { - "char": { - "maxLength": 2, - "minLength": 1, - "type": "string" - }, - "side": { - "enum": [ - "before", - "after" - ], - "type": "string" - }, - "space": { - "description": "U+00A0 / U+202F (narrow needs embedFonts).", - "enum": [ - "nbsp", - "narrow" - ], - "type": "string" - } - }, - "required": [ - "char", - "side", - "space" - ], - "type": "object" - }, - "maxItems": 32, - "type": "array" - } -]New value: +[ + { + "enum": [ + "fr", + "fr-CA" + ], + "type": "string" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "char": { + "maxLength": 2, + "minLength": 1, + "type": "string" + }, + "side": { + "enum": [ + "before", + "after" + ], + "type": "string" + }, + "space": { + "description": "U+00A0 / U+202F (narrow: a TJ adjustment on base-14, the glyph on an embedded font).", + "enum": [ + "nbsp", + "narrow" + ], + "type": "string" + } + }, + "required": [ + "char", + "side", + "space" + ], + "type": "object" + }, + "maxItems": 32, + "type": "array" + } +] - changed
Input schema / properties / watermark / descriptionPrevious value: -"Optional semi-transparent watermark rendered centred on every page: `text` (e.g. 'DRAFT'), `image` (JPEG/PNG), or both combined. At least one of text / image is required. opacity < 1.0 (text or image, including the defaults) is rejected under pdfA='pdfa1b' (ISO 19005-1 forbids transparency)."New value: +"Optional semi-transparent watermark rendered centred on every page: `text` (e.g. 'DRAFT'), `image` (JPEG/PNG/JPEG 2000), or both combined. At least one of text / image is required. opacity < 1.0 (text or image, including the defaults) is rejected under pdfA='pdfa1b' (ISO 19005-1 forbids transparency)." - changed
Input schema / properties / watermark / properties / color / anyOfPrevious value: -[ - { - "items": { - "maximum": 1, - "minimum": 0, - "type": "number" - }, - "maxItems": 3, - "minItems": 3, - "type": "array" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "items": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - changed
Input schema / properties / watermark / properties / image / descriptionPrevious value: -"Image watermark (JPEG or PNG) centred on every page, optionally combined with `text`. Bytes are validated against the JPEG/PNG magic numbers; mimeType must match."New value: +"Image watermark (JPEG, PNG or JPEG 2000) centred on every page, optionally combined with `text`. Bytes are validated against the format magic numbers; mimeType must match." - changed
Input schema / properties / watermark / properties / image / properties / imageBase64 / descriptionPrevious value: -"Base64-encoded JPEG or 8-bit opaque PNG bytes (max 8 MiB decoded; alpha-channel, palette and interlaced PNGs are rejected with a remedy). Plain base64, no data: URI prefix."New value: +"Base64-encoded JPEG, 8-bit opaque PNG or JPEG 2000 (JP2 / raw codestream) bytes (max 8 MiB decoded; alpha-channel, palette and interlaced PNGs are rejected with a remedy; a JPEG 2000 opacity channel raises PDFA_JPX_IMAGE under PDF/A). Plain base64, no data: URI prefix." - changed
Input schema / properties / watermark / properties / image / properties / mimeType / descriptionPrevious value: -"'image/jpeg' or 'image/png' — must match the actual bytes."New value: +"'image/jpeg', 'image/png' or 'image/jp2' — must match the actual bytes." - changed
Input schema / properties / watermark / properties / image / properties / mimeType / enumPrevious value: -[ - "image/jpeg", - "image/png" -]New value: +[ + "image/jpeg", + "image/png", + "image/jp2" +] - changed
Output schema / descriptionPrevious value: -"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath` (and `url` when the operator maps the sandbox to a public base URL)." - added
Output schema / properties / urlAdded value: +{ + "description": "Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded.", + "type": "string" +}
- Changed
annotate_pdf4 fields changed- changed
Input schema / properties / annotations / items / properties / type / enumPrevious value: -[ - "text", - "highlight", - "underline", - "strikeout", - "squiggly", - "square", - "circle", - "line", - "freetext" -]New value: +[ + "text", + "highlight", + "underline", + "strikeout", + "squiggly", + "square", + "circle", + "line", + "freetext", + "link" +] - added
Input schema / properties / annotations / items / properties / urlAdded value: +{ + "description": "type='link' (required): target of the /URI action — http:, https: or mailto: only, no control characters. The `rect` is the clickable area; no visible appearance is drawn.", + "maxLength": 2048, + "minLength": 1, + "type": "string" +} - changed
Output schema / descriptionPrevious value: -"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath` (and `url` when the operator maps the sandbox to a public base URL)." - added
Output schema / properties / urlAdded value: +{ + "description": "Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded.", + "type": "string" +}
- Changed
decrypt_pdf2 fields changed- changed
Output schema / descriptionPrevious value: -"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath` (and `url` when the operator maps the sandbox to a public base URL)." - added
Output schema / properties / urlAdded value: +{ + "description": "Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded.", + "type": "string" +}
- Changed
draft_governance_issue1 field changed- added
Output schema / properties / urlAdded value: +{ + "description": "Public URL of the draft (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set).", + "type": "string" +}
- Changed
embed_image16 fields changed- added
Input schema / properties / actualTextAdded value: +{ + "description": "Untagged output: wrap reordered shaped runs and RTL runs in /ActualText so extract_text returns reading order. Default true; false = bare 1.7.0 glyph runs. No effect on tagged (pdfA) output.", + "type": "boolean" +} - added
Input schema / properties / directionAdded value: +{ + "description": "Base text direction (UAX #9): 'auto' reads each paragraph's first strong character and right-aligns RTL ones; 'ltr' / 'rtl' force it. A paragraph's own direction overrides it. Omitted = LTR (1.7.0 bytes).", + "enum": [ + "auto", + "ltr", + "rtl" + ], + "type": "string" +} - changed
Input schema / properties / footerTemplate / properties / color / anyOfPrevious value: -[ - { - "pattern": "^#[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - changed
Input schema / properties / headerTemplate / properties / color / anyOfPrevious value: -[ - { - "pattern": "^#[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - changed
Input schema / properties / imageBase64 / descriptionPrevious value: -"Base64 image bytes. JPEG (baseline; 1, 3 or 4 components — CMYK raises PDFA_DEVICE_CMYK_IMAGE under PDF/A) or PNG (8-bit greyscale/RGB, non-interlaced; alpha-channel and palette PNGs are rejected with a remedy). No data: URI."New value: +"Base64 image bytes. JPEG (baseline; 1, 3 or 4 components — CMYK raises PDFA_DEVICE_CMYK_IMAGE under PDF/A), PNG (8-bit greyscale/RGB, non-interlaced; alpha-channel and palette PNGs are rejected with a remedy) or JPEG 2000 (JP2 file or raw .j2k codestream, passed through as /JPXDecode; PDF 1.5+, so PDFA1_JPX_IMAGE under pdfa1b). No data: URI." - changed
Input schema / properties / includeDiagnostics / descriptionPrevious value: -"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*) as `diagnostics[]` (possibly empty)."New value: +"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*, TEXT_GLYPH_NOT_COVERED) as `diagnostics[]` (possibly empty)." - changed
Input schema / properties / mimeType / descriptionPrevious value: -"MIME type of the image. Must match the actual encoding of imageBase64 (magic bytes are checked)."New value: +"MIME type of the image. Must match the actual encoding of imageBase64 (magic bytes are checked). 'image/jp2' accepts a JP2 file (.jp2/.jpx) or a raw JPEG 2000 codestream (.j2k/.j2c)." - changed
Input schema / properties / mimeType / enumPrevious value: -[ - "image/jpeg", - "image/png" -]New value: +[ + "image/jpeg", + "image/png", + "image/jp2" +] - changed
Input schema / properties / pdfx / descriptionPrevious value: -"PDF/X-4 print exchange (ISO 15930-7). REQUIRES outputIntent with the printer's ICC profile (device class 'prtr'; CMYK or Gray — none is bundled); needs embedFonts:true for a conformant file (PDFX_NO_FONT_ENTRIES otherwise, strict:true refuses). Exclusive with pdfA and encrypt; metadata.trapped must be 'True' or 'False'; TrimBox or ArtBox, not both. Links and form fields are reported (PDFX_ANNOTATIONS). Check with validate_pdf standard:'pdf-x-4'. See the print_ready prompt."New value: +"PDF/X-4 print exchange (ISO 15930-7). REQUIRES outputIntent with the printer's ICC profile (device class 'prtr'; CMYK or Gray — none is bundled); needs embedFonts:true for a conformant file (PDFX_NO_FONT_ENTRIES otherwise, strict:true refuses). Combines with pdfA:'pdfa2b' | 'pdfa2u' (dual claim) but not pdfa1b / pdfa3b; exclusive with encrypt; metadata.trapped must be 'True' or 'False'; TrimBox or ArtBox, not both. Links and form fields are reported (PDFX_ANNOTATIONS). Check with validate_pdf standard:'pdf-x-4'. See the print_ready prompt." - changed
Input schema / properties / print / descriptionPrevious value: -"Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b). See docs/guides/PRINT.md."New value: +"Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b), `spotColours` ink declarations. See docs/guides/PRINT.md." - added
Input schema / properties / print / properties / spotColoursAdded value: +{ + "description": "Spot inks (/Separation plates) the document may paint with { spot:'name', tint } or { inks:{ name: tint } } anywhere a colour is accepted. Undeclared ink → VALIDATION_ERROR; blank or duplicate name → PRINT_ERROR (an empty string is VALIDATION_ERROR).", + "items": { + "additionalProperties": false, + "properties": { + "alternate": { + "anyOf": [ + { + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "items": { + "maximum": 255, + "minimum": 0, + "type": "number" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" + } + ], + "description": "Process alternate for proofing: [c, m, y, k] 0–100 or [r, g, b] 0–255." + }, + "name": { + "description": "'PANTONE 300 C', 'Varnish', …", + "maxLength": 100, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "name", + "alternate" + ], + "type": "object" + }, + "maxItems": 32, + "minItems": 1, + "type": "array" +} - changed
Input schema / properties / strict / descriptionPrevious value: -"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true."New value: +"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other (TYPOGRAPHY_FEATURE_INEFFECTIVE, TEXT_GLYPH_NOT_COVERED — a character no font covers, drawn as a box or '?') → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true." - changed
Input schema / properties / typography / descriptionPrevious value: -"Fine typography, all opt-in (omitted = unchanged bytes). kerning, fontFeatures and the 'fr' narrow space need embedFonts:true. No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt."New value: +"Fine typography, all opt-in (omitted = unchanged bytes). kerning and fontFeatures need embedFonts:true ('fr' works on base-14 too). No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt." - changed
Input schema / properties / typography / properties / punctuationSpacing / anyOfPrevious value: -[ - { - "enum": [ - "fr", - "fr-CA" - ], - "type": "string" - }, - { - "items": { - "additionalProperties": false, - "properties": { - "char": { - "maxLength": 2, - "minLength": 1, - "type": "string" - }, - "side": { - "enum": [ - "before", - "after" - ], - "type": "string" - }, - "space": { - "description": "U+00A0 / U+202F (narrow needs embedFonts).", - "enum": [ - "nbsp", - "narrow" - ], - "type": "string" - } - }, - "required": [ - "char", - "side", - "space" - ], - "type": "object" - }, - "maxItems": 32, - "type": "array" - } -]New value: +[ + { + "enum": [ + "fr", + "fr-CA" + ], + "type": "string" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "char": { + "maxLength": 2, + "minLength": 1, + "type": "string" + }, + "side": { + "enum": [ + "before", + "after" + ], + "type": "string" + }, + "space": { + "description": "U+00A0 / U+202F (narrow: a TJ adjustment on base-14, the glyph on an embedded font).", + "enum": [ + "nbsp", + "narrow" + ], + "type": "string" + } + }, + "required": [ + "char", + "side", + "space" + ], + "type": "object" + }, + "maxItems": 32, + "type": "array" + } +] - changed
Output schema / descriptionPrevious value: -"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath` (and `url` when the operator maps the sandbox to a public base URL)." - added
Output schema / properties / urlAdded value: +{ + "description": "Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded.", + "type": "string" +}
- Changed
encrypt_pdf2 fields changed- changed
Output schema / descriptionPrevious value: -"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath` (and `url` when the operator maps the sandbox to a public base URL)." - added
Output schema / properties / urlAdded value: +{ + "description": "Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded.", + "type": "string" +}
- Changed
extract_pages2 fields changed- changed
Output schema / descriptionPrevious value: -"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath` (and `url` when the operator maps the sandbox to a public base URL)." - added
Output schema / properties / urlAdded value: +{ + "description": "Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded.", + "type": "string" +}
- Changed
extract_text1 field changed- added
Input schema / properties / onStreamErrorAdded value: +{ + "default": "limit", + "description": "'limit' (default): a stream over the decompression cap (PDFNATIVE_MCP_MAX_INFLATE_BYTES) fails with PDF_PARSE_FAILED; other damaged streams are skipped. 'throw': any undecodable stream fails the call (PDF_PARSE_FAILED). 'skip': skip the over-cap stream too and read the rest (1.7.0 behaviour — that page reads as empty).", + "enum": [ + "limit", + "skip", + "throw" + ], + "type": "string" +}
- Changed
fill_form2 fields changed- changed
Output schema / descriptionPrevious value: -"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath` (and `url` when the operator maps the sandbox to a public base URL)." - added
Output schema / properties / urlAdded value: +{ + "description": "Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded.", + "type": "string" +}
- Changed
generate_basic_pdf22 fields changed- added
Input schema / properties / actualTextAdded value: +{ + "description": "Untagged output: wrap reordered shaped runs and RTL runs in /ActualText so extract_text returns reading order. Default true; false = bare 1.7.0 glyph runs. No effect on tagged (pdfA) output.", + "type": "boolean" +} - changed
Input schema / properties / blocks / items / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "keepWithNext": { - "description": "Keep this heading on the same page as the block that follows. Overrides typography.keepHeadingsWithNext for this block, either way.", - "type": "boolean" - }, - "level": { - "enum": [ - 1, - 2, - 3 - ], - "type": "integer" - }, - "text": { - "maxLength": 500, - "minLength": 1, - "type": "string" - }, - "type": { - "const": "heading" - } - }, - "required": [ - "type", - "text", - "level" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "align": { - "description": "Text alignment (default left). 'justify' spans every line but the last across the measure; pair it with typography.opticalMargins.", - "enum": [ - "left", - "right", - "center", - "justify" - ], - "type": "string" - }, - "keepWithNext": { - "description": "Keep this paragraph on the same page as the block that follows (a lead-in line before a table or figure). Default false.", - "type": "boolean" - }, - "splittable": { - "description": "Allow / forbid this paragraph breaking across pages, overriding typography.splitParagraphs for this block.", - "type": "boolean" - }, - "text": { - "description": "Paragraph text. Embedded newlines ('\\n') are automatically split into separate paragraphs — no need to pre-split; never emit a literal newline expecting a soft line break.", - "maxLength": 50000, - "minLength": 1, - "type": "string" - }, - "type": { - "const": "paragraph" - } - }, - "required": [ - "type", - "text" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "description": "List items. A string is a leaf; an object { text, items } nests a sub-list (bullets/numbers indent; numbered sub-lists restart at 1).", - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "style": { - "default": "bullet", - "enum": [ - "bullet", - "numbered" - ], - "type": "string" - }, - "type": { - "const": "list" - } - }, - "required": [ - "type", - "items" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "type": { - "const": "pageBreak" - } - }, - "required": [ - "type" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "height": { - "maximum": 500, - "minimum": 1, - "type": "number" - }, - "type": { - "const": "spacer" - } - }, - "required": [ - "type", - "height" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Native vector chart rendered as pure PDF path operators — bar / horizontal-bar / stacked-bar / line / area / scatter / pie / donut (pdfnative 1.7 charts v2: time and log axes, data labels, secondary axis, legends). Same body as add_chart.", - "properties": { - "align": { - "description": "Horizontal alignment within the content width. Default 'left'.", - "enum": [ - "left", - "center", - "right" - ], - "type": "string" - }, - "altText": { - "description": "Alt text for the tagged-PDF /Figure /Alt. Auto-generated when omitted.", - "maxLength": 500, - "type": "string" - }, - "axis": { - "additionalProperties": false, - "description": "Value-axis options (bar/line only).", - "properties": { - "grid": { - "description": "Draw horizontal gridlines.", - "type": "boolean" - }, - "scale": { - "description": "Value-axis scale. 'log' requires strictly positive values and is not available for stacked charts.", - "enum": [ - "linear", - "log" - ], - "type": "string" - }, - "ticks": { - "description": "Target tick count (nice 1/2/5×10ⁿ steps).", - "maximum": 20, - "minimum": 2, - "type": "integer" - }, - "yMax": { - "description": "Force the axis maximum (values are clamped to the plot band).", - "type": "number" - }, - "yMin": { - "description": "Force the axis minimum (values are clamped to the plot band).", - "type": "number" - } - }, - "type": "object" - }, - "axis2": { - "additionalProperties": false, - "description": "Secondary RIGHT value axis (drawn only when a series sets yAxis:'right').", - "properties": { - "scale": { - "enum": [ - "linear", - "log" - ], - "type": "string" - }, - "ticks": { - "maximum": 20, - "minimum": 2, - "type": "integer" - }, - "yMax": { - "type": "number" - }, - "yMin": { - "type": "number" - } - }, - "type": "object" - }, - "categories": { - "description": "Category / slice labels (x-axis). Defaults to 1-based indices when omitted.", - "items": { - "maxLength": 200, - "type": "string" - }, - "maxItems": 1000, - "type": "array" - }, - "chartType": { - "description": "Chart kind. 'pie'/'donut' use exactly one series; 'bar'/'barH'/'stackedBar'/'stackedBarH'/'line'/'area'/'scatter' support multiple series. 'scatter' requires xValues on every series and a positional xAxis.type ('linear' or 'time').", - "enum": [ - "bar", - "barH", - "stackedBar", - "stackedBarH", - "line", - "area", - "scatter", - "pie", - "donut" - ], - "type": "string" - }, - "colors": { - "description": "Palette override (per-series for bar/line, per-slice for pie/donut).", - "items": { - "anyOf": [ - { - "pattern": "^#?[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } - ], - "description": "CSS-style hex colour, e.g. \"#3366cc\"." - }, - "maxItems": 50, - "type": "array" - }, - "dataLabels": { - "description": "Per-point value labels: true for defaults, or an object to format them.", - "oneOf": [ - { - "type": "boolean" - }, - { - "additionalProperties": false, - "properties": { - "decimals": { - "maximum": 6, - "minimum": 0, - "type": "integer" - }, - "prefix": { - "maxLength": 16, - "type": "string" - }, - "suffix": { - "maxLength": 16, - "type": "string" - } - }, - "type": "object" - } - ] - }, - "height": { - "description": "Plot-area height in points. Default 240.", - "maximum": 2000, - "minimum": 50, - "type": "number" - }, - "labelRotation": { - "description": "Rotate category labels counter-clockwise by this many degrees (disables the automatic stride).", - "maximum": 90, - "minimum": 0, - "type": "number" - }, - "labelStride": { - "description": "Draw every Nth category label. Default: automatic (measured non-overlap); 1 draws every label.", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "legend": { - "description": "Legend placement. Defaults to 'bottom' for multi-series/pie, else 'none'.", - "enum": [ - "bottom", - "none" - ], - "type": "string" - }, - "markers": { - "description": "Draw point markers on line series. Default false.", - "type": "boolean" - }, - "series": { - "description": "Data series. Pie/donut charts use exactly one series (each value becomes a slice).", - "items": { - "additionalProperties": false, - "properties": { - "color": { - "anyOf": [ - { - "pattern": "^#?[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } - ], - "description": "CSS-style hex colour, e.g. \"#3366cc\"." - }, - "label": { - "description": "Series label (shown in the legend).", - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "values": { - "description": "Numeric values, one per category. Negative values are supported for bar/line.", - "items": { - "type": "number" - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "xValues": { - "description": "Per-point x positions (same length as values) for scatter charts and for line/area charts with xAxis.type 'linear' or 'time'.", - "items": { - "description": "Positional x value: a number (linear axis) or an ISO-8601 date / epoch milliseconds (time axis).", - "maxLength": 64, - "type": [ - "number", - "string" - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "yAxis": { - "description": "Bind the series to the left (default) or the secondary right value axis (cartesian charts only; configure its range with 'axis2').", - "enum": [ - "left", - "right" - ], - "type": "string" - } - }, - "required": [ - "label", - "values" - ], - "type": "object" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "title": { - "description": "Chart title rendered above the plot.", - "maxLength": 200, - "type": "string" - }, - "type": { - "const": "chart" - }, - "width": { - "description": "Plot width in points (clamped to content width). Default 460.", - "maximum": 2000, - "minimum": 50, - "type": "number" - }, - "xAxis": { - "additionalProperties": false, - "description": "Horizontal axis. 'category' (default) positions points by index; 'linear' / 'time' position them by series xValues (line/area/scatter only). Time ticks are UTC-deterministic.", - "properties": { - "grid": { - "description": "Draw vertical gridlines.", - "type": "boolean" - }, - "max": { - "description": "Axis maximum (number, or ISO-8601 / epoch ms for time axes).", - "maxLength": 64, - "type": [ - "number", - "string" - ] - }, - "min": { - "description": "Axis minimum (number, or ISO-8601 / epoch ms for time axes).", - "maxLength": 64, - "type": [ - "number", - "string" - ] - }, - "ticks": { - "maximum": 20, - "minimum": 2, - "type": "integer" - }, - "type": { - "enum": [ - "category", - "linear", - "time" - ], - "type": "string" - } - }, - "type": "object" - } - }, - "required": [ - "type", - "chartType", - "series" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Inline smart table — same body as add_table (every row must have exactly as many cells as headers).", - "properties": { - "autoFitColumns": { - "description": "Auto-fit column widths to content. Output bytes then depend on text metrics (not byte-deterministic across content changes).", - "type": "boolean" - }, - "caption": { - "description": "Caption rendered above the table (tagged as /Caption under PDF/A).", - "maxLength": 200, - "type": "string" - }, - "cellBorders": { - "additionalProperties": false, - "description": "Per-cell vector borders (pure strokes, PDF/A-safe). Choose individual sides or `all`.", - "properties": { - "all": { - "description": "Draw all four edges (overrides the individual side flags).", - "type": "boolean" - }, - "bottom": { - "type": "boolean" - }, - "color": { - "anyOf": [ - { - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } - ], - "description": "Stroke colour as a PDF operator string ('0.8 0.8 0.8') or hex. Default light grey." - }, - "left": { - "type": "boolean" - }, - "right": { - "type": "boolean" - }, - "style": { - "description": "Stroke style (default 'solid').", - "enum": [ - "solid", - "dashed", - "dotted" - ], - "type": "string" - }, - "top": { - "type": "boolean" - }, - "width": { - "description": "Stroke width in points (default 0.5).", - "maximum": 10, - "minimum": 0, - "type": "number" - } - }, - "type": "object" - }, - "cellPadding": { - "description": "Horizontal cell padding in points (default 3).", - "maximum": 50, - "minimum": 0, - "type": "number" - }, - "cellVAlign": { - "description": "Vertical alignment of cell content.", - "enum": [ - "top", - "middle", - "bottom" - ], - "type": "string" - }, - "clipCells": { - "description": "Clip cell contents to the column bounds (PDF clip operators). Recommended for PDF/A and visual safety.", - "type": "boolean" - }, - "headers": { - "description": "Column header labels. Must have the same length as each row in `rows`.", - "items": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "minRowHeight": { - "description": "Minimum row height in points (default 12).", - "maximum": 200, - "minimum": 1, - "type": "number" - }, - "repeatHeader": { - "description": "Repeat the header row on every continuation page (default true).", - "type": "boolean" - }, - "rows": { - "description": "Data rows. Each row is an array of cell strings with the same length as `headers`.", - "items": { - "items": { - "maxLength": 500, - "type": "string" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "maxItems": 5000, - "minItems": 1, - "type": "array" - }, - "type": { - "const": "table" - }, - "wrap": { - "description": "Cell wrap policy: 'auto' (default) wraps only overflowing cells; 'always' wraps every cell; 'never' truncates.", - "enum": [ - "auto", - "always", - "never" - ], - "type": "string" - }, - "zebra": { - "description": "Alternate-row light tint (static fill, PDF/A-1b safe).", - "type": "boolean" - } - }, - "required": [ - "type", - "headers", - "rows" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Inline JPEG/PNG image. Without width/height the pixel size is used as points and clamped to the content width; with one dimension the aspect ratio is kept. The decoded bytes of all image blocks in one call are capped at 24 MiB (a watermark image has its own 8 MiB cap).", - "properties": { - "align": { - "default": "left", - "description": "Horizontal placement inside the content width.", - "enum": [ - "left", - "center", - "right" - ], - "type": "string" - }, - "alt": { - "description": "Accessible description (tagged /Figure /Alt). Always provide it for non-decorative content under PDF/A or PDF/UA.", - "maxLength": 500, - "type": "string" - }, - "height": { - "description": "Render height in points.", - "maximum": 1000, - "minimum": 10, - "type": "number" - }, - "imageBase64": { - "description": "Base64 image bytes. JPEG (baseline; 1, 3 or 4 components — CMYK raises PDFA_DEVICE_CMYK_IMAGE under PDF/A) or PNG (8-bit greyscale/RGB, non-interlaced; alpha-channel and palette PNGs are rejected with a remedy). No data: URI.", - "maxLength": 12000000, - "minLength": 4, - "type": "string" - }, - "mimeType": { - "description": "MIME type of the image. Must match the actual encoding of imageBase64 (magic bytes are checked).", - "enum": [ - "image/jpeg", - "image/png" - ], - "type": "string" - }, - "type": { - "const": "image" - }, - "width": { - "description": "Render width in points.", - "maximum": 800, - "minimum": 10, - "type": "number" - } - }, - "required": [ - "type", - "imageBase64", - "mimeType" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Clickable external link (/URI action). Only http:, https: and mailto: URLs are accepted.", - "properties": { - "color": { - "anyOf": [ - { - "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } - ], - "description": "Hex colour (#RGB or #RRGGBB)." - }, - "fontSize": { - "description": "Default 10.", - "maximum": 48, - "minimum": 6, - "type": "number" - }, - "text": { - "maxLength": 500, - "minLength": 1, - "type": "string" - }, - "type": { - "const": "link" - }, - "url": { - "description": "http(s):// or mailto: URL.", - "maxLength": 2048, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "type", - "text", - "url" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Printed table of contents generated from the document's heading blocks (internal /GoTo links with dot leaders). Pairs with outline:'auto' for the bookmark pane.", - "properties": { - "fontSize": { - "description": "Default 10.", - "maximum": 24, - "minimum": 6, - "type": "number" - }, - "indent": { - "description": "Points of indent per heading level (default 15).", - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxLevel": { - "description": "Deepest heading level listed (default 3).", - "enum": [ - 1, - 2, - 3 - ], - "type": "integer" - }, - "title": { - "description": "Default 'Table of Contents'.", - "maxLength": 200, - "type": "string" - }, - "type": { - "const": "toc" - } - }, - "required": [ - "type" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Inline barcode — same body as add_barcode (pure vector, no /Alt available in the engine).", - "properties": { - "align": { - "default": "left", - "description": "Horizontal placement inside the content width.", - "enum": [ - "left", - "center", - "right" - ], - "type": "string" - }, - "data": { - "description": "Raw payload to encode — do NOT URL-encode. For QR/URL pass e.g. \"https://example.com\" verbatim. EAN-13 must be 12 or 13 digits (13th is auto-computed). Code 128 accepts ASCII alphanumerics.", - "maxLength": 4296, - "minLength": 1, - "type": "string" - }, - "ecLevel": { - "default": "M", - "description": "QR ONLY. Error correction level (L=7%, M=15%, Q=25%, H=30%). Ignored for code128/ean13/datamatrix/pdf417. Use H for printed media that may get smudged or partially covered (e.g. logo overlay).", - "enum": [ - "L", - "M", - "Q", - "H" - ], - "type": "string" - }, - "format": { - "description": "Barcode symbology to render.", - "enum": [ - "qr", - "code128", - "ean13", - "datamatrix", - "pdf417" - ], - "type": "string" - }, - "height": { - "default": 200, - "description": "Barcode height in PDF points (ignored for square symbologies like QR/Data Matrix).", - "maximum": 500, - "minimum": 30, - "type": "number" - }, - "type": { - "const": "barcode" - }, - "width": { - "default": 200, - "description": "Barcode width in PDF points.", - "maximum": 500, - "minimum": 30, - "type": "number" - } - }, - "required": [ - "type", - "format", - "data" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Vector drawing from an SVG path `d` string or SVG markup. Supported: <path> <rect> (rx/ry) <circle> <ellipse> <line> <polyline> <polygon> and <text>/<tspan> (x, y, font-size, fill, text-anchor, dx/dy); fill / stroke / stroke-width attributes; double-quoted attributes only. NOT supported (silently ignored): transform, <g>, <use>, <image>, <defs>/<clipPath>, gradients, opacity, CSS/style, dash patterns, text word-wrap. No external reference is ever fetched (no XML parser: entities other than & < > " ' &#n; are dropped). Pure path operators — PDF/A-safe at every level.", - "properties": { - "align": { - "default": "left", - "description": "Horizontal placement inside the content width.", - "enum": [ - "left", - "center", - "right" - ], - "type": "string" - }, - "alt": { - "description": "Accessible description (tagged /Figure /Alt). Always provide it for non-decorative content under PDF/A or PDF/UA.", - "maxLength": 500, - "type": "string" - }, - "data": { - "description": "Path `d` string or SVG markup (≤ 100 000 characters).", - "maxLength": 100000, - "minLength": 1, - "type": "string" - }, - "fill": { - "anyOf": [ - { - "pattern": "^(?:none|#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}))$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } - ], - "description": "Hex colour or 'none' (default black)." - }, - "height": { - "description": "Render height in points (default 200).", - "maximum": 1000, - "minimum": 10, - "type": "number" - }, - "stroke": { - "anyOf": [ - { - "pattern": "^(?:none|#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}))$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } - ], - "description": "Hex colour or 'none' (default none)." - }, - "strokeWidth": { - "description": "Stroke width in SVG user units (default 1).", - "maximum": 50, - "minimum": 0, - "type": "number" - }, - "type": { - "const": "svg" - }, - "viewBox": { - "description": "[minX, minY, width, height] — overrides the viewBox of the markup; required for a bare path string that is not 0-based.", - "items": { - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - }, - "width": { - "description": "Render width in points (default 200).", - "maximum": 800, - "minimum": 10, - "type": "number" - } - }, - "required": [ - "type", - "data" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Inline AcroForm field — same body as an add_form field. Under a PDF/A claim pass embedFonts:true so the field font is embedded too (PDFA_UNEMBEDDED_FORM_FONT otherwise; strict:true then fails the call).", - "properties": { - "checked": { - "description": "Initial checked state for checkbox / radio fields.", - "type": "boolean" - }, - "fieldType": { - "description": "Type of form control to render. Radio fields sharing a name form one radio group.", - "enum": [ - "text", - "textarea", - "checkbox", - "radio", - "dropdown", - "listbox" - ], - "type": "string" - }, - "fontSize": { - "description": "Font size for text rendering inside the field.", - "maximum": 48, - "minimum": 6, - "type": "number" - }, - "height": { - "description": "Field height in points (default depends on the type).", - "maximum": 300, - "minimum": 10, - "type": "number" - }, - "label": { - "description": "Human-readable label shown above the field.", - "maxLength": 200, - "type": "string" - }, - "maxLength": { - "description": "Maximum character length for text/textarea fields.", - "maximum": 32767, - "minimum": 1, - "type": "integer" - }, - "name": { - "description": "Unique field name used as the PDF annotation identifier (/T).", - "maxLength": 100, - "minLength": 1, - "type": "string" - }, - "options": { - "description": "Choices for dropdown, listbox or radio fields.", - "items": { - "maxLength": 200, - "type": "string" - }, - "maxItems": 100, - "type": "array" - }, - "placeholder": { - "description": "Hint text shown while the field is empty.", - "maxLength": 200, - "type": "string" - }, - "readOnly": { - "description": "Prevent editing of this field.", - "type": "boolean" - }, - "required": { - "description": "Mark field as required.", - "type": "boolean" - }, - "type": { - "const": "formField" - }, - "value": { - "description": "Pre-filled value. The key is 'value' (there is no defaultValue).", - "maxLength": 2000, - "type": "string" - }, - "width": { - "description": "Field width in points (default: full content width).", - "maximum": 500, - "minimum": 10, - "type": "number" - } - }, - "required": [ - "type", - "fieldType", - "name" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "keepWithNext": { + "description": "Keep this heading on the same page as the block that follows. Overrides typography.keepHeadingsWithNext for this block, either way.", + "type": "boolean" + }, + "level": { + "enum": [ + 1, + 2, + 3 + ], + "type": "integer" + }, + "text": { + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "heading" + } + }, + "required": [ + "type", + "text", + "level" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "align": { + "description": "Text alignment (default left). 'justify' spans every line but the last across the measure; pair it with typography.opticalMargins.", + "enum": [ + "left", + "right", + "center", + "justify" + ], + "type": "string" + }, + "direction": { + "description": "Base direction of this paragraph, overriding the document `direction`: 'auto' (first strong character), 'ltr' or 'rtl'. A right-to-left paragraph is right-aligned unless `align` says otherwise.", + "enum": [ + "auto", + "ltr", + "rtl" + ], + "type": "string" + }, + "keepWithNext": { + "description": "Keep this paragraph on the same page as the block that follows (a lead-in line before a table or figure). Default false.", + "type": "boolean" + }, + "splittable": { + "description": "Allow / forbid this paragraph breaking across pages, overriding typography.splitParagraphs for this block.", + "type": "boolean" + }, + "text": { + "description": "Paragraph text. Embedded newlines ('\\n') are automatically split into separate paragraphs — no need to pre-split; never emit a literal newline expecting a soft line break.", + "maxLength": 50000, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "paragraph" + } + }, + "required": [ + "type", + "text" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "description": "List items. A string is a leaf; an object { text, items } nests a sub-list (bullets/numbers indent; numbered sub-lists restart at 1).", + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "style": { + "default": "bullet", + "enum": [ + "bullet", + "numbered" + ], + "type": "string" + }, + "type": { + "const": "list" + } + }, + "required": [ + "type", + "items" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "type": { + "const": "pageBreak" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "height": { + "maximum": 500, + "minimum": 1, + "type": "number" + }, + "type": { + "const": "spacer" + } + }, + "required": [ + "type", + "height" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Native vector chart rendered as pure PDF path operators — bar / horizontal-bar / stacked-bar / line / area / scatter / pie / donut (pdfnative 1.7 charts v2: time and log axes, data labels, secondary axis, legends). Same body as add_chart.", + "properties": { + "align": { + "description": "Horizontal alignment within the content width. Default 'left'.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + }, + "altText": { + "description": "Alt text for the tagged-PDF /Figure /Alt. Auto-generated when omitted.", + "maxLength": 500, + "type": "string" + }, + "axis": { + "additionalProperties": false, + "description": "Value-axis options (bar/line only).", + "properties": { + "grid": { + "description": "Draw horizontal gridlines.", + "type": "boolean" + }, + "scale": { + "description": "Value-axis scale. 'log' requires strictly positive values and is not available for stacked charts.", + "enum": [ + "linear", + "log" + ], + "type": "string" + }, + "ticks": { + "description": "Target tick count (nice 1/2/5×10ⁿ steps).", + "maximum": 20, + "minimum": 2, + "type": "integer" + }, + "yMax": { + "description": "Force the axis maximum (values are clamped to the plot band).", + "type": "number" + }, + "yMin": { + "description": "Force the axis minimum (values are clamped to the plot band).", + "type": "number" + } + }, + "type": "object" + }, + "axis2": { + "additionalProperties": false, + "description": "Secondary RIGHT value axis (drawn only when a series sets yAxis:'right').", + "properties": { + "scale": { + "enum": [ + "linear", + "log" + ], + "type": "string" + }, + "ticks": { + "maximum": 20, + "minimum": 2, + "type": "integer" + }, + "yMax": { + "type": "number" + }, + "yMin": { + "type": "number" + } + }, + "type": "object" + }, + "categories": { + "description": "Category / slice labels (x-axis). Defaults to 1-based indices when omitted.", + "items": { + "maxLength": 200, + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "chartType": { + "description": "Chart kind. 'pie'/'donut' use exactly one series; 'bar'/'barH'/'stackedBar'/'stackedBarH'/'line'/'area'/'scatter' support multiple series. 'scatter' requires xValues on every series and a positional xAxis.type ('linear' or 'time').", + "enum": [ + "bar", + "barH", + "stackedBar", + "stackedBarH", + "line", + "area", + "scatter", + "pie", + "donut" + ], + "type": "string" + }, + "colors": { + "description": "Palette override (per-series for bar/line, per-slice for pie/donut).", + "items": { + "anyOf": [ + { + "pattern": "^#?[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } + ], + "description": "CSS-style hex colour, e.g. \"#3366cc\"." + }, + "maxItems": 50, + "type": "array" + }, + "dataLabels": { + "description": "Per-point value labels: true for defaults, or an object to format them.", + "oneOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "decimals": { + "maximum": 6, + "minimum": 0, + "type": "integer" + }, + "prefix": { + "maxLength": 16, + "type": "string" + }, + "suffix": { + "maxLength": 16, + "type": "string" + } + }, + "type": "object" + } + ] + }, + "height": { + "description": "Plot-area height in points. Default 240.", + "maximum": 2000, + "minimum": 50, + "type": "number" + }, + "labelRotation": { + "description": "Rotate category labels counter-clockwise by this many degrees (disables the automatic stride).", + "maximum": 90, + "minimum": 0, + "type": "number" + }, + "labelStride": { + "description": "Draw every Nth category label. Default: automatic (measured non-overlap); 1 draws every label.", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "legend": { + "description": "Legend placement. Defaults to 'bottom' for multi-series/pie, else 'none'.", + "enum": [ + "bottom", + "none" + ], + "type": "string" + }, + "markers": { + "description": "Draw point markers on line series. Default false.", + "type": "boolean" + }, + "series": { + "description": "Data series. Pie/donut charts use exactly one series (each value becomes a slice).", + "items": { + "additionalProperties": false, + "properties": { + "color": { + "anyOf": [ + { + "pattern": "^#?[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } + ], + "description": "CSS-style hex colour, e.g. \"#3366cc\"." + }, + "colors": { + "description": "One colour per value, painted on bar, barH, stackedBar and stackedBarH; the length must equal values.length on every chart type (CHART_ERROR otherwise). The legend swatch keeps 'color'; line, area, scatter, pie and donut paint 'color' only.", + "items": { + "anyOf": [ + { + "pattern": "^#?[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } + ], + "description": "CSS-style hex colour, e.g. \"#3366cc\"." + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "label": { + "description": "Series label (shown in the legend). Optional since 1.8.0: an unlabelled series is listed as 'Series N'.", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "values": { + "description": "Numeric values, one per category. Negative values are supported for bar/line.", + "items": { + "type": "number" + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "xValues": { + "description": "Per-point x positions (same length as values) for scatter charts and for line/area charts with xAxis.type 'linear' or 'time'.", + "items": { + "description": "Positional x value: a number (linear axis) or an ISO-8601 date / epoch milliseconds (time axis).", + "maxLength": 64, + "type": [ + "number", + "string" + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "yAxis": { + "description": "Bind the series to the left (default) or the secondary right value axis (cartesian charts only; configure its range with 'axis2').", + "enum": [ + "left", + "right" + ], + "type": "string" + } + }, + "required": [ + "values" + ], + "type": "object" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "title": { + "description": "Chart title rendered above the plot.", + "maxLength": 200, + "type": "string" + }, + "type": { + "const": "chart" + }, + "width": { + "description": "Plot width in points (clamped to content width). Default 460.", + "maximum": 2000, + "minimum": 50, + "type": "number" + }, + "xAxis": { + "additionalProperties": false, + "description": "Horizontal axis. 'category' (default) positions points by index; 'linear' / 'time' position them by series xValues (line/area/scatter only). Time ticks are UTC-deterministic.", + "properties": { + "grid": { + "description": "Draw vertical gridlines.", + "type": "boolean" + }, + "max": { + "description": "Axis maximum (number, or ISO-8601 / epoch ms for time axes).", + "maxLength": 64, + "type": [ + "number", + "string" + ] + }, + "min": { + "description": "Axis minimum (number, or ISO-8601 / epoch ms for time axes).", + "maxLength": 64, + "type": [ + "number", + "string" + ] + }, + "ticks": { + "maximum": 20, + "minimum": 2, + "type": "integer" + }, + "type": { + "enum": [ + "category", + "linear", + "time" + ], + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "type", + "chartType", + "series" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Inline smart table — same body as add_table (every row must have exactly as many cells as headers).", + "properties": { + "autoFitColumns": { + "description": "Auto-fit column widths to content. Output bytes then depend on text metrics (not byte-deterministic across content changes).", + "type": "boolean" + }, + "caption": { + "description": "Caption rendered above the table (tagged as /Caption under PDF/A).", + "maxLength": 200, + "type": "string" + }, + "cellBorders": { + "additionalProperties": false, + "description": "Per-cell vector borders (pure strokes, PDF/A-safe). Choose individual sides or `all`.", + "properties": { + "all": { + "description": "Draw all four edges (overrides the individual side flags).", + "type": "boolean" + }, + "bottom": { + "type": "boolean" + }, + "color": { + "anyOf": [ + { + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } + ], + "description": "Stroke colour as a PDF operator string ('0.8 0.8 0.8') or hex. Default light grey." + }, + "left": { + "type": "boolean" + }, + "right": { + "type": "boolean" + }, + "style": { + "description": "Stroke style (default 'solid').", + "enum": [ + "solid", + "dashed", + "dotted" + ], + "type": "string" + }, + "top": { + "type": "boolean" + }, + "width": { + "description": "Stroke width in points (default 0.5).", + "maximum": 10, + "minimum": 0, + "type": "number" + } + }, + "type": "object" + }, + "cellPadding": { + "description": "Horizontal cell padding in points (default 3).", + "maximum": 50, + "minimum": 0, + "type": "number" + }, + "cellVAlign": { + "description": "Vertical alignment of cell content.", + "enum": [ + "top", + "middle", + "bottom" + ], + "type": "string" + }, + "clipCells": { + "description": "Clip cell contents to the column bounds (PDF clip operators). Recommended for PDF/A and visual safety.", + "type": "boolean" + }, + "headers": { + "description": "Column header labels. Must have the same length as each row in `rows`.", + "items": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "minRowHeight": { + "description": "Minimum row height in points (default 12).", + "maximum": 200, + "minimum": 1, + "type": "number" + }, + "repeatHeader": { + "description": "Repeat the header row on every continuation page (default true).", + "type": "boolean" + }, + "rows": { + "description": "Data rows. Each row is an array of cell strings with the same length as `headers`.", + "items": { + "items": { + "maxLength": 500, + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "maxItems": 5000, + "minItems": 1, + "type": "array" + }, + "type": { + "const": "table" + }, + "wrap": { + "description": "Cell wrap policy: 'auto' (default) wraps only overflowing cells; 'always' wraps every cell; 'never' truncates.", + "enum": [ + "auto", + "always", + "never" + ], + "type": "string" + }, + "zebra": { + "description": "Alternate-row light tint (static fill, PDF/A-1b safe).", + "type": "boolean" + } + }, + "required": [ + "type", + "headers", + "rows" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Inline JPEG / PNG / JPEG 2000 image. Without width/height the pixel size is used as points and clamped to the content width; with one dimension the aspect ratio is kept. The decoded bytes of all image blocks in one call are capped at 24 MiB (a watermark image has its own 8 MiB cap).", + "properties": { + "align": { + "default": "left", + "description": "Horizontal placement inside the content width.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + }, + "alt": { + "description": "Accessible description (tagged /Figure /Alt). Always provide it for non-decorative content under PDF/A or PDF/UA.", + "maxLength": 500, + "type": "string" + }, + "height": { + "description": "Render height in points.", + "maximum": 1000, + "minimum": 10, + "type": "number" + }, + "imageBase64": { + "description": "Base64 image bytes. JPEG (baseline; 1, 3 or 4 components — CMYK raises PDFA_DEVICE_CMYK_IMAGE under PDF/A), PNG (8-bit greyscale/RGB, non-interlaced; alpha-channel and palette PNGs are rejected with a remedy) or JPEG 2000 (JP2 file or raw .j2k codestream, passed through as /JPXDecode; PDF 1.5+, so PDFA1_JPX_IMAGE under pdfa1b). No data: URI.", + "maxLength": 12000000, + "minLength": 4, + "type": "string" + }, + "mimeType": { + "description": "MIME type of the image. Must match the actual encoding of imageBase64 (magic bytes are checked). 'image/jp2' accepts a JP2 file (.jp2/.jpx) or a raw JPEG 2000 codestream (.j2k/.j2c).", + "enum": [ + "image/jpeg", + "image/png", + "image/jp2" + ], + "type": "string" + }, + "type": { + "const": "image" + }, + "width": { + "description": "Render width in points.", + "maximum": 800, + "minimum": 10, + "type": "number" + } + }, + "required": [ + "type", + "imageBase64", + "mimeType" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Clickable external link (/URI action). Only http:, https: and mailto: URLs are accepted.", + "properties": { + "color": { + "anyOf": [ + { + "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } + ], + "description": "Hex colour (#RGB or #RRGGBB)." + }, + "fontSize": { + "description": "Default 10.", + "maximum": 48, + "minimum": 6, + "type": "number" + }, + "text": { + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "link" + }, + "url": { + "description": "http(s):// or mailto: URL.", + "maxLength": 2048, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "type", + "text", + "url" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Printed table of contents generated from the document's heading blocks (internal /GoTo links with dot leaders). Pairs with outline:'auto' for the bookmark pane.", + "properties": { + "fontSize": { + "description": "Default 10.", + "maximum": 24, + "minimum": 6, + "type": "number" + }, + "indent": { + "description": "Points of indent per heading level (default 15).", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxLevel": { + "description": "Deepest heading level listed (default 3).", + "enum": [ + 1, + 2, + 3 + ], + "type": "integer" + }, + "title": { + "description": "Default 'Table of Contents'.", + "maxLength": 200, + "type": "string" + }, + "type": { + "const": "toc" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Inline barcode — same body as add_barcode (pure vector, no /Alt available in the engine).", + "properties": { + "align": { + "default": "left", + "description": "Horizontal placement inside the content width.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + }, + "data": { + "description": "Raw payload to encode — do NOT URL-encode. For QR/URL pass e.g. \"https://example.com\" verbatim. EAN-13 must be 12 or 13 digits (13th is auto-computed). Code 128 accepts ASCII alphanumerics.", + "maxLength": 4296, + "minLength": 1, + "type": "string" + }, + "ecLevel": { + "default": "M", + "description": "QR ONLY. Error correction level (L=7%, M=15%, Q=25%, H=30%). Ignored for code128/ean13/datamatrix/pdf417. Use H for printed media that may get smudged or partially covered (e.g. logo overlay).", + "enum": [ + "L", + "M", + "Q", + "H" + ], + "type": "string" + }, + "format": { + "description": "Barcode symbology to render.", + "enum": [ + "qr", + "code128", + "ean13", + "datamatrix", + "pdf417" + ], + "type": "string" + }, + "height": { + "default": 200, + "description": "Barcode height in PDF points (ignored for square symbologies like QR/Data Matrix).", + "maximum": 500, + "minimum": 30, + "type": "number" + }, + "type": { + "const": "barcode" + }, + "width": { + "default": 200, + "description": "Barcode width in PDF points.", + "maximum": 500, + "minimum": 30, + "type": "number" + } + }, + "required": [ + "type", + "format", + "data" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Vector drawing from an SVG path `d` string or SVG markup. Supported: <path> <rect> (rx/ry) <circle> <ellipse> <line> <polyline> <polygon> and <text>/<tspan> (x, y, font-size, fill, text-anchor, dx/dy); fill / stroke / stroke-width attributes; double-quoted attributes only. NOT supported (silently ignored): transform, <g>, <use>, <image>, <defs>/<clipPath>, gradients, opacity, CSS/style, dash patterns, text word-wrap. No external reference is ever fetched (no XML parser: entities other than & < > " ' &#n; are dropped). Pure path operators — PDF/A-safe at every level.", + "properties": { + "align": { + "default": "left", + "description": "Horizontal placement inside the content width.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + }, + "alt": { + "description": "Accessible description (tagged /Figure /Alt). Always provide it for non-decorative content under PDF/A or PDF/UA.", + "maxLength": 500, + "type": "string" + }, + "data": { + "description": "Path `d` string or SVG markup (≤ 100 000 characters).", + "maxLength": 100000, + "minLength": 1, + "type": "string" + }, + "fill": { + "anyOf": [ + { + "pattern": "^(?:none|#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}))$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } + ], + "description": "Hex colour or 'none' (default black)." + }, + "height": { + "description": "Render height in points (default 200).", + "maximum": 1000, + "minimum": 10, + "type": "number" + }, + "stroke": { + "anyOf": [ + { + "pattern": "^(?:none|#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}))$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } + ], + "description": "Hex colour or 'none' (default none)." + }, + "strokeWidth": { + "description": "Stroke width in SVG user units (default 1).", + "maximum": 50, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "svg" + }, + "viewBox": { + "description": "[minX, minY, width, height] — overrides the viewBox of the markup; required for a bare path string that is not 0-based.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "width": { + "description": "Render width in points (default 200).", + "maximum": 800, + "minimum": 10, + "type": "number" + } + }, + "required": [ + "type", + "data" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Inline AcroForm field — same body as an add_form field. Under a PDF/A claim pass embedFonts:true so the field font is embedded too (PDFA_UNEMBEDDED_FORM_FONT otherwise; strict:true then fails the call).", + "properties": { + "checked": { + "description": "Initial checked state for checkbox / radio fields.", + "type": "boolean" + }, + "fieldType": { + "description": "Type of form control to render. Radio fields sharing a name form one radio group.", + "enum": [ + "text", + "textarea", + "checkbox", + "radio", + "dropdown", + "listbox" + ], + "type": "string" + }, + "fontSize": { + "description": "Font size for text rendering inside the field.", + "maximum": 48, + "minimum": 6, + "type": "number" + }, + "height": { + "description": "Field height in points (default depends on the type).", + "maximum": 300, + "minimum": 10, + "type": "number" + }, + "label": { + "description": "Human-readable label shown above the field.", + "maxLength": 200, + "type": "string" + }, + "maxLength": { + "description": "Maximum character length for text/textarea fields.", + "maximum": 32767, + "minimum": 1, + "type": "integer" + }, + "name": { + "description": "Unique field name used as the PDF annotation identifier (/T).", + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "options": { + "description": "Choices for dropdown, listbox or radio fields.", + "items": { + "maxLength": 200, + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "placeholder": { + "description": "Hint text shown while the field is empty.", + "maxLength": 200, + "type": "string" + }, + "readOnly": { + "description": "Prevent editing of this field.", + "type": "boolean" + }, + "required": { + "description": "Mark field as required.", + "type": "boolean" + }, + "type": { + "const": "formField" + }, + "value": { + "description": "Pre-filled value. The key is 'value' (there is no defaultValue).", + "maxLength": 2000, + "type": "string" + }, + "width": { + "description": "Field width in points (default: full content width).", + "maximum": 500, + "minimum": 10, + "type": "number" + } + }, + "required": [ + "type", + "fieldType", + "name" + ], + "type": "object" + } +] - added
Input schema / properties / directionAdded value: +{ + "description": "Base text direction (UAX #9): 'auto' reads each paragraph's first strong character and right-aligns RTL ones; 'ltr' / 'rtl' force it. A paragraph's own direction overrides it. Omitted = LTR (1.7.0 bytes).", + "enum": [ + "auto", + "ltr", + "rtl" + ], + "type": "string" +} - added
Input schema / properties / fontAdded value: +{ + "description": "Operator-registered custom font (the slug of a .ttf / .otf file in PDFNATIVE_MCP_FONT_DIR, e.g. 'brand-sans'): drawn first, with the bundled faces as fallbacks. Unknown slug → FONT_NOT_FOUND listing the registered ones; always embedded, so valid under PDF/A.", + "maxLength": 64, + "pattern": "^[a-z0-9][a-z0-9-]{0,63}$", + "type": "string" +} - changed
Input schema / properties / footerTemplate / properties / color / anyOfPrevious value: -[ - { - "pattern": "^#[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - changed
Input schema / properties / headerTemplate / properties / color / anyOfPrevious value: -[ - { - "pattern": "^#[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - changed
Input schema / properties / includeDiagnostics / descriptionPrevious value: -"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*) as `diagnostics[]` (possibly empty)."New value: +"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*, TEXT_GLYPH_NOT_COVERED) as `diagnostics[]` (possibly empty)." - changed
Input schema / properties / outline / oneOfPrevious value: -[ - { - "enum": [ - "auto" - ], - "type": "string" - }, - { - "items": { - "additionalProperties": false, - "properties": { - "bold": { - "type": "boolean" - }, - "children": { - "items": { - "additionalProperties": false, - "properties": { - "bold": { - "type": "boolean" - }, - "children": { - "items": { - "additionalProperties": false, - "properties": { - "bold": { - "type": "boolean" - }, - "children": { - "items": { - "additionalProperties": false, - "properties": { - "bold": { - "type": "boolean" - }, - "children": { - "items": { - "additionalProperties": false, - "properties": { - "bold": { - "type": "boolean" - }, - "children": { - "items": { - "additionalProperties": false, - "properties": { - "bold": { - "type": "boolean" - }, - "color": { - "anyOf": [ - { - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } - ], - "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1'). An outline label is RGB by definition (/C): a CMYK value is converted for on-screen display." - }, - "italic": { - "type": "boolean" - }, - "open": { - "description": "Initial expansion state (default true). false renders the branch collapsed.", - "type": "boolean" - }, - "pageIndex": { - "description": "0-based destination page index.", - "minimum": 0, - "type": "integer" - }, - "title": { - "description": "Bookmark label.", - "maxLength": 500, - "minLength": 1, - "type": "string" - }, - "y": { - "description": "Destination Y coordinate in points (default: top of page).", - "type": "number" - } - }, - "required": [ - "title", - "pageIndex" - ], - "type": "object" - }, - "maxItems": 1000, - "type": "array" - }, - "color": { - "anyOf": [ - { - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } - ], - "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1'). An outline label is RGB by definition (/C): a CMYK value is converted for on-screen display." - }, - "italic": { - "type": "boolean" - }, - "open": { - "description": "Initial expansion state (default true). false renders the branch collapsed.", - "type": "boolean" - }, - "pageIndex": { - "description": "0-based destination page index.", - "minimum": 0, - "type": "integer" - }, - "title": { - "description": "Bookmark label.", - "maxLength": 500, - "minLength": 1, - "type": "string" - }, - "y": { - "description": "Destination Y coordinate in points (default: top of page).", - "type": "number" - } - }, - "required": [ - "title", - "pageIndex" - ], - "type": "object" - }, - "maxItems": 1000, - "type": "array" - }, - "color": { - "anyOf": [ - { - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } - ], - "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1'). An outline label is RGB by definition (/C): a CMYK value is converted for on-screen display." - }, - "italic": { - "type": "boolean" - }, - "open": { - "description": "Initial expansion state (default true). false renders the branch collapsed.", - "type": "boolean" - }, - "pageIndex": { - "description": "0-based destination page index.", - "minimum": 0, - "type": "integer" - }, - "title": { - "description": "Bookmark label.", - "maxLength": 500, - "minLength": 1, - "type": "string" - }, - "y": { - "description": "Destination Y coordinate in points (default: top of page).", - "type": "number" - } - }, - "required": [ - "title", - "pageIndex" - ], - "type": "object" - }, - "maxItems": 1000, - "type": "array" - }, - "color": { - "anyOf": [ - { - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } - ], - "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1'). An outline label is RGB by definition (/C): a CMYK value is converted for on-screen display." - }, - "italic": { - "type": "boolean" - }, - "open": { - "description": "Initial expansion state (default true). false renders the branch collapsed.", - "type": "boolean" - }, - "pageIndex": { - "description": "0-based destination page index.", - "minimum": 0, - "type": "integer" - }, - "title": { - "description": "Bookmark label.", - "maxLength": 500, - "minLength": 1, - "type": "string" - }, - "y": { - "description": "Destination Y coordinate in points (default: top of page).", - "type": "number" - } - }, - "required": [ - "title", - "pageIndex" - ], - "type": "object" - }, - "maxItems": 1000, - "type": "array" - }, - "color": { - "anyOf": [ - { - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } - ], - "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1'). An outline label is RGB by definition (/C): a CMYK value is converted for on-screen display." - }, - "italic": { - "type": "boolean" - }, - "open": { - "description": "Initial expansion state (default true). false renders the branch collapsed.", - "type": "boolean" - }, - "pageIndex": { - "description": "0-based destination page index.", - "minimum": 0, - "type": "integer" - }, - "title": { - "description": "Bookmark label.", - "maxLength": 500, - "minLength": 1, - "type": "string" - }, - "y": { - "description": "Destination Y coordinate in points (default: top of page).", - "type": "number" - } - }, - "required": [ - "title", - "pageIndex" - ], - "type": "object" - }, - "maxItems": 1000, - "type": "array" - }, - "color": { - "anyOf": [ - { - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } - ], - "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1'). An outline label is RGB by definition (/C): a CMYK value is converted for on-screen display." - }, - "italic": { - "type": "boolean" - }, - "open": { - "description": "Initial expansion state (default true). false renders the branch collapsed.", - "type": "boolean" - }, - "pageIndex": { - "description": "0-based destination page index.", - "minimum": 0, - "type": "integer" - }, - "title": { - "description": "Bookmark label.", - "maxLength": 500, - "minLength": 1, - "type": "string" - }, - "y": { - "description": "Destination Y coordinate in points (default: top of page).", - "type": "number" - } - }, - "required": [ - "title", - "pageIndex" - ], - "type": "object" - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - } -]New value: +[ + { + "enum": [ + "auto" + ], + "type": "string" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "bold": { + "type": "boolean" + }, + "children": { + "items": { + "additionalProperties": false, + "properties": { + "bold": { + "type": "boolean" + }, + "children": { + "items": { + "additionalProperties": false, + "properties": { + "bold": { + "type": "boolean" + }, + "children": { + "items": { + "additionalProperties": false, + "properties": { + "bold": { + "type": "boolean" + }, + "children": { + "items": { + "additionalProperties": false, + "properties": { + "bold": { + "type": "boolean" + }, + "children": { + "items": { + "additionalProperties": false, + "properties": { + "bold": { + "type": "boolean" + }, + "color": { + "anyOf": [ + { + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } + ], + "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1'). An outline label is RGB by definition (/C): a CMYK value is converted for on-screen display." + }, + "italic": { + "type": "boolean" + }, + "open": { + "description": "Initial expansion state (default true). false renders the branch collapsed.", + "type": "boolean" + }, + "pageIndex": { + "description": "0-based destination page index.", + "minimum": 0, + "type": "integer" + }, + "title": { + "description": "Bookmark label.", + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "y": { + "description": "Destination Y coordinate in points (default: top of page).", + "type": "number" + } + }, + "required": [ + "title", + "pageIndex" + ], + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "color": { + "anyOf": [ + { + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } + ], + "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1'). An outline label is RGB by definition (/C): a CMYK value is converted for on-screen display." + }, + "italic": { + "type": "boolean" + }, + "open": { + "description": "Initial expansion state (default true). false renders the branch collapsed.", + "type": "boolean" + }, + "pageIndex": { + "description": "0-based destination page index.", + "minimum": 0, + "type": "integer" + }, + "title": { + "description": "Bookmark label.", + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "y": { + "description": "Destination Y coordinate in points (default: top of page).", + "type": "number" + } + }, + "required": [ + "title", + "pageIndex" + ], + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "color": { + "anyOf": [ + { + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } + ], + "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1'). An outline label is RGB by definition (/C): a CMYK value is converted for on-screen display." + }, + "italic": { + "type": "boolean" + }, + "open": { + "description": "Initial expansion state (default true). false renders the branch collapsed.", + "type": "boolean" + }, + "pageIndex": { + "description": "0-based destination page index.", + "minimum": 0, + "type": "integer" + }, + "title": { + "description": "Bookmark label.", + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "y": { + "description": "Destination Y coordinate in points (default: top of page).", + "type": "number" + } + }, + "required": [ + "title", + "pageIndex" + ], + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "color": { + "anyOf": [ + { + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } + ], + "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1'). An outline label is RGB by definition (/C): a CMYK value is converted for on-screen display." + }, + "italic": { + "type": "boolean" + }, + "open": { + "description": "Initial expansion state (default true). false renders the branch collapsed.", + "type": "boolean" + }, + "pageIndex": { + "description": "0-based destination page index.", + "minimum": 0, + "type": "integer" + }, + "title": { + "description": "Bookmark label.", + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "y": { + "description": "Destination Y coordinate in points (default: top of page).", + "type": "number" + } + }, + "required": [ + "title", + "pageIndex" + ], + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "color": { + "anyOf": [ + { + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } + ], + "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1'). An outline label is RGB by definition (/C): a CMYK value is converted for on-screen display." + }, + "italic": { + "type": "boolean" + }, + "open": { + "description": "Initial expansion state (default true). false renders the branch collapsed.", + "type": "boolean" + }, + "pageIndex": { + "description": "0-based destination page index.", + "minimum": 0, + "type": "integer" + }, + "title": { + "description": "Bookmark label.", + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "y": { + "description": "Destination Y coordinate in points (default: top of page).", + "type": "number" + } + }, + "required": [ + "title", + "pageIndex" + ], + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "color": { + "anyOf": [ + { + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } + ], + "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1'). An outline label is RGB by definition (/C): a CMYK value is converted for on-screen display." + }, + "italic": { + "type": "boolean" + }, + "open": { + "description": "Initial expansion state (default true). false renders the branch collapsed.", + "type": "boolean" + }, + "pageIndex": { + "description": "0-based destination page index.", + "minimum": 0, + "type": "integer" + }, + "title": { + "description": "Bookmark label.", + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "y": { + "description": "Destination Y coordinate in points (default: top of page).", + "type": "number" + } + }, + "required": [ + "title", + "pageIndex" + ], + "type": "object" + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + } +] - changed
Input schema / properties / pdfx / descriptionPrevious value: -"PDF/X-4 print exchange (ISO 15930-7). REQUIRES outputIntent with the printer's ICC profile (device class 'prtr'; CMYK or Gray — none is bundled); needs embedFonts:true for a conformant file (PDFX_NO_FONT_ENTRIES otherwise, strict:true refuses). Exclusive with pdfA and encrypt; metadata.trapped must be 'True' or 'False'; TrimBox or ArtBox, not both. Links and form fields are reported (PDFX_ANNOTATIONS). Check with validate_pdf standard:'pdf-x-4'. See the print_ready prompt."New value: +"PDF/X-4 print exchange (ISO 15930-7). REQUIRES outputIntent with the printer's ICC profile (device class 'prtr'; CMYK or Gray — none is bundled); needs embedFonts:true for a conformant file (PDFX_NO_FONT_ENTRIES otherwise, strict:true refuses). Combines with pdfA:'pdfa2b' | 'pdfa2u' (dual claim) but not pdfa1b / pdfa3b; exclusive with encrypt; metadata.trapped must be 'True' or 'False'; TrimBox or ArtBox, not both. Links and form fields are reported (PDFX_ANNOTATIONS). Check with validate_pdf standard:'pdf-x-4'. See the print_ready prompt." - changed
Input schema / properties / print / descriptionPrevious value: -"Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b). See docs/guides/PRINT.md."New value: +"Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b), `spotColours` ink declarations. See docs/guides/PRINT.md." - added
Input schema / properties / print / properties / spotColoursAdded value: +{ + "description": "Spot inks (/Separation plates) the document may paint with { spot:'name', tint } or { inks:{ name: tint } } anywhere a colour is accepted. Undeclared ink → VALIDATION_ERROR; blank or duplicate name → PRINT_ERROR (an empty string is VALIDATION_ERROR).", + "items": { + "additionalProperties": false, + "properties": { + "alternate": { + "anyOf": [ + { + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "items": { + "maximum": 255, + "minimum": 0, + "type": "number" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" + } + ], + "description": "Process alternate for proofing: [c, m, y, k] 0–100 or [r, g, b] 0–255." + }, + "name": { + "description": "'PANTONE 300 C', 'Varnish', …", + "maxLength": 100, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "name", + "alternate" + ], + "type": "object" + }, + "maxItems": 32, + "minItems": 1, + "type": "array" +} - changed
Input schema / properties / strict / descriptionPrevious value: -"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true."New value: +"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other (TYPOGRAPHY_FEATURE_INEFFECTIVE, TEXT_GLYPH_NOT_COVERED — a character no font covers, drawn as a box or '?') → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true." - changed
Input schema / properties / typography / descriptionPrevious value: -"Fine typography, all opt-in (omitted = unchanged bytes). kerning, fontFeatures and the 'fr' narrow space need embedFonts:true. No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt."New value: +"Fine typography, all opt-in (omitted = unchanged bytes). kerning and fontFeatures need embedFonts:true ('fr' works on base-14 too). No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt." - changed
Input schema / properties / typography / properties / punctuationSpacing / anyOfPrevious value: -[ - { - "enum": [ - "fr", - "fr-CA" - ], - "type": "string" - }, - { - "items": { - "additionalProperties": false, - "properties": { - "char": { - "maxLength": 2, - "minLength": 1, - "type": "string" - }, - "side": { - "enum": [ - "before", - "after" - ], - "type": "string" - }, - "space": { - "description": "U+00A0 / U+202F (narrow needs embedFonts).", - "enum": [ - "nbsp", - "narrow" - ], - "type": "string" - } - }, - "required": [ - "char", - "side", - "space" - ], - "type": "object" - }, - "maxItems": 32, - "type": "array" - } -]New value: +[ + { + "enum": [ + "fr", + "fr-CA" + ], + "type": "string" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "char": { + "maxLength": 2, + "minLength": 1, + "type": "string" + }, + "side": { + "enum": [ + "before", + "after" + ], + "type": "string" + }, + "space": { + "description": "U+00A0 / U+202F (narrow: a TJ adjustment on base-14, the glyph on an embedded font).", + "enum": [ + "nbsp", + "narrow" + ], + "type": "string" + } + }, + "required": [ + "char", + "side", + "space" + ], + "type": "object" + }, + "maxItems": 32, + "type": "array" + } +] - changed
Input schema / properties / watermark / descriptionPrevious value: -"Optional semi-transparent watermark rendered centred on every page: `text` (e.g. 'DRAFT'), `image` (JPEG/PNG), or both combined. At least one of text / image is required. opacity < 1.0 (text or image, including the defaults) is rejected under pdfA='pdfa1b' (ISO 19005-1 forbids transparency)."New value: +"Optional semi-transparent watermark rendered centred on every page: `text` (e.g. 'DRAFT'), `image` (JPEG/PNG/JPEG 2000), or both combined. At least one of text / image is required. opacity < 1.0 (text or image, including the defaults) is rejected under pdfA='pdfa1b' (ISO 19005-1 forbids transparency)." - changed
Input schema / properties / watermark / properties / color / anyOfPrevious value: -[ - { - "items": { - "maximum": 1, - "minimum": 0, - "type": "number" - }, - "maxItems": 3, - "minItems": 3, - "type": "array" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "items": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - changed
Input schema / properties / watermark / properties / image / descriptionPrevious value: -"Image watermark (JPEG or PNG) centred on every page, optionally combined with `text`. Bytes are validated against the JPEG/PNG magic numbers; mimeType must match."New value: +"Image watermark (JPEG, PNG or JPEG 2000) centred on every page, optionally combined with `text`. Bytes are validated against the format magic numbers; mimeType must match." - changed
Input schema / properties / watermark / properties / image / properties / imageBase64 / descriptionPrevious value: -"Base64-encoded JPEG or 8-bit opaque PNG bytes (max 8 MiB decoded; alpha-channel, palette and interlaced PNGs are rejected with a remedy). Plain base64, no data: URI prefix."New value: +"Base64-encoded JPEG, 8-bit opaque PNG or JPEG 2000 (JP2 / raw codestream) bytes (max 8 MiB decoded; alpha-channel, palette and interlaced PNGs are rejected with a remedy; a JPEG 2000 opacity channel raises PDFA_JPX_IMAGE under PDF/A). Plain base64, no data: URI prefix." - changed
Input schema / properties / watermark / properties / image / properties / mimeType / descriptionPrevious value: -"'image/jpeg' or 'image/png' — must match the actual bytes."New value: +"'image/jpeg', 'image/png' or 'image/jp2' — must match the actual bytes." - changed
Input schema / properties / watermark / properties / image / properties / mimeType / enumPrevious value: -[ - "image/jpeg", - "image/png" -]New value: +[ + "image/jpeg", + "image/png", + "image/jp2" +] - changed
Output schema / descriptionPrevious value: -"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath` (and `url` when the operator maps the sandbox to a public base URL)." - added
Output schema / properties / urlAdded value: +{ + "description": "Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded.", + "type": "string" +}
- Changed
inspect_layout8 fields changed- added
Input schema / properties / actualTextAdded value: +{ + "description": "Untagged output: wrap reordered shaped runs and RTL runs in /ActualText so extract_text returns reading order. Default true; false = bare 1.7.0 glyph runs. No effect on tagged (pdfA) output.", + "type": "boolean" +} - changed
Input schema / properties / blocks / items / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "keepWithNext": { - "description": "Keep this heading on the same page as the block that follows. Overrides typography.keepHeadingsWithNext for this block, either way.", - "type": "boolean" - }, - "level": { - "enum": [ - 1, - 2, - 3 - ], - "type": "integer" - }, - "text": { - "maxLength": 500, - "minLength": 1, - "type": "string" - }, - "type": { - "const": "heading" - } - }, - "required": [ - "type", - "text", - "level" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "align": { - "description": "Text alignment (default left). 'justify' spans every line but the last across the measure; pair it with typography.opticalMargins.", - "enum": [ - "left", - "right", - "center", - "justify" - ], - "type": "string" - }, - "keepWithNext": { - "description": "Keep this paragraph on the same page as the block that follows (a lead-in line before a table or figure). Default false.", - "type": "boolean" - }, - "splittable": { - "description": "Allow / forbid this paragraph breaking across pages, overriding typography.splitParagraphs for this block.", - "type": "boolean" - }, - "text": { - "description": "Paragraph text. Embedded newlines ('\\n') are automatically split into separate paragraphs — no need to pre-split; never emit a literal newline expecting a soft line break.", - "maxLength": 50000, - "minLength": 1, - "type": "string" - }, - "type": { - "const": "paragraph" - } - }, - "required": [ - "type", - "text" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "description": "List items. A string is a leaf; an object { text, items } nests a sub-list (bullets/numbers indent; numbered sub-lists restart at 1).", - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "style": { - "default": "bullet", - "enum": [ - "bullet", - "numbered" - ], - "type": "string" - }, - "type": { - "const": "list" - } - }, - "required": [ - "type", - "items" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "type": { - "const": "pageBreak" - } - }, - "required": [ - "type" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "height": { - "maximum": 500, - "minimum": 1, - "type": "number" - }, - "type": { - "const": "spacer" - } - }, - "required": [ - "type", - "height" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Native vector chart rendered as pure PDF path operators — bar / horizontal-bar / stacked-bar / line / area / scatter / pie / donut (pdfnative 1.7 charts v2: time and log axes, data labels, secondary axis, legends). Same body as add_chart.", - "properties": { - "align": { - "description": "Horizontal alignment within the content width. Default 'left'.", - "enum": [ - "left", - "center", - "right" - ], - "type": "string" - }, - "altText": { - "description": "Alt text for the tagged-PDF /Figure /Alt. Auto-generated when omitted.", - "maxLength": 500, - "type": "string" - }, - "axis": { - "additionalProperties": false, - "description": "Value-axis options (bar/line only).", - "properties": { - "grid": { - "description": "Draw horizontal gridlines.", - "type": "boolean" - }, - "scale": { - "description": "Value-axis scale. 'log' requires strictly positive values and is not available for stacked charts.", - "enum": [ - "linear", - "log" - ], - "type": "string" - }, - "ticks": { - "description": "Target tick count (nice 1/2/5×10ⁿ steps).", - "maximum": 20, - "minimum": 2, - "type": "integer" - }, - "yMax": { - "description": "Force the axis maximum (values are clamped to the plot band).", - "type": "number" - }, - "yMin": { - "description": "Force the axis minimum (values are clamped to the plot band).", - "type": "number" - } - }, - "type": "object" - }, - "axis2": { - "additionalProperties": false, - "description": "Secondary RIGHT value axis (drawn only when a series sets yAxis:'right').", - "properties": { - "scale": { - "enum": [ - "linear", - "log" - ], - "type": "string" - }, - "ticks": { - "maximum": 20, - "minimum": 2, - "type": "integer" - }, - "yMax": { - "type": "number" - }, - "yMin": { - "type": "number" - } - }, - "type": "object" - }, - "categories": { - "description": "Category / slice labels (x-axis). Defaults to 1-based indices when omitted.", - "items": { - "maxLength": 200, - "type": "string" - }, - "maxItems": 1000, - "type": "array" - }, - "chartType": { - "description": "Chart kind. 'pie'/'donut' use exactly one series; 'bar'/'barH'/'stackedBar'/'stackedBarH'/'line'/'area'/'scatter' support multiple series. 'scatter' requires xValues on every series and a positional xAxis.type ('linear' or 'time').", - "enum": [ - "bar", - "barH", - "stackedBar", - "stackedBarH", - "line", - "area", - "scatter", - "pie", - "donut" - ], - "type": "string" - }, - "colors": { - "description": "Palette override (per-series for bar/line, per-slice for pie/donut).", - "items": { - "anyOf": [ - { - "pattern": "^#?[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } - ], - "description": "CSS-style hex colour, e.g. \"#3366cc\"." - }, - "maxItems": 50, - "type": "array" - }, - "dataLabels": { - "description": "Per-point value labels: true for defaults, or an object to format them.", - "oneOf": [ - { - "type": "boolean" - }, - { - "additionalProperties": false, - "properties": { - "decimals": { - "maximum": 6, - "minimum": 0, - "type": "integer" - }, - "prefix": { - "maxLength": 16, - "type": "string" - }, - "suffix": { - "maxLength": 16, - "type": "string" - } - }, - "type": "object" - } - ] - }, - "height": { - "description": "Plot-area height in points. Default 240.", - "maximum": 2000, - "minimum": 50, - "type": "number" - }, - "labelRotation": { - "description": "Rotate category labels counter-clockwise by this many degrees (disables the automatic stride).", - "maximum": 90, - "minimum": 0, - "type": "number" - }, - "labelStride": { - "description": "Draw every Nth category label. Default: automatic (measured non-overlap); 1 draws every label.", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "legend": { - "description": "Legend placement. Defaults to 'bottom' for multi-series/pie, else 'none'.", - "enum": [ - "bottom", - "none" - ], - "type": "string" - }, - "markers": { - "description": "Draw point markers on line series. Default false.", - "type": "boolean" - }, - "series": { - "description": "Data series. Pie/donut charts use exactly one series (each value becomes a slice).", - "items": { - "additionalProperties": false, - "properties": { - "color": { - "anyOf": [ - { - "pattern": "^#?[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } - ], - "description": "CSS-style hex colour, e.g. \"#3366cc\"." - }, - "label": { - "description": "Series label (shown in the legend).", - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "values": { - "description": "Numeric values, one per category. Negative values are supported for bar/line.", - "items": { - "type": "number" - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "xValues": { - "description": "Per-point x positions (same length as values) for scatter charts and for line/area charts with xAxis.type 'linear' or 'time'.", - "items": { - "description": "Positional x value: a number (linear axis) or an ISO-8601 date / epoch milliseconds (time axis).", - "maxLength": 64, - "type": [ - "number", - "string" - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "yAxis": { - "description": "Bind the series to the left (default) or the secondary right value axis (cartesian charts only; configure its range with 'axis2').", - "enum": [ - "left", - "right" - ], - "type": "string" - } - }, - "required": [ - "label", - "values" - ], - "type": "object" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "title": { - "description": "Chart title rendered above the plot.", - "maxLength": 200, - "type": "string" - }, - "type": { - "const": "chart" - }, - "width": { - "description": "Plot width in points (clamped to content width). Default 460.", - "maximum": 2000, - "minimum": 50, - "type": "number" - }, - "xAxis": { - "additionalProperties": false, - "description": "Horizontal axis. 'category' (default) positions points by index; 'linear' / 'time' position them by series xValues (line/area/scatter only). Time ticks are UTC-deterministic.", - "properties": { - "grid": { - "description": "Draw vertical gridlines.", - "type": "boolean" - }, - "max": { - "description": "Axis maximum (number, or ISO-8601 / epoch ms for time axes).", - "maxLength": 64, - "type": [ - "number", - "string" - ] - }, - "min": { - "description": "Axis minimum (number, or ISO-8601 / epoch ms for time axes).", - "maxLength": 64, - "type": [ - "number", - "string" - ] - }, - "ticks": { - "maximum": 20, - "minimum": 2, - "type": "integer" - }, - "type": { - "enum": [ - "category", - "linear", - "time" - ], - "type": "string" - } - }, - "type": "object" - } - }, - "required": [ - "type", - "chartType", - "series" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Inline smart table — same body as add_table (every row must have exactly as many cells as headers).", - "properties": { - "autoFitColumns": { - "description": "Auto-fit column widths to content. Output bytes then depend on text metrics (not byte-deterministic across content changes).", - "type": "boolean" - }, - "caption": { - "description": "Caption rendered above the table (tagged as /Caption under PDF/A).", - "maxLength": 200, - "type": "string" - }, - "cellBorders": { - "additionalProperties": false, - "description": "Per-cell vector borders (pure strokes, PDF/A-safe). Choose individual sides or `all`.", - "properties": { - "all": { - "description": "Draw all four edges (overrides the individual side flags).", - "type": "boolean" - }, - "bottom": { - "type": "boolean" - }, - "color": { - "anyOf": [ - { - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } - ], - "description": "Stroke colour as a PDF operator string ('0.8 0.8 0.8') or hex. Default light grey." - }, - "left": { - "type": "boolean" - }, - "right": { - "type": "boolean" - }, - "style": { - "description": "Stroke style (default 'solid').", - "enum": [ - "solid", - "dashed", - "dotted" - ], - "type": "string" - }, - "top": { - "type": "boolean" - }, - "width": { - "description": "Stroke width in points (default 0.5).", - "maximum": 10, - "minimum": 0, - "type": "number" - } - }, - "type": "object" - }, - "cellPadding": { - "description": "Horizontal cell padding in points (default 3).", - "maximum": 50, - "minimum": 0, - "type": "number" - }, - "cellVAlign": { - "description": "Vertical alignment of cell content.", - "enum": [ - "top", - "middle", - "bottom" - ], - "type": "string" - }, - "clipCells": { - "description": "Clip cell contents to the column bounds (PDF clip operators). Recommended for PDF/A and visual safety.", - "type": "boolean" - }, - "headers": { - "description": "Column header labels. Must have the same length as each row in `rows`.", - "items": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "minRowHeight": { - "description": "Minimum row height in points (default 12).", - "maximum": 200, - "minimum": 1, - "type": "number" - }, - "repeatHeader": { - "description": "Repeat the header row on every continuation page (default true).", - "type": "boolean" - }, - "rows": { - "description": "Data rows. Each row is an array of cell strings with the same length as `headers`.", - "items": { - "items": { - "maxLength": 500, - "type": "string" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "maxItems": 5000, - "minItems": 1, - "type": "array" - }, - "type": { - "const": "table" - }, - "wrap": { - "description": "Cell wrap policy: 'auto' (default) wraps only overflowing cells; 'always' wraps every cell; 'never' truncates.", - "enum": [ - "auto", - "always", - "never" - ], - "type": "string" - }, - "zebra": { - "description": "Alternate-row light tint (static fill, PDF/A-1b safe).", - "type": "boolean" - } - }, - "required": [ - "type", - "headers", - "rows" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Inline JPEG/PNG image. Without width/height the pixel size is used as points and clamped to the content width; with one dimension the aspect ratio is kept. The decoded bytes of all image blocks in one call are capped at 24 MiB (a watermark image has its own 8 MiB cap).", - "properties": { - "align": { - "default": "left", - "description": "Horizontal placement inside the content width.", - "enum": [ - "left", - "center", - "right" - ], - "type": "string" - }, - "alt": { - "description": "Accessible description (tagged /Figure /Alt). Always provide it for non-decorative content under PDF/A or PDF/UA.", - "maxLength": 500, - "type": "string" - }, - "height": { - "description": "Render height in points.", - "maximum": 1000, - "minimum": 10, - "type": "number" - }, - "imageBase64": { - "description": "Base64 image bytes. JPEG (baseline; 1, 3 or 4 components — CMYK raises PDFA_DEVICE_CMYK_IMAGE under PDF/A) or PNG (8-bit greyscale/RGB, non-interlaced; alpha-channel and palette PNGs are rejected with a remedy). No data: URI.", - "maxLength": 12000000, - "minLength": 4, - "type": "string" - }, - "mimeType": { - "description": "MIME type of the image. Must match the actual encoding of imageBase64 (magic bytes are checked).", - "enum": [ - "image/jpeg", - "image/png" - ], - "type": "string" - }, - "type": { - "const": "image" - }, - "width": { - "description": "Render width in points.", - "maximum": 800, - "minimum": 10, - "type": "number" - } - }, - "required": [ - "type", - "imageBase64", - "mimeType" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Clickable external link (/URI action). Only http:, https: and mailto: URLs are accepted.", - "properties": { - "color": { - "anyOf": [ - { - "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } - ], - "description": "Hex colour (#RGB or #RRGGBB)." - }, - "fontSize": { - "description": "Default 10.", - "maximum": 48, - "minimum": 6, - "type": "number" - }, - "text": { - "maxLength": 500, - "minLength": 1, - "type": "string" - }, - "type": { - "const": "link" - }, - "url": { - "description": "http(s):// or mailto: URL.", - "maxLength": 2048, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "type", - "text", - "url" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Printed table of contents generated from the document's heading blocks (internal /GoTo links with dot leaders). Pairs with outline:'auto' for the bookmark pane.", - "properties": { - "fontSize": { - "description": "Default 10.", - "maximum": 24, - "minimum": 6, - "type": "number" - }, - "indent": { - "description": "Points of indent per heading level (default 15).", - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxLevel": { - "description": "Deepest heading level listed (default 3).", - "enum": [ - 1, - 2, - 3 - ], - "type": "integer" - }, - "title": { - "description": "Default 'Table of Contents'.", - "maxLength": 200, - "type": "string" - }, - "type": { - "const": "toc" - } - }, - "required": [ - "type" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Inline barcode — same body as add_barcode (pure vector, no /Alt available in the engine).", - "properties": { - "align": { - "default": "left", - "description": "Horizontal placement inside the content width.", - "enum": [ - "left", - "center", - "right" - ], - "type": "string" - }, - "data": { - "description": "Raw payload to encode — do NOT URL-encode. For QR/URL pass e.g. \"https://example.com\" verbatim. EAN-13 must be 12 or 13 digits (13th is auto-computed). Code 128 accepts ASCII alphanumerics.", - "maxLength": 4296, - "minLength": 1, - "type": "string" - }, - "ecLevel": { - "default": "M", - "description": "QR ONLY. Error correction level (L=7%, M=15%, Q=25%, H=30%). Ignored for code128/ean13/datamatrix/pdf417. Use H for printed media that may get smudged or partially covered (e.g. logo overlay).", - "enum": [ - "L", - "M", - "Q", - "H" - ], - "type": "string" - }, - "format": { - "description": "Barcode symbology to render.", - "enum": [ - "qr", - "code128", - "ean13", - "datamatrix", - "pdf417" - ], - "type": "string" - }, - "height": { - "default": 200, - "description": "Barcode height in PDF points (ignored for square symbologies like QR/Data Matrix).", - "maximum": 500, - "minimum": 30, - "type": "number" - }, - "type": { - "const": "barcode" - }, - "width": { - "default": 200, - "description": "Barcode width in PDF points.", - "maximum": 500, - "minimum": 30, - "type": "number" - } - }, - "required": [ - "type", - "format", - "data" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Vector drawing from an SVG path `d` string or SVG markup. Supported: <path> <rect> (rx/ry) <circle> <ellipse> <line> <polyline> <polygon> and <text>/<tspan> (x, y, font-size, fill, text-anchor, dx/dy); fill / stroke / stroke-width attributes; double-quoted attributes only. NOT supported (silently ignored): transform, <g>, <use>, <image>, <defs>/<clipPath>, gradients, opacity, CSS/style, dash patterns, text word-wrap. No external reference is ever fetched (no XML parser: entities other than & < > " ' &#n; are dropped). Pure path operators — PDF/A-safe at every level.", - "properties": { - "align": { - "default": "left", - "description": "Horizontal placement inside the content width.", - "enum": [ - "left", - "center", - "right" - ], - "type": "string" - }, - "alt": { - "description": "Accessible description (tagged /Figure /Alt). Always provide it for non-decorative content under PDF/A or PDF/UA.", - "maxLength": 500, - "type": "string" - }, - "data": { - "description": "Path `d` string or SVG markup (≤ 100 000 characters).", - "maxLength": 100000, - "minLength": 1, - "type": "string" - }, - "fill": { - "anyOf": [ - { - "pattern": "^(?:none|#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}))$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } - ], - "description": "Hex colour or 'none' (default black)." - }, - "height": { - "description": "Render height in points (default 200).", - "maximum": 1000, - "minimum": 10, - "type": "number" - }, - "stroke": { - "anyOf": [ - { - "pattern": "^(?:none|#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}))$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } - ], - "description": "Hex colour or 'none' (default none)." - }, - "strokeWidth": { - "description": "Stroke width in SVG user units (default 1).", - "maximum": 50, - "minimum": 0, - "type": "number" - }, - "type": { - "const": "svg" - }, - "viewBox": { - "description": "[minX, minY, width, height] — overrides the viewBox of the markup; required for a bare path string that is not 0-based.", - "items": { - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - }, - "width": { - "description": "Render width in points (default 200).", - "maximum": 800, - "minimum": 10, - "type": "number" - } - }, - "required": [ - "type", - "data" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Inline AcroForm field — same body as an add_form field. Under a PDF/A claim pass embedFonts:true so the field font is embedded too (PDFA_UNEMBEDDED_FORM_FONT otherwise; strict:true then fails the call).", - "properties": { - "checked": { - "description": "Initial checked state for checkbox / radio fields.", - "type": "boolean" - }, - "fieldType": { - "description": "Type of form control to render. Radio fields sharing a name form one radio group.", - "enum": [ - "text", - "textarea", - "checkbox", - "radio", - "dropdown", - "listbox" - ], - "type": "string" - }, - "fontSize": { - "description": "Font size for text rendering inside the field.", - "maximum": 48, - "minimum": 6, - "type": "number" - }, - "height": { - "description": "Field height in points (default depends on the type).", - "maximum": 300, - "minimum": 10, - "type": "number" - }, - "label": { - "description": "Human-readable label shown above the field.", - "maxLength": 200, - "type": "string" - }, - "maxLength": { - "description": "Maximum character length for text/textarea fields.", - "maximum": 32767, - "minimum": 1, - "type": "integer" - }, - "name": { - "description": "Unique field name used as the PDF annotation identifier (/T).", - "maxLength": 100, - "minLength": 1, - "type": "string" - }, - "options": { - "description": "Choices for dropdown, listbox or radio fields.", - "items": { - "maxLength": 200, - "type": "string" - }, - "maxItems": 100, - "type": "array" - }, - "placeholder": { - "description": "Hint text shown while the field is empty.", - "maxLength": 200, - "type": "string" - }, - "readOnly": { - "description": "Prevent editing of this field.", - "type": "boolean" - }, - "required": { - "description": "Mark field as required.", - "type": "boolean" - }, - "type": { - "const": "formField" - }, - "value": { - "description": "Pre-filled value. The key is 'value' (there is no defaultValue).", - "maxLength": 2000, - "type": "string" - }, - "width": { - "description": "Field width in points (default: full content width).", - "maximum": 500, - "minimum": 10, - "type": "number" - } - }, - "required": [ - "type", - "fieldType", - "name" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "keepWithNext": { + "description": "Keep this heading on the same page as the block that follows. Overrides typography.keepHeadingsWithNext for this block, either way.", + "type": "boolean" + }, + "level": { + "enum": [ + 1, + 2, + 3 + ], + "type": "integer" + }, + "text": { + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "heading" + } + }, + "required": [ + "type", + "text", + "level" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "align": { + "description": "Text alignment (default left). 'justify' spans every line but the last across the measure; pair it with typography.opticalMargins.", + "enum": [ + "left", + "right", + "center", + "justify" + ], + "type": "string" + }, + "direction": { + "description": "Base direction of this paragraph, overriding the document `direction`: 'auto' (first strong character), 'ltr' or 'rtl'. A right-to-left paragraph is right-aligned unless `align` says otherwise.", + "enum": [ + "auto", + "ltr", + "rtl" + ], + "type": "string" + }, + "keepWithNext": { + "description": "Keep this paragraph on the same page as the block that follows (a lead-in line before a table or figure). Default false.", + "type": "boolean" + }, + "splittable": { + "description": "Allow / forbid this paragraph breaking across pages, overriding typography.splitParagraphs for this block.", + "type": "boolean" + }, + "text": { + "description": "Paragraph text. Embedded newlines ('\\n') are automatically split into separate paragraphs — no need to pre-split; never emit a literal newline expecting a soft line break.", + "maxLength": 50000, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "paragraph" + } + }, + "required": [ + "type", + "text" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "description": "List items. A string is a leaf; an object { text, items } nests a sub-list (bullets/numbers indent; numbered sub-lists restart at 1).", + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "style": { + "default": "bullet", + "enum": [ + "bullet", + "numbered" + ], + "type": "string" + }, + "type": { + "const": "list" + } + }, + "required": [ + "type", + "items" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "type": { + "const": "pageBreak" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "height": { + "maximum": 500, + "minimum": 1, + "type": "number" + }, + "type": { + "const": "spacer" + } + }, + "required": [ + "type", + "height" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Native vector chart rendered as pure PDF path operators — bar / horizontal-bar / stacked-bar / line / area / scatter / pie / donut (pdfnative 1.7 charts v2: time and log axes, data labels, secondary axis, legends). Same body as add_chart.", + "properties": { + "align": { + "description": "Horizontal alignment within the content width. Default 'left'.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + }, + "altText": { + "description": "Alt text for the tagged-PDF /Figure /Alt. Auto-generated when omitted.", + "maxLength": 500, + "type": "string" + }, + "axis": { + "additionalProperties": false, + "description": "Value-axis options (bar/line only).", + "properties": { + "grid": { + "description": "Draw horizontal gridlines.", + "type": "boolean" + }, + "scale": { + "description": "Value-axis scale. 'log' requires strictly positive values and is not available for stacked charts.", + "enum": [ + "linear", + "log" + ], + "type": "string" + }, + "ticks": { + "description": "Target tick count (nice 1/2/5×10ⁿ steps).", + "maximum": 20, + "minimum": 2, + "type": "integer" + }, + "yMax": { + "description": "Force the axis maximum (values are clamped to the plot band).", + "type": "number" + }, + "yMin": { + "description": "Force the axis minimum (values are clamped to the plot band).", + "type": "number" + } + }, + "type": "object" + }, + "axis2": { + "additionalProperties": false, + "description": "Secondary RIGHT value axis (drawn only when a series sets yAxis:'right').", + "properties": { + "scale": { + "enum": [ + "linear", + "log" + ], + "type": "string" + }, + "ticks": { + "maximum": 20, + "minimum": 2, + "type": "integer" + }, + "yMax": { + "type": "number" + }, + "yMin": { + "type": "number" + } + }, + "type": "object" + }, + "categories": { + "description": "Category / slice labels (x-axis). Defaults to 1-based indices when omitted.", + "items": { + "maxLength": 200, + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "chartType": { + "description": "Chart kind. 'pie'/'donut' use exactly one series; 'bar'/'barH'/'stackedBar'/'stackedBarH'/'line'/'area'/'scatter' support multiple series. 'scatter' requires xValues on every series and a positional xAxis.type ('linear' or 'time').", + "enum": [ + "bar", + "barH", + "stackedBar", + "stackedBarH", + "line", + "area", + "scatter", + "pie", + "donut" + ], + "type": "string" + }, + "colors": { + "description": "Palette override (per-series for bar/line, per-slice for pie/donut).", + "items": { + "anyOf": [ + { + "pattern": "^#?[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } + ], + "description": "CSS-style hex colour, e.g. \"#3366cc\"." + }, + "maxItems": 50, + "type": "array" + }, + "dataLabels": { + "description": "Per-point value labels: true for defaults, or an object to format them.", + "oneOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "decimals": { + "maximum": 6, + "minimum": 0, + "type": "integer" + }, + "prefix": { + "maxLength": 16, + "type": "string" + }, + "suffix": { + "maxLength": 16, + "type": "string" + } + }, + "type": "object" + } + ] + }, + "height": { + "description": "Plot-area height in points. Default 240.", + "maximum": 2000, + "minimum": 50, + "type": "number" + }, + "labelRotation": { + "description": "Rotate category labels counter-clockwise by this many degrees (disables the automatic stride).", + "maximum": 90, + "minimum": 0, + "type": "number" + }, + "labelStride": { + "description": "Draw every Nth category label. Default: automatic (measured non-overlap); 1 draws every label.", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "legend": { + "description": "Legend placement. Defaults to 'bottom' for multi-series/pie, else 'none'.", + "enum": [ + "bottom", + "none" + ], + "type": "string" + }, + "markers": { + "description": "Draw point markers on line series. Default false.", + "type": "boolean" + }, + "series": { + "description": "Data series. Pie/donut charts use exactly one series (each value becomes a slice).", + "items": { + "additionalProperties": false, + "properties": { + "color": { + "anyOf": [ + { + "pattern": "^#?[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } + ], + "description": "CSS-style hex colour, e.g. \"#3366cc\"." + }, + "colors": { + "description": "One colour per value, painted on bar, barH, stackedBar and stackedBarH; the length must equal values.length on every chart type (CHART_ERROR otherwise). The legend swatch keeps 'color'; line, area, scatter, pie and donut paint 'color' only.", + "items": { + "anyOf": [ + { + "pattern": "^#?[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } + ], + "description": "CSS-style hex colour, e.g. \"#3366cc\"." + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "label": { + "description": "Series label (shown in the legend). Optional since 1.8.0: an unlabelled series is listed as 'Series N'.", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "values": { + "description": "Numeric values, one per category. Negative values are supported for bar/line.", + "items": { + "type": "number" + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "xValues": { + "description": "Per-point x positions (same length as values) for scatter charts and for line/area charts with xAxis.type 'linear' or 'time'.", + "items": { + "description": "Positional x value: a number (linear axis) or an ISO-8601 date / epoch milliseconds (time axis).", + "maxLength": 64, + "type": [ + "number", + "string" + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "yAxis": { + "description": "Bind the series to the left (default) or the secondary right value axis (cartesian charts only; configure its range with 'axis2').", + "enum": [ + "left", + "right" + ], + "type": "string" + } + }, + "required": [ + "values" + ], + "type": "object" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "title": { + "description": "Chart title rendered above the plot.", + "maxLength": 200, + "type": "string" + }, + "type": { + "const": "chart" + }, + "width": { + "description": "Plot width in points (clamped to content width). Default 460.", + "maximum": 2000, + "minimum": 50, + "type": "number" + }, + "xAxis": { + "additionalProperties": false, + "description": "Horizontal axis. 'category' (default) positions points by index; 'linear' / 'time' position them by series xValues (line/area/scatter only). Time ticks are UTC-deterministic.", + "properties": { + "grid": { + "description": "Draw vertical gridlines.", + "type": "boolean" + }, + "max": { + "description": "Axis maximum (number, or ISO-8601 / epoch ms for time axes).", + "maxLength": 64, + "type": [ + "number", + "string" + ] + }, + "min": { + "description": "Axis minimum (number, or ISO-8601 / epoch ms for time axes).", + "maxLength": 64, + "type": [ + "number", + "string" + ] + }, + "ticks": { + "maximum": 20, + "minimum": 2, + "type": "integer" + }, + "type": { + "enum": [ + "category", + "linear", + "time" + ], + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "type", + "chartType", + "series" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Inline smart table — same body as add_table (every row must have exactly as many cells as headers).", + "properties": { + "autoFitColumns": { + "description": "Auto-fit column widths to content. Output bytes then depend on text metrics (not byte-deterministic across content changes).", + "type": "boolean" + }, + "caption": { + "description": "Caption rendered above the table (tagged as /Caption under PDF/A).", + "maxLength": 200, + "type": "string" + }, + "cellBorders": { + "additionalProperties": false, + "description": "Per-cell vector borders (pure strokes, PDF/A-safe). Choose individual sides or `all`.", + "properties": { + "all": { + "description": "Draw all four edges (overrides the individual side flags).", + "type": "boolean" + }, + "bottom": { + "type": "boolean" + }, + "color": { + "anyOf": [ + { + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } + ], + "description": "Stroke colour as a PDF operator string ('0.8 0.8 0.8') or hex. Default light grey." + }, + "left": { + "type": "boolean" + }, + "right": { + "type": "boolean" + }, + "style": { + "description": "Stroke style (default 'solid').", + "enum": [ + "solid", + "dashed", + "dotted" + ], + "type": "string" + }, + "top": { + "type": "boolean" + }, + "width": { + "description": "Stroke width in points (default 0.5).", + "maximum": 10, + "minimum": 0, + "type": "number" + } + }, + "type": "object" + }, + "cellPadding": { + "description": "Horizontal cell padding in points (default 3).", + "maximum": 50, + "minimum": 0, + "type": "number" + }, + "cellVAlign": { + "description": "Vertical alignment of cell content.", + "enum": [ + "top", + "middle", + "bottom" + ], + "type": "string" + }, + "clipCells": { + "description": "Clip cell contents to the column bounds (PDF clip operators). Recommended for PDF/A and visual safety.", + "type": "boolean" + }, + "headers": { + "description": "Column header labels. Must have the same length as each row in `rows`.", + "items": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "minRowHeight": { + "description": "Minimum row height in points (default 12).", + "maximum": 200, + "minimum": 1, + "type": "number" + }, + "repeatHeader": { + "description": "Repeat the header row on every continuation page (default true).", + "type": "boolean" + }, + "rows": { + "description": "Data rows. Each row is an array of cell strings with the same length as `headers`.", + "items": { + "items": { + "maxLength": 500, + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "maxItems": 5000, + "minItems": 1, + "type": "array" + }, + "type": { + "const": "table" + }, + "wrap": { + "description": "Cell wrap policy: 'auto' (default) wraps only overflowing cells; 'always' wraps every cell; 'never' truncates.", + "enum": [ + "auto", + "always", + "never" + ], + "type": "string" + }, + "zebra": { + "description": "Alternate-row light tint (static fill, PDF/A-1b safe).", + "type": "boolean" + } + }, + "required": [ + "type", + "headers", + "rows" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Inline JPEG / PNG / JPEG 2000 image. Without width/height the pixel size is used as points and clamped to the content width; with one dimension the aspect ratio is kept. The decoded bytes of all image blocks in one call are capped at 24 MiB (a watermark image has its own 8 MiB cap).", + "properties": { + "align": { + "default": "left", + "description": "Horizontal placement inside the content width.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + }, + "alt": { + "description": "Accessible description (tagged /Figure /Alt). Always provide it for non-decorative content under PDF/A or PDF/UA.", + "maxLength": 500, + "type": "string" + }, + "height": { + "description": "Render height in points.", + "maximum": 1000, + "minimum": 10, + "type": "number" + }, + "imageBase64": { + "description": "Base64 image bytes. JPEG (baseline; 1, 3 or 4 components — CMYK raises PDFA_DEVICE_CMYK_IMAGE under PDF/A), PNG (8-bit greyscale/RGB, non-interlaced; alpha-channel and palette PNGs are rejected with a remedy) or JPEG 2000 (JP2 file or raw .j2k codestream, passed through as /JPXDecode; PDF 1.5+, so PDFA1_JPX_IMAGE under pdfa1b). No data: URI.", + "maxLength": 12000000, + "minLength": 4, + "type": "string" + }, + "mimeType": { + "description": "MIME type of the image. Must match the actual encoding of imageBase64 (magic bytes are checked). 'image/jp2' accepts a JP2 file (.jp2/.jpx) or a raw JPEG 2000 codestream (.j2k/.j2c).", + "enum": [ + "image/jpeg", + "image/png", + "image/jp2" + ], + "type": "string" + }, + "type": { + "const": "image" + }, + "width": { + "description": "Render width in points.", + "maximum": 800, + "minimum": 10, + "type": "number" + } + }, + "required": [ + "type", + "imageBase64", + "mimeType" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Clickable external link (/URI action). Only http:, https: and mailto: URLs are accepted.", + "properties": { + "color": { + "anyOf": [ + { + "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } + ], + "description": "Hex colour (#RGB or #RRGGBB)." + }, + "fontSize": { + "description": "Default 10.", + "maximum": 48, + "minimum": 6, + "type": "number" + }, + "text": { + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "link" + }, + "url": { + "description": "http(s):// or mailto: URL.", + "maxLength": 2048, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "type", + "text", + "url" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Printed table of contents generated from the document's heading blocks (internal /GoTo links with dot leaders). Pairs with outline:'auto' for the bookmark pane.", + "properties": { + "fontSize": { + "description": "Default 10.", + "maximum": 24, + "minimum": 6, + "type": "number" + }, + "indent": { + "description": "Points of indent per heading level (default 15).", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxLevel": { + "description": "Deepest heading level listed (default 3).", + "enum": [ + 1, + 2, + 3 + ], + "type": "integer" + }, + "title": { + "description": "Default 'Table of Contents'.", + "maxLength": 200, + "type": "string" + }, + "type": { + "const": "toc" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Inline barcode — same body as add_barcode (pure vector, no /Alt available in the engine).", + "properties": { + "align": { + "default": "left", + "description": "Horizontal placement inside the content width.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + }, + "data": { + "description": "Raw payload to encode — do NOT URL-encode. For QR/URL pass e.g. \"https://example.com\" verbatim. EAN-13 must be 12 or 13 digits (13th is auto-computed). Code 128 accepts ASCII alphanumerics.", + "maxLength": 4296, + "minLength": 1, + "type": "string" + }, + "ecLevel": { + "default": "M", + "description": "QR ONLY. Error correction level (L=7%, M=15%, Q=25%, H=30%). Ignored for code128/ean13/datamatrix/pdf417. Use H for printed media that may get smudged or partially covered (e.g. logo overlay).", + "enum": [ + "L", + "M", + "Q", + "H" + ], + "type": "string" + }, + "format": { + "description": "Barcode symbology to render.", + "enum": [ + "qr", + "code128", + "ean13", + "datamatrix", + "pdf417" + ], + "type": "string" + }, + "height": { + "default": 200, + "description": "Barcode height in PDF points (ignored for square symbologies like QR/Data Matrix).", + "maximum": 500, + "minimum": 30, + "type": "number" + }, + "type": { + "const": "barcode" + }, + "width": { + "default": 200, + "description": "Barcode width in PDF points.", + "maximum": 500, + "minimum": 30, + "type": "number" + } + }, + "required": [ + "type", + "format", + "data" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Vector drawing from an SVG path `d` string or SVG markup. Supported: <path> <rect> (rx/ry) <circle> <ellipse> <line> <polyline> <polygon> and <text>/<tspan> (x, y, font-size, fill, text-anchor, dx/dy); fill / stroke / stroke-width attributes; double-quoted attributes only. NOT supported (silently ignored): transform, <g>, <use>, <image>, <defs>/<clipPath>, gradients, opacity, CSS/style, dash patterns, text word-wrap. No external reference is ever fetched (no XML parser: entities other than & < > " ' &#n; are dropped). Pure path operators — PDF/A-safe at every level.", + "properties": { + "align": { + "default": "left", + "description": "Horizontal placement inside the content width.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + }, + "alt": { + "description": "Accessible description (tagged /Figure /Alt). Always provide it for non-decorative content under PDF/A or PDF/UA.", + "maxLength": 500, + "type": "string" + }, + "data": { + "description": "Path `d` string or SVG markup (≤ 100 000 characters).", + "maxLength": 100000, + "minLength": 1, + "type": "string" + }, + "fill": { + "anyOf": [ + { + "pattern": "^(?:none|#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}))$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } + ], + "description": "Hex colour or 'none' (default black)." + }, + "height": { + "description": "Render height in points (default 200).", + "maximum": 1000, + "minimum": 10, + "type": "number" + }, + "stroke": { + "anyOf": [ + { + "pattern": "^(?:none|#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}))$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } + ], + "description": "Hex colour or 'none' (default none)." + }, + "strokeWidth": { + "description": "Stroke width in SVG user units (default 1).", + "maximum": 50, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "svg" + }, + "viewBox": { + "description": "[minX, minY, width, height] — overrides the viewBox of the markup; required for a bare path string that is not 0-based.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "width": { + "description": "Render width in points (default 200).", + "maximum": 800, + "minimum": 10, + "type": "number" + } + }, + "required": [ + "type", + "data" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Inline AcroForm field — same body as an add_form field. Under a PDF/A claim pass embedFonts:true so the field font is embedded too (PDFA_UNEMBEDDED_FORM_FONT otherwise; strict:true then fails the call).", + "properties": { + "checked": { + "description": "Initial checked state for checkbox / radio fields.", + "type": "boolean" + }, + "fieldType": { + "description": "Type of form control to render. Radio fields sharing a name form one radio group.", + "enum": [ + "text", + "textarea", + "checkbox", + "radio", + "dropdown", + "listbox" + ], + "type": "string" + }, + "fontSize": { + "description": "Font size for text rendering inside the field.", + "maximum": 48, + "minimum": 6, + "type": "number" + }, + "height": { + "description": "Field height in points (default depends on the type).", + "maximum": 300, + "minimum": 10, + "type": "number" + }, + "label": { + "description": "Human-readable label shown above the field.", + "maxLength": 200, + "type": "string" + }, + "maxLength": { + "description": "Maximum character length for text/textarea fields.", + "maximum": 32767, + "minimum": 1, + "type": "integer" + }, + "name": { + "description": "Unique field name used as the PDF annotation identifier (/T).", + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "options": { + "description": "Choices for dropdown, listbox or radio fields.", + "items": { + "maxLength": 200, + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "placeholder": { + "description": "Hint text shown while the field is empty.", + "maxLength": 200, + "type": "string" + }, + "readOnly": { + "description": "Prevent editing of this field.", + "type": "boolean" + }, + "required": { + "description": "Mark field as required.", + "type": "boolean" + }, + "type": { + "const": "formField" + }, + "value": { + "description": "Pre-filled value. The key is 'value' (there is no defaultValue).", + "maxLength": 2000, + "type": "string" + }, + "width": { + "description": "Field width in points (default: full content width).", + "maximum": 500, + "minimum": 10, + "type": "number" + } + }, + "required": [ + "type", + "fieldType", + "name" + ], + "type": "object" + } +] - added
Input schema / properties / directionAdded value: +{ + "description": "Base text direction (UAX #9): 'auto' reads each paragraph's first strong character and right-aligns RTL ones; 'ltr' / 'rtl' force it. A paragraph's own direction overrides it. Omitted = LTR (1.7.0 bytes).", + "enum": [ + "auto", + "ltr", + "rtl" + ], + "type": "string" +} - added
Input schema / properties / fontAdded value: +{ + "description": "Operator-registered custom font (the slug of a .ttf / .otf file in PDFNATIVE_MCP_FONT_DIR, e.g. 'brand-sans'): drawn first, with the bundled faces as fallbacks. Unknown slug → FONT_NOT_FOUND listing the registered ones; always embedded, so valid under PDF/A.", + "maxLength": 64, + "pattern": "^[a-z0-9][a-z0-9-]{0,63}$", + "type": "string" +} - changed
Input schema / properties / footerTemplate / properties / color / anyOfPrevious value: -[ - { - "pattern": "^#[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - changed
Input schema / properties / headerTemplate / properties / color / anyOfPrevious value: -[ - { - "pattern": "^#[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - changed
Input schema / properties / typography / descriptionPrevious value: -"Fine typography, all opt-in (omitted = unchanged bytes). kerning, fontFeatures and the 'fr' narrow space need embedFonts:true. No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt."New value: +"Fine typography, all opt-in (omitted = unchanged bytes). kerning and fontFeatures need embedFonts:true ('fr' works on base-14 too). No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt." - changed
Input schema / properties / typography / properties / punctuationSpacing / anyOfPrevious value: -[ - { - "enum": [ - "fr", - "fr-CA" - ], - "type": "string" - }, - { - "items": { - "additionalProperties": false, - "properties": { - "char": { - "maxLength": 2, - "minLength": 1, - "type": "string" - }, - "side": { - "enum": [ - "before", - "after" - ], - "type": "string" - }, - "space": { - "description": "U+00A0 / U+202F (narrow needs embedFonts).", - "enum": [ - "nbsp", - "narrow" - ], - "type": "string" - } - }, - "required": [ - "char", - "side", - "space" - ], - "type": "object" - }, - "maxItems": 32, - "type": "array" - } -]New value: +[ + { + "enum": [ + "fr", + "fr-CA" + ], + "type": "string" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "char": { + "maxLength": 2, + "minLength": 1, + "type": "string" + }, + "side": { + "enum": [ + "before", + "after" + ], + "type": "string" + }, + "space": { + "description": "U+00A0 / U+202F (narrow: a TJ adjustment on base-14, the glyph on an embedded font).", + "enum": [ + "nbsp", + "narrow" + ], + "type": "string" + } + }, + "required": [ + "char", + "side", + "space" + ], + "type": "object" + }, + "maxItems": 32, + "type": "array" + } +]
- Changed
merge_pdfs2 fields changed- changed
Output schema / descriptionPrevious value: -"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath` (and `url` when the operator maps the sandbox to a public base URL)." - added
Output schema / properties / urlAdded value: +{ + "description": "Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded.", + "type": "string" +}
- Changed
prepare_signature_placeholder13 fields changed- added
Input schema / properties / actualTextAdded value: +{ + "description": "Untagged output: wrap reordered shaped runs and RTL runs in /ActualText so extract_text returns reading order. Default true; false = bare 1.7.0 glyph runs. No effect on tagged (pdfA) output.", + "type": "boolean" +} - changed
Input schema / properties / blocks / maxItemsPrevious value: -2000New value: +5000 - added
Input schema / properties / directionAdded value: +{ + "description": "Base text direction (UAX #9): 'auto' reads each paragraph's first strong character and right-aligns RTL ones; 'ltr' / 'rtl' force it. A paragraph's own direction overrides it. Omitted = LTR (1.7.0 bytes).", + "enum": [ + "auto", + "ltr", + "rtl" + ], + "type": "string" +} - changed
Input schema / properties / footerTemplate / properties / color / anyOfPrevious value: -[ - { - "pattern": "^#[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - changed
Input schema / properties / headerTemplate / properties / color / anyOfPrevious value: -[ - { - "pattern": "^#[0-9a-fA-F]{6}$", - "type": "string" - }, - { - "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", - "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", - "type": "string" - }, - { - "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", - "items": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - } -]New value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "additionalProperties": false, + "description": "Spot ink of print.spotColours, tint 0–1.", + "properties": { + "spot": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "tint": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "spot" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Mix of spot inks (name → tint).", + "properties": { + "inks": { + "additionalProperties": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxProperties": 8, + "minProperties": 1, + "type": "object" + } + }, + "required": [ + "inks" + ], + "type": "object" + } +] - changed
Input schema / properties / includeDiagnostics / descriptionPrevious value: -"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*) as `diagnostics[]` (possibly empty)."New value: +"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*, TEXT_GLYPH_NOT_COVERED) as `diagnostics[]` (possibly empty)." - changed
Input schema / properties / print / descriptionPrevious value: -"Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b). See docs/guides/PRINT.md."New value: +"Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b), `spotColours` ink declarations. See docs/guides/PRINT.md." - added
Input schema / properties / print / properties / spotColoursAdded value: +{ + "description": "Spot inks (/Separation plates) the document may paint with { spot:'name', tint } or { inks:{ name: tint } } anywhere a colour is accepted. Undeclared ink → VALIDATION_ERROR; blank or duplicate name → PRINT_ERROR (an empty string is VALIDATION_ERROR).", + "items": { + "additionalProperties": false, + "properties": { + "alternate": { + "anyOf": [ + { + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + { + "items": { + "maximum": 255, + "minimum": 0, + "type": "number" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" + } + ], + "description": "Process alternate for proofing: [c, m, y, k] 0–100 or [r, g, b] 0–255." + }, + "name": { + "description": "'PANTONE 300 C', 'Varnish', …", + "maxLength": 100, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "name", + "alternate" + ], + "type": "object" + }, + "maxItems": 32, + "minItems": 1, + "type": "array" +} - changed
Input schema / properties / strict / descriptionPrevious value: -"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true."New value: +"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other (TYPOGRAPHY_FEATURE_INEFFECTIVE, TEXT_GLYPH_NOT_COVERED — a character no font covers, drawn as a box or '?') → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true." - changed
Input schema / properties / typography / descriptionPrevious value: -"Fine typography, all opt-in (omitted = unchanged bytes). kerning, fontFeatures and the 'fr' narrow space need embedFonts:true. No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt."New value: +"Fine typography, all opt-in (omitted = unchanged bytes). kerning and fontFeatures need embedFonts:true ('fr' works on base-14 too). No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt." - changed
Input schema / properties / typography / properties / punctuationSpacing / anyOfPrevious value: -[ - { - "enum": [ - "fr", - "fr-CA" - ], - "type": "string" - }, - { - "items": { - "additionalProperties": false, - "properties": { - "char": { - "maxLength": 2, - "minLength": 1, - "type": "string" - }, - "side": { - "enum": [ - "before", - "after" - ], - "type": "string" - }, - "space": { - "description": "U+00A0 / U+202F (narrow needs embedFonts).", - "enum": [ - "nbsp", - "narrow" - ], - "type": "string" - } - }, - "required": [ - "char", - "side", - "space" - ], - "type": "object" - }, - "maxItems": 32, - "type": "array" - } -]New value: +[ + { + "enum": [ + "fr", + "fr-CA" + ], + "type": "string" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "char": { + "maxLength": 2, + "minLength": 1, + "type": "string" + }, + "side": { + "enum": [ + "before", + "after" + ], + "type": "string" + }, + "space": { + "description": "U+00A0 / U+202F (narrow: a TJ adjustment on base-14, the glyph on an embedded font).", + "enum": [ + "nbsp", + "narrow" + ], + "type": "string" + } + }, + "required": [ + "char", + "side", + "space" + ], + "type": "object" + }, + "maxItems": 32, + "type": "array" + } +] - changed
Output schema / descriptionPrevious value: -"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath` (and `url` when the operator maps the sandbox to a public base URL)." - added
Output schema / properties / urlAdded value: +{ + "description": "Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded.", + "type": "string" +}
- Changed
sign_pdf2 fields changed- changed
Output schema / descriptionPrevious value: -"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath` (and `url` when the operator maps the sandbox to a public base URL)." - added
Output schema / properties / urlAdded value: +{ + "description": "Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded.", + "type": "string" +}
- Changed
split_pdf1 field changed- added
Output schema / properties / parts / items / properties / urlAdded value: +{ + "description": "Public URL of the part (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set).", + "type": "string" +}
- Changed
timestamp_pdf2 fields changed- changed
Output schema / descriptionPrevious value: -"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath` (and `url` when the operator maps the sandbox to a public base URL)." - added
Output schema / properties / urlAdded value: +{ + "description": "Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded.", + "type": "string" +}
- Changed
update_metadata2 fields changed- changed
Output schema / descriptionPrevious value: -"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath` (and `url` when the operator maps the sandbox to a public base URL)." - added
Output schema / properties / urlAdded value: +{ + "description": "Public URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded.", + "type": "string" +}
22 tool updates
v1.6.2- Changed
add_attachment23 fields changed- changed
Input schema / properties / creationDate / descriptionPrevious value: -"ISO-8601 instant for /CreationDate (+ XMP). Pin it for byte-identical output across calls (same host TZ); omitted = wall clock, so every call differs."New value: +"ISO-8601 instant for /CreationDate (+ XMP, the trailer /ID and the {date} placeholder), written in UTC. Pin it for byte-identical output across calls and hosts; omitted = wall clock, so every call differs." - changed
Input schema / properties / embedFonts / descriptionPrevious value: -"Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A claim (ISO 19005 §6.2.11.4.1) and for strict=true; adds ~0.3 MiB."New value: +"Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A or PDF/X claim (every font embedded) and for strict=true; adds ~0.3 MiB." - changed
Input schema / properties / footerTemplate / properties / center / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - added
Input schema / properties / footerTemplate / properties / color / anyOfAdded value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - changed
Input schema / properties / footerTemplate / properties / color / descriptionPrevious value: -"Hex colour."New value: +"Hex colour (#RRGGBB)." - removed
Input schema / properties / footerTemplate / properties / color / patternRemoved value: -"^#[0-9a-fA-F]{6}$" - removed
Input schema / properties / footerTemplate / properties / color / typeRemoved value: -"string" - changed
Input schema / properties / footerTemplate / properties / left / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / footerTemplate / properties / right / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / headerTemplate / properties / center / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - added
Input schema / properties / headerTemplate / properties / color / anyOfAdded value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - changed
Input schema / properties / headerTemplate / properties / color / descriptionPrevious value: -"Hex colour."New value: +"Hex colour (#RRGGBB)." - removed
Input schema / properties / headerTemplate / properties / color / patternRemoved value: -"^#[0-9a-fA-F]{6}$" - removed
Input schema / properties / headerTemplate / properties / color / typeRemoved value: -"string" - changed
Input schema / properties / headerTemplate / properties / left / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / headerTemplate / properties / right / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / includeDiagnostics / descriptionPrevious value: -"Return the PDF/A diagnostics raised while building as `diagnostics[]` (possibly empty)."New value: +"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*) as `diagnostics[]` (possibly empty)." - changed
Input schema / properties / outputIntent / descriptionPrevious value: -"Custom PDF/A OutputIntent: an RGB ICC profile + condition strings replacing the built-in sRGB intent (CMYK rejected)."New value: +"Custom OutputIntent (under pdfA or pdfx): an RGB, CMYK or Gray ICC profile + condition strings, replacing the built-in sRGB intent. The profile must be a real ICC file ('acsp' signature, consistent size — PRINT_ERROR otherwise); pdfx needs device class 'prtr'. Under a CMYK / Gray intent RGB content is mapped through a calibrated default space." - changed
Input schema / properties / outputIntent / properties / iccProfileBase64 / descriptionPrevious value: -"ICC profile bytes, base64 (RGB, ≤ 8 MiB)."New value: +"ICC profile bytes, base64 (RGB, CMYK or Gray; ≤ 8 MiB)." - changed
Input schema / properties / print / properties / marks / oneOfPrevious value: -[ - { - "type": "boolean" - }, - { - "additionalProperties": false, - "properties": { - "crop": { - "description": "Corner crop (trim) marks. Default true.", - "type": "boolean" - }, - "length": { - "description": "Mark length in points. Default 14.", - "maximum": 100, - "minimum": 1, - "type": "number" - }, - "offset": { - "description": "Gap between TrimBox and marks in points. Default 5.", - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "registration": { - "description": "Edge-midpoint registration targets. Default true.", - "type": "boolean" - }, - "weight": { - "description": "Stroke width in points. Default 0.25.", - "maximum": 5, - "minimum": 0.05, - "type": "number" - } - }, - "type": "object" - } -]New value: +[ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "colourBars": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "size": { + "description": "Patch size in points. Default 12.", + "maximum": 72, + "minimum": 4, + "type": "number" + }, + "tints": { + "description": "Add the four 50 % tint patches. Default true.", + "type": "boolean" + } + }, + "type": "object" + } + ], + "description": "Colour control strip in the bleed (C M Y K solids + their 50 % tints): true for defaults. Off by default; needs a bleed of about 5 mm (14.17 pt) and is skipped when the strip would not fit." + }, + "crop": { + "description": "Corner crop (trim) marks. Default true.", + "type": "boolean" + }, + "length": { + "description": "Mark length in points. Default 14.", + "maximum": 100, + "minimum": 1, + "type": "number" + }, + "offset": { + "description": "Gap between TrimBox and marks in points. Default 5.", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "registration": { + "description": "Edge-midpoint registration targets. Default true.", + "type": "boolean" + }, + "weight": { + "description": "Stroke width in points. Default 0.25.", + "maximum": 5, + "minimum": 0.05, + "type": "number" + } + }, + "type": "object" + } +] - changed
Input schema / properties / strict / descriptionPrevious value: -"Fail with PDF_A_COMPLIANCE_VIOLATION instead of producing a non-conformant PDF/A file (e.g. PDFA_NO_FONT_ENTRIES without embedFonts). Pair with embedFonts=true."New value: +"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true." - added
Input schema / properties / typographyAdded value: +{ + "additionalProperties": false, + "description": "Fine typography, all opt-in (omitted = unchanged bytes). kerning, fontFeatures and the 'fr' narrow space need embedFonts:true. No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt.", + "properties": { + "bindShortWords": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "maxLength": { + "maximum": 3, + "minimum": 1, + "type": "integer" + }, + "words": { + "items": { + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + ], + "description": "Never end a line on a short word: up to maxLength letters (default 1), or exactly the listed words." + }, + "fontFeatures": { + "description": "OpenType features, later wins. tnum / lnum are no-ops on Noto Sans (TYPOGRAPHY_FEATURE_INEFFECTIVE).", + "items": { + "enum": [ + "tnum", + "pnum", + "lnum", + "onum", + "zero", + "ordn", + "sups", + "subs", + "smcp", + "c2sc", + "case" + ], + "type": "string" + }, + "maxItems": 11, + "type": "array", + "uniqueItems": true + }, + "hyphenationLanguage": { + "description": "BCP 47 tag; no effect here (no hyphenation provider installed).", + "maxLength": 35, + "pattern": "^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$", + "type": "string" + }, + "keepHeadingsWithNext": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "minLines": { + "maximum": 10, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + } + ], + "description": "Never strand a heading at a page foot. true = { minLines: 2 }." + }, + "kerning": { + "description": "Pair kerning (GPOS).", + "type": "boolean" + }, + "metrics": { + "description": "Base-14 text: 'exact' uses the AFM widths (different wraps). Default 'approximate'.", + "enum": [ + "approximate", + "exact" + ], + "type": "string" + }, + "opticalMargins": { + "description": "Hang punctuation into the margin of align:'justify' text.", + "type": "boolean" + }, + "orphans": { + "description": "Min lines left at a page foot (default 2; needs splitParagraphs).", + "maximum": 10, + "minimum": 1, + "type": "integer" + }, + "punctuationSpacing": { + "anyOf": [ + { + "enum": [ + "fr", + "fr-CA" + ], + "type": "string" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "char": { + "maxLength": 2, + "minLength": 1, + "type": "string" + }, + "side": { + "enum": [ + "before", + "after" + ], + "type": "string" + }, + "space": { + "description": "U+00A0 / U+202F (narrow needs embedFonts).", + "enum": [ + "nbsp", + "narrow" + ], + "type": "string" + } + }, + "required": [ + "char", + "side", + "space" + ], + "type": "object" + }, + "maxItems": 32, + "type": "array" + } + ], + "description": "No-break spaces next to punctuation (existing spaces only). 'fr': narrow before ; ! ?, no-break before ':' and inside « ». 'fr-CA': ':' and « » only. Or explicit rules." + }, + "splitParagraphs": { + "description": "Paragraphs may break across pages at a line boundary (default: atomic).", + "type": "boolean" + }, + "unitBinding": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "units": { + "items": { + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + ], + "description": "No-break space between a number and its unit ('150 €', '12 kg'); units replaces the built-in list." + }, + "widows": { + "description": "Min lines carried over (default 2; needs splitParagraphs).", + "maximum": 10, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" +} - changed
Output schema / properties / diagnostics / descriptionPrevious value: -"PDF/A diagnostics (when includeDiagnostics=true)."New value: +"Engine diagnostics (when includeDiagnostics=true)."
- Changed
add_barcode24 fields changed- changed
Input schema / properties / creationDate / descriptionPrevious value: -"ISO-8601 instant for /CreationDate (+ XMP). Pin it for byte-identical output across calls (same host TZ); omitted = wall clock, so every call differs."New value: +"ISO-8601 instant for /CreationDate (+ XMP, the trailer /ID and the {date} placeholder), written in UTC. Pin it for byte-identical output across calls and hosts; omitted = wall clock, so every call differs." - changed
Input schema / properties / embedFonts / descriptionPrevious value: -"Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A claim (ISO 19005 §6.2.11.4.1) and for strict=true; adds ~0.3 MiB."New value: +"Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A or PDF/X claim (every font embedded) and for strict=true; adds ~0.3 MiB." - changed
Input schema / properties / footerTemplate / properties / center / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - added
Input schema / properties / footerTemplate / properties / color / anyOfAdded value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - changed
Input schema / properties / footerTemplate / properties / color / descriptionPrevious value: -"Hex colour."New value: +"Hex colour (#RRGGBB)." - removed
Input schema / properties / footerTemplate / properties / color / patternRemoved value: -"^#[0-9a-fA-F]{6}$" - removed
Input schema / properties / footerTemplate / properties / color / typeRemoved value: -"string" - changed
Input schema / properties / footerTemplate / properties / left / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / footerTemplate / properties / right / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / headerTemplate / properties / center / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - added
Input schema / properties / headerTemplate / properties / color / anyOfAdded value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - changed
Input schema / properties / headerTemplate / properties / color / descriptionPrevious value: -"Hex colour."New value: +"Hex colour (#RRGGBB)." - removed
Input schema / properties / headerTemplate / properties / color / patternRemoved value: -"^#[0-9a-fA-F]{6}$" - removed
Input schema / properties / headerTemplate / properties / color / typeRemoved value: -"string" - changed
Input schema / properties / headerTemplate / properties / left / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / headerTemplate / properties / right / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / includeDiagnostics / descriptionPrevious value: -"Return the PDF/A diagnostics raised while building as `diagnostics[]` (possibly empty)."New value: +"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*) as `diagnostics[]` (possibly empty)." - changed
Input schema / properties / outputIntent / descriptionPrevious value: -"Custom PDF/A OutputIntent: an RGB ICC profile + condition strings replacing the built-in sRGB intent (CMYK rejected)."New value: +"Custom OutputIntent (under pdfA or pdfx): an RGB, CMYK or Gray ICC profile + condition strings, replacing the built-in sRGB intent. The profile must be a real ICC file ('acsp' signature, consistent size — PRINT_ERROR otherwise); pdfx needs device class 'prtr'. Under a CMYK / Gray intent RGB content is mapped through a calibrated default space." - changed
Input schema / properties / outputIntent / properties / iccProfileBase64 / descriptionPrevious value: -"ICC profile bytes, base64 (RGB, ≤ 8 MiB)."New value: +"ICC profile bytes, base64 (RGB, CMYK or Gray; ≤ 8 MiB)." - added
Input schema / properties / pdfxAdded value: +{ + "description": "PDF/X-4 print exchange (ISO 15930-7). REQUIRES outputIntent with the printer's ICC profile (device class 'prtr'; CMYK or Gray — none is bundled); needs embedFonts:true for a conformant file (PDFX_NO_FONT_ENTRIES otherwise, strict:true refuses). Exclusive with pdfA and encrypt; metadata.trapped must be 'True' or 'False'; TrimBox or ArtBox, not both. Links and form fields are reported (PDFX_ANNOTATIONS). Check with validate_pdf standard:'pdf-x-4'. See the print_ready prompt.", + "enum": [ + "pdfx4" + ], + "type": "string" +} - changed
Input schema / properties / print / properties / marks / oneOfPrevious value: -[ - { - "type": "boolean" - }, - { - "additionalProperties": false, - "properties": { - "crop": { - "description": "Corner crop (trim) marks. Default true.", - "type": "boolean" - }, - "length": { - "description": "Mark length in points. Default 14.", - "maximum": 100, - "minimum": 1, - "type": "number" - }, - "offset": { - "description": "Gap between TrimBox and marks in points. Default 5.", - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "registration": { - "description": "Edge-midpoint registration targets. Default true.", - "type": "boolean" - }, - "weight": { - "description": "Stroke width in points. Default 0.25.", - "maximum": 5, - "minimum": 0.05, - "type": "number" - } - }, - "type": "object" - } -]New value: +[ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "colourBars": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "size": { + "description": "Patch size in points. Default 12.", + "maximum": 72, + "minimum": 4, + "type": "number" + }, + "tints": { + "description": "Add the four 50 % tint patches. Default true.", + "type": "boolean" + } + }, + "type": "object" + } + ], + "description": "Colour control strip in the bleed (C M Y K solids + their 50 % tints): true for defaults. Off by default; needs a bleed of about 5 mm (14.17 pt) and is skipped when the strip would not fit." + }, + "crop": { + "description": "Corner crop (trim) marks. Default true.", + "type": "boolean" + }, + "length": { + "description": "Mark length in points. Default 14.", + "maximum": 100, + "minimum": 1, + "type": "number" + }, + "offset": { + "description": "Gap between TrimBox and marks in points. Default 5.", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "registration": { + "description": "Edge-midpoint registration targets. Default true.", + "type": "boolean" + }, + "weight": { + "description": "Stroke width in points. Default 0.25.", + "maximum": 5, + "minimum": 0.05, + "type": "number" + } + }, + "type": "object" + } +] - changed
Input schema / properties / strict / descriptionPrevious value: -"Fail with PDF_A_COMPLIANCE_VIOLATION instead of producing a non-conformant PDF/A file (e.g. PDFA_NO_FONT_ENTRIES without embedFonts). Pair with embedFonts=true."New value: +"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true." - added
Input schema / properties / typographyAdded value: +{ + "additionalProperties": false, + "description": "Fine typography, all opt-in (omitted = unchanged bytes). kerning, fontFeatures and the 'fr' narrow space need embedFonts:true. No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt.", + "properties": { + "bindShortWords": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "maxLength": { + "maximum": 3, + "minimum": 1, + "type": "integer" + }, + "words": { + "items": { + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + ], + "description": "Never end a line on a short word: up to maxLength letters (default 1), or exactly the listed words." + }, + "fontFeatures": { + "description": "OpenType features, later wins. tnum / lnum are no-ops on Noto Sans (TYPOGRAPHY_FEATURE_INEFFECTIVE).", + "items": { + "enum": [ + "tnum", + "pnum", + "lnum", + "onum", + "zero", + "ordn", + "sups", + "subs", + "smcp", + "c2sc", + "case" + ], + "type": "string" + }, + "maxItems": 11, + "type": "array", + "uniqueItems": true + }, + "hyphenationLanguage": { + "description": "BCP 47 tag; no effect here (no hyphenation provider installed).", + "maxLength": 35, + "pattern": "^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$", + "type": "string" + }, + "keepHeadingsWithNext": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "minLines": { + "maximum": 10, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + } + ], + "description": "Never strand a heading at a page foot. true = { minLines: 2 }." + }, + "kerning": { + "description": "Pair kerning (GPOS).", + "type": "boolean" + }, + "metrics": { + "description": "Base-14 text: 'exact' uses the AFM widths (different wraps). Default 'approximate'.", + "enum": [ + "approximate", + "exact" + ], + "type": "string" + }, + "opticalMargins": { + "description": "Hang punctuation into the margin of align:'justify' text.", + "type": "boolean" + }, + "orphans": { + "description": "Min lines left at a page foot (default 2; needs splitParagraphs).", + "maximum": 10, + "minimum": 1, + "type": "integer" + }, + "punctuationSpacing": { + "anyOf": [ + { + "enum": [ + "fr", + "fr-CA" + ], + "type": "string" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "char": { + "maxLength": 2, + "minLength": 1, + "type": "string" + }, + "side": { + "enum": [ + "before", + "after" + ], + "type": "string" + }, + "space": { + "description": "U+00A0 / U+202F (narrow needs embedFonts).", + "enum": [ + "nbsp", + "narrow" + ], + "type": "string" + } + }, + "required": [ + "char", + "side", + "space" + ], + "type": "object" + }, + "maxItems": 32, + "type": "array" + } + ], + "description": "No-break spaces next to punctuation (existing spaces only). 'fr': narrow before ; ! ?, no-break before ':' and inside « ». 'fr-CA': ':' and « » only. Or explicit rules." + }, + "splitParagraphs": { + "description": "Paragraphs may break across pages at a line boundary (default: atomic).", + "type": "boolean" + }, + "unitBinding": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "units": { + "items": { + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + ], + "description": "No-break space between a number and its unit ('150 €', '12 kg'); units replaces the built-in list." + }, + "widows": { + "description": "Min lines carried over (default 2; needs splitParagraphs).", + "maximum": 10, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" +} - changed
Output schema / properties / diagnostics / descriptionPrevious value: -"PDF/A diagnostics (when includeDiagnostics=true)."New value: +"Engine diagnostics (when includeDiagnostics=true)."
- Changed
add_chart30 fields changed- added
Input schema / properties / colors / items / anyOfAdded value: +[ + { + "pattern": "^#?[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - removed
Input schema / properties / colors / items / patternRemoved value: -"^#?[0-9a-fA-F]{6}$" - removed
Input schema / properties / colors / items / typeRemoved value: -"string" - changed
Input schema / properties / creationDate / descriptionPrevious value: -"ISO-8601 instant for /CreationDate (+ XMP). Pin it for byte-identical output across calls (same host TZ); omitted = wall clock, so every call differs."New value: +"ISO-8601 instant for /CreationDate (+ XMP, the trailer /ID and the {date} placeholder), written in UTC. Pin it for byte-identical output across calls and hosts; omitted = wall clock, so every call differs." - changed
Input schema / properties / embedFonts / descriptionPrevious value: -"Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A claim (ISO 19005 §6.2.11.4.1) and for strict=true; adds ~0.3 MiB."New value: +"Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A or PDF/X claim (every font embedded) and for strict=true; adds ~0.3 MiB." - changed
Input schema / properties / footerTemplate / properties / center / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - added
Input schema / properties / footerTemplate / properties / color / anyOfAdded value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - changed
Input schema / properties / footerTemplate / properties / color / descriptionPrevious value: -"Hex colour."New value: +"Hex colour (#RRGGBB)." - removed
Input schema / properties / footerTemplate / properties / color / patternRemoved value: -"^#[0-9a-fA-F]{6}$" - removed
Input schema / properties / footerTemplate / properties / color / typeRemoved value: -"string" - changed
Input schema / properties / footerTemplate / properties / left / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / footerTemplate / properties / right / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / headerTemplate / properties / center / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - added
Input schema / properties / headerTemplate / properties / color / anyOfAdded value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - changed
Input schema / properties / headerTemplate / properties / color / descriptionPrevious value: -"Hex colour."New value: +"Hex colour (#RRGGBB)." - removed
Input schema / properties / headerTemplate / properties / color / patternRemoved value: -"^#[0-9a-fA-F]{6}$" - removed
Input schema / properties / headerTemplate / properties / color / typeRemoved value: -"string" - changed
Input schema / properties / headerTemplate / properties / left / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / headerTemplate / properties / right / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / includeDiagnostics / descriptionPrevious value: -"Return the PDF/A diagnostics raised while building as `diagnostics[]` (possibly empty)."New value: +"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*) as `diagnostics[]` (possibly empty)." - changed
Input schema / properties / outputIntent / descriptionPrevious value: -"Custom PDF/A OutputIntent: an RGB ICC profile + condition strings replacing the built-in sRGB intent (CMYK rejected)."New value: +"Custom OutputIntent (under pdfA or pdfx): an RGB, CMYK or Gray ICC profile + condition strings, replacing the built-in sRGB intent. The profile must be a real ICC file ('acsp' signature, consistent size — PRINT_ERROR otherwise); pdfx needs device class 'prtr'. Under a CMYK / Gray intent RGB content is mapped through a calibrated default space." - changed
Input schema / properties / outputIntent / properties / iccProfileBase64 / descriptionPrevious value: -"ICC profile bytes, base64 (RGB, ≤ 8 MiB)."New value: +"ICC profile bytes, base64 (RGB, CMYK or Gray; ≤ 8 MiB)." - added
Input schema / properties / pdfxAdded value: +{ + "description": "PDF/X-4 print exchange (ISO 15930-7). REQUIRES outputIntent with the printer's ICC profile (device class 'prtr'; CMYK or Gray — none is bundled); needs embedFonts:true for a conformant file (PDFX_NO_FONT_ENTRIES otherwise, strict:true refuses). Exclusive with pdfA and encrypt; metadata.trapped must be 'True' or 'False'; TrimBox or ArtBox, not both. Links and form fields are reported (PDFX_ANNOTATIONS). Check with validate_pdf standard:'pdf-x-4'. See the print_ready prompt.", + "enum": [ + "pdfx4" + ], + "type": "string" +} - changed
Input schema / properties / print / properties / marks / oneOfPrevious value: -[ - { - "type": "boolean" - }, - { - "additionalProperties": false, - "properties": { - "crop": { - "description": "Corner crop (trim) marks. Default true.", - "type": "boolean" - }, - "length": { - "description": "Mark length in points. Default 14.", - "maximum": 100, - "minimum": 1, - "type": "number" - }, - "offset": { - "description": "Gap between TrimBox and marks in points. Default 5.", - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "registration": { - "description": "Edge-midpoint registration targets. Default true.", - "type": "boolean" - }, - "weight": { - "description": "Stroke width in points. Default 0.25.", - "maximum": 5, - "minimum": 0.05, - "type": "number" - } - }, - "type": "object" - } -]New value: +[ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "colourBars": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "size": { + "description": "Patch size in points. Default 12.", + "maximum": 72, + "minimum": 4, + "type": "number" + }, + "tints": { + "description": "Add the four 50 % tint patches. Default true.", + "type": "boolean" + } + }, + "type": "object" + } + ], + "description": "Colour control strip in the bleed (C M Y K solids + their 50 % tints): true for defaults. Off by default; needs a bleed of about 5 mm (14.17 pt) and is skipped when the strip would not fit." + }, + "crop": { + "description": "Corner crop (trim) marks. Default true.", + "type": "boolean" + }, + "length": { + "description": "Mark length in points. Default 14.", + "maximum": 100, + "minimum": 1, + "type": "number" + }, + "offset": { + "description": "Gap between TrimBox and marks in points. Default 5.", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "registration": { + "description": "Edge-midpoint registration targets. Default true.", + "type": "boolean" + }, + "weight": { + "description": "Stroke width in points. Default 0.25.", + "maximum": 5, + "minimum": 0.05, + "type": "number" + } + }, + "type": "object" + } +] - added
Input schema / properties / series / items / properties / color / anyOfAdded value: +[ + { + "pattern": "^#?[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - removed
Input schema / properties / series / items / properties / color / patternRemoved value: -"^#?[0-9a-fA-F]{6}$" - removed
Input schema / properties / series / items / properties / color / typeRemoved value: -"string" - changed
Input schema / properties / strict / descriptionPrevious value: -"Fail with PDF_A_COMPLIANCE_VIOLATION instead of producing a non-conformant PDF/A file (e.g. PDFA_NO_FONT_ENTRIES without embedFonts). Pair with embedFonts=true."New value: +"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true." - added
Input schema / properties / typographyAdded value: +{ + "additionalProperties": false, + "description": "Fine typography, all opt-in (omitted = unchanged bytes). kerning, fontFeatures and the 'fr' narrow space need embedFonts:true. No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt.", + "properties": { + "bindShortWords": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "maxLength": { + "maximum": 3, + "minimum": 1, + "type": "integer" + }, + "words": { + "items": { + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + ], + "description": "Never end a line on a short word: up to maxLength letters (default 1), or exactly the listed words." + }, + "fontFeatures": { + "description": "OpenType features, later wins. tnum / lnum are no-ops on Noto Sans (TYPOGRAPHY_FEATURE_INEFFECTIVE).", + "items": { + "enum": [ + "tnum", + "pnum", + "lnum", + "onum", + "zero", + "ordn", + "sups", + "subs", + "smcp", + "c2sc", + "case" + ], + "type": "string" + }, + "maxItems": 11, + "type": "array", + "uniqueItems": true + }, + "hyphenationLanguage": { + "description": "BCP 47 tag; no effect here (no hyphenation provider installed).", + "maxLength": 35, + "pattern": "^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$", + "type": "string" + }, + "keepHeadingsWithNext": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "minLines": { + "maximum": 10, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + } + ], + "description": "Never strand a heading at a page foot. true = { minLines: 2 }." + }, + "kerning": { + "description": "Pair kerning (GPOS).", + "type": "boolean" + }, + "metrics": { + "description": "Base-14 text: 'exact' uses the AFM widths (different wraps). Default 'approximate'.", + "enum": [ + "approximate", + "exact" + ], + "type": "string" + }, + "opticalMargins": { + "description": "Hang punctuation into the margin of align:'justify' text.", + "type": "boolean" + }, + "orphans": { + "description": "Min lines left at a page foot (default 2; needs splitParagraphs).", + "maximum": 10, + "minimum": 1, + "type": "integer" + }, + "punctuationSpacing": { + "anyOf": [ + { + "enum": [ + "fr", + "fr-CA" + ], + "type": "string" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "char": { + "maxLength": 2, + "minLength": 1, + "type": "string" + }, + "side": { + "enum": [ + "before", + "after" + ], + "type": "string" + }, + "space": { + "description": "U+00A0 / U+202F (narrow needs embedFonts).", + "enum": [ + "nbsp", + "narrow" + ], + "type": "string" + } + }, + "required": [ + "char", + "side", + "space" + ], + "type": "object" + }, + "maxItems": 32, + "type": "array" + } + ], + "description": "No-break spaces next to punctuation (existing spaces only). 'fr': narrow before ; ! ?, no-break before ':' and inside « ». 'fr-CA': ':' and « » only. Or explicit rules." + }, + "splitParagraphs": { + "description": "Paragraphs may break across pages at a line boundary (default: atomic).", + "type": "boolean" + }, + "unitBinding": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "units": { + "items": { + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + ], + "description": "No-break space between a number and its unit ('150 €', '12 kg'); units replaces the built-in list." + }, + "widows": { + "description": "Min lines carried over (default 2; needs splitParagraphs).", + "maximum": 10, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" +} - changed
Output schema / properties / diagnostics / descriptionPrevious value: -"PDF/A diagnostics (when includeDiagnostics=true)."New value: +"Engine diagnostics (when includeDiagnostics=true)."
- Changed
add_form24 fields changed- changed
Input schema / properties / creationDate / descriptionPrevious value: -"ISO-8601 instant for /CreationDate (+ XMP). Pin it for byte-identical output across calls (same host TZ); omitted = wall clock, so every call differs."New value: +"ISO-8601 instant for /CreationDate (+ XMP, the trailer /ID and the {date} placeholder), written in UTC. Pin it for byte-identical output across calls and hosts; omitted = wall clock, so every call differs." - changed
Input schema / properties / embedFonts / descriptionPrevious value: -"Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A claim (ISO 19005 §6.2.11.4.1) and for strict=true; adds ~0.3 MiB."New value: +"Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A or PDF/X claim (every font embedded) and for strict=true; adds ~0.3 MiB." - changed
Input schema / properties / fields / items / properties / value / descriptionPrevious value: -"Default value pre-filled in the field."New value: +"Pre-filled value. The key is 'value' (there is no defaultValue)." - changed
Input schema / properties / footerTemplate / properties / center / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - added
Input schema / properties / footerTemplate / properties / color / anyOfAdded value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - changed
Input schema / properties / footerTemplate / properties / color / descriptionPrevious value: -"Hex colour."New value: +"Hex colour (#RRGGBB)." - removed
Input schema / properties / footerTemplate / properties / color / patternRemoved value: -"^#[0-9a-fA-F]{6}$" - removed
Input schema / properties / footerTemplate / properties / color / typeRemoved value: -"string" - changed
Input schema / properties / footerTemplate / properties / left / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / footerTemplate / properties / right / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / headerTemplate / properties / center / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - added
Input schema / properties / headerTemplate / properties / color / anyOfAdded value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - changed
Input schema / properties / headerTemplate / properties / color / descriptionPrevious value: -"Hex colour."New value: +"Hex colour (#RRGGBB)." - removed
Input schema / properties / headerTemplate / properties / color / patternRemoved value: -"^#[0-9a-fA-F]{6}$" - removed
Input schema / properties / headerTemplate / properties / color / typeRemoved value: -"string" - changed
Input schema / properties / headerTemplate / properties / left / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / headerTemplate / properties / right / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / includeDiagnostics / descriptionPrevious value: -"Return the PDF/A diagnostics raised while building as `diagnostics[]` (possibly empty)."New value: +"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*) as `diagnostics[]` (possibly empty)." - changed
Input schema / properties / outputIntent / descriptionPrevious value: -"Custom PDF/A OutputIntent: an RGB ICC profile + condition strings replacing the built-in sRGB intent (CMYK rejected)."New value: +"Custom OutputIntent (under pdfA or pdfx): an RGB, CMYK or Gray ICC profile + condition strings, replacing the built-in sRGB intent. The profile must be a real ICC file ('acsp' signature, consistent size — PRINT_ERROR otherwise); pdfx needs device class 'prtr'. Under a CMYK / Gray intent RGB content is mapped through a calibrated default space." - changed
Input schema / properties / outputIntent / properties / iccProfileBase64 / descriptionPrevious value: -"ICC profile bytes, base64 (RGB, ≤ 8 MiB)."New value: +"ICC profile bytes, base64 (RGB, CMYK or Gray; ≤ 8 MiB)." - changed
Input schema / properties / print / properties / marks / oneOfPrevious value: -[ - { - "type": "boolean" - }, - { - "additionalProperties": false, - "properties": { - "crop": { - "description": "Corner crop (trim) marks. Default true.", - "type": "boolean" - }, - "length": { - "description": "Mark length in points. Default 14.", - "maximum": 100, - "minimum": 1, - "type": "number" - }, - "offset": { - "description": "Gap between TrimBox and marks in points. Default 5.", - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "registration": { - "description": "Edge-midpoint registration targets. Default true.", - "type": "boolean" - }, - "weight": { - "description": "Stroke width in points. Default 0.25.", - "maximum": 5, - "minimum": 0.05, - "type": "number" - } - }, - "type": "object" - } -]New value: +[ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "colourBars": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "size": { + "description": "Patch size in points. Default 12.", + "maximum": 72, + "minimum": 4, + "type": "number" + }, + "tints": { + "description": "Add the four 50 % tint patches. Default true.", + "type": "boolean" + } + }, + "type": "object" + } + ], + "description": "Colour control strip in the bleed (C M Y K solids + their 50 % tints): true for defaults. Off by default; needs a bleed of about 5 mm (14.17 pt) and is skipped when the strip would not fit." + }, + "crop": { + "description": "Corner crop (trim) marks. Default true.", + "type": "boolean" + }, + "length": { + "description": "Mark length in points. Default 14.", + "maximum": 100, + "minimum": 1, + "type": "number" + }, + "offset": { + "description": "Gap between TrimBox and marks in points. Default 5.", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "registration": { + "description": "Edge-midpoint registration targets. Default true.", + "type": "boolean" + }, + "weight": { + "description": "Stroke width in points. Default 0.25.", + "maximum": 5, + "minimum": 0.05, + "type": "number" + } + }, + "type": "object" + } +] - changed
Input schema / properties / strict / descriptionPrevious value: -"Fail with PDF_A_COMPLIANCE_VIOLATION instead of producing a non-conformant PDF/A file (e.g. PDFA_NO_FONT_ENTRIES without embedFonts). Pair with embedFonts=true."New value: +"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true." - added
Input schema / properties / typographyAdded value: +{ + "additionalProperties": false, + "description": "Fine typography, all opt-in (omitted = unchanged bytes). kerning, fontFeatures and the 'fr' narrow space need embedFonts:true. No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt.", + "properties": { + "bindShortWords": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "maxLength": { + "maximum": 3, + "minimum": 1, + "type": "integer" + }, + "words": { + "items": { + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + ], + "description": "Never end a line on a short word: up to maxLength letters (default 1), or exactly the listed words." + }, + "fontFeatures": { + "description": "OpenType features, later wins. tnum / lnum are no-ops on Noto Sans (TYPOGRAPHY_FEATURE_INEFFECTIVE).", + "items": { + "enum": [ + "tnum", + "pnum", + "lnum", + "onum", + "zero", + "ordn", + "sups", + "subs", + "smcp", + "c2sc", + "case" + ], + "type": "string" + }, + "maxItems": 11, + "type": "array", + "uniqueItems": true + }, + "hyphenationLanguage": { + "description": "BCP 47 tag; no effect here (no hyphenation provider installed).", + "maxLength": 35, + "pattern": "^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$", + "type": "string" + }, + "keepHeadingsWithNext": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "minLines": { + "maximum": 10, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + } + ], + "description": "Never strand a heading at a page foot. true = { minLines: 2 }." + }, + "kerning": { + "description": "Pair kerning (GPOS).", + "type": "boolean" + }, + "metrics": { + "description": "Base-14 text: 'exact' uses the AFM widths (different wraps). Default 'approximate'.", + "enum": [ + "approximate", + "exact" + ], + "type": "string" + }, + "opticalMargins": { + "description": "Hang punctuation into the margin of align:'justify' text.", + "type": "boolean" + }, + "orphans": { + "description": "Min lines left at a page foot (default 2; needs splitParagraphs).", + "maximum": 10, + "minimum": 1, + "type": "integer" + }, + "punctuationSpacing": { + "anyOf": [ + { + "enum": [ + "fr", + "fr-CA" + ], + "type": "string" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "char": { + "maxLength": 2, + "minLength": 1, + "type": "string" + }, + "side": { + "enum": [ + "before", + "after" + ], + "type": "string" + }, + "space": { + "description": "U+00A0 / U+202F (narrow needs embedFonts).", + "enum": [ + "nbsp", + "narrow" + ], + "type": "string" + } + }, + "required": [ + "char", + "side", + "space" + ], + "type": "object" + }, + "maxItems": 32, + "type": "array" + } + ], + "description": "No-break spaces next to punctuation (existing spaces only). 'fr': narrow before ; ! ?, no-break before ':' and inside « ». 'fr-CA': ':' and « » only. Or explicit rules." + }, + "splitParagraphs": { + "description": "Paragraphs may break across pages at a line boundary (default: atomic).", + "type": "boolean" + }, + "unitBinding": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "units": { + "items": { + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + ], + "description": "No-break space between a number and its unit ('150 €', '12 kg'); units replaces the built-in list." + }, + "widows": { + "description": "Min lines carried over (default 2; needs splitParagraphs).", + "maximum": 10, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" +} - changed
Output schema / properties / diagnostics / descriptionPrevious value: -"PDF/A diagnostics (when includeDiagnostics=true)."New value: +"Engine diagnostics (when includeDiagnostics=true)."
- Changed
add_international_text25 fields changed- changed
Input schema / properties / creationDate / descriptionPrevious value: -"ISO-8601 instant for /CreationDate (+ XMP). Pin it for byte-identical output across calls (same host TZ); omitted = wall clock, so every call differs."New value: +"ISO-8601 instant for /CreationDate (+ XMP, the trailer /ID and the {date} placeholder), written in UTC. Pin it for byte-identical output across calls and hosts; omitted = wall clock, so every call differs." - changed
Input schema / properties / footerTemplate / properties / center / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - added
Input schema / properties / footerTemplate / properties / color / anyOfAdded value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - changed
Input schema / properties / footerTemplate / properties / color / descriptionPrevious value: -"Hex colour."New value: +"Hex colour (#RRGGBB)." - removed
Input schema / properties / footerTemplate / properties / color / patternRemoved value: -"^#[0-9a-fA-F]{6}$" - removed
Input schema / properties / footerTemplate / properties / color / typeRemoved value: -"string" - changed
Input schema / properties / footerTemplate / properties / left / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / footerTemplate / properties / right / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / headerTemplate / properties / center / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - added
Input schema / properties / headerTemplate / properties / color / anyOfAdded value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - changed
Input schema / properties / headerTemplate / properties / color / descriptionPrevious value: -"Hex colour."New value: +"Hex colour (#RRGGBB)." - removed
Input schema / properties / headerTemplate / properties / color / patternRemoved value: -"^#[0-9a-fA-F]{6}$" - removed
Input schema / properties / headerTemplate / properties / color / typeRemoved value: -"string" - changed
Input schema / properties / headerTemplate / properties / left / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / headerTemplate / properties / right / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / includeDiagnostics / descriptionPrevious value: -"Return the PDF/A diagnostics raised while building as `diagnostics[]` (possibly empty)."New value: +"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*) as `diagnostics[]` (possibly empty)." - changed
Input schema / properties / lang / anyOfPrevious value: -[ - { - "enum": [ - "ar", - "he", - "th", - "ja", - "zh", - "ko", - "el", - "hi", - "bn", - "ta", - "ru", - "ka", - "hy", - "tr", - "pl", - "vi", - "latin", - "te", - "si", - "bo", - "km", - "my", - "am", - "emoji", - "math" - ], - "type": "string" - }, - { - "items": { - "enum": [ - "ar", - "he", - "th", - "ja", - "zh", - "ko", - "el", - "hi", - "bn", - "ta", - "ru", - "ka", - "hy", - "tr", - "pl", - "vi", - "latin", - "te", - "si", - "bo", - "km", - "my", - "am", - "emoji", - "math" - ], - "type": "string" - }, - "maxItems": 25, - "minItems": 1, - "type": "array" - }, - { - "description": "Comma-separated list of supported codes.", - "maxLength": 80, - "minLength": 2, - "type": "string" - } -]New value: +[ + { + "enum": [ + "ar", + "he", + "th", + "ja", + "zh", + "ko", + "el", + "hi", + "bn", + "ta", + "ru", + "ka", + "hy", + "tr", + "pl", + "vi", + "latin", + "te", + "si", + "bo", + "km", + "my", + "am", + "emoji", + "math", + "lo", + "nod", + "khb", + "tdd", + "cjm", + "ha", + "yo", + "ig", + "sw" + ], + "type": "string" + }, + { + "items": { + "enum": [ + "ar", + "he", + "th", + "ja", + "zh", + "ko", + "el", + "hi", + "bn", + "ta", + "ru", + "ka", + "hy", + "tr", + "pl", + "vi", + "latin", + "te", + "si", + "bo", + "km", + "my", + "am", + "emoji", + "math", + "lo", + "nod", + "khb", + "tdd", + "cjm", + "ha", + "yo", + "ig", + "sw" + ], + "type": "string" + }, + "maxItems": 34, + "minItems": 1, + "type": "array" + }, + { + "description": "Comma-separated list of supported codes.", + "maxLength": 80, + "minLength": 2, + "type": "string" + } +] - changed
Input schema / properties / lang / descriptionPrevious value: -"Language / script identifier. Either a single code (e.g. 'ar'), a comma-separated list ('ar,emoji'), or an array (['ar','emoji']). Multiple codes enable multi-font run splitting (script + emoji + Latin fallback)."New value: +"Language / script identifier. Either a single code (e.g. 'ar'), a comma-separated list ('ar,emoji'), or an array (['ar','emoji']). Multiple codes enable multi-font run splitting (script + emoji + Latin fallback). 27 scripts; ha / yo / ig / sw (Hausa, Yoruba, Igbo, Swahili) are aliases of latin, whose combining marks are anchored." - changed
Input schema / properties / outputIntent / descriptionPrevious value: -"Custom PDF/A OutputIntent: an RGB ICC profile + condition strings replacing the built-in sRGB intent (CMYK rejected)."New value: +"Custom OutputIntent (under pdfA or pdfx): an RGB, CMYK or Gray ICC profile + condition strings, replacing the built-in sRGB intent. The profile must be a real ICC file ('acsp' signature, consistent size — PRINT_ERROR otherwise); pdfx needs device class 'prtr'. Under a CMYK / Gray intent RGB content is mapped through a calibrated default space." - changed
Input schema / properties / outputIntent / properties / iccProfileBase64 / descriptionPrevious value: -"ICC profile bytes, base64 (RGB, ≤ 8 MiB)."New value: +"ICC profile bytes, base64 (RGB, CMYK or Gray; ≤ 8 MiB)." - added
Input schema / properties / pdfxAdded value: +{ + "description": "PDF/X-4 print exchange (ISO 15930-7). REQUIRES outputIntent with the printer's ICC profile (device class 'prtr'; CMYK or Gray — none is bundled); needs embedFonts:true for a conformant file (PDFX_NO_FONT_ENTRIES otherwise, strict:true refuses). Exclusive with pdfA and encrypt; metadata.trapped must be 'True' or 'False'; TrimBox or ArtBox, not both. Links and form fields are reported (PDFX_ANNOTATIONS). Check with validate_pdf standard:'pdf-x-4'. See the print_ready prompt.", + "enum": [ + "pdfx4" + ], + "type": "string" +} - changed
Input schema / properties / print / properties / marks / oneOfPrevious value: -[ - { - "type": "boolean" - }, - { - "additionalProperties": false, - "properties": { - "crop": { - "description": "Corner crop (trim) marks. Default true.", - "type": "boolean" - }, - "length": { - "description": "Mark length in points. Default 14.", - "maximum": 100, - "minimum": 1, - "type": "number" - }, - "offset": { - "description": "Gap between TrimBox and marks in points. Default 5.", - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "registration": { - "description": "Edge-midpoint registration targets. Default true.", - "type": "boolean" - }, - "weight": { - "description": "Stroke width in points. Default 0.25.", - "maximum": 5, - "minimum": 0.05, - "type": "number" - } - }, - "type": "object" - } -]New value: +[ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "colourBars": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "size": { + "description": "Patch size in points. Default 12.", + "maximum": 72, + "minimum": 4, + "type": "number" + }, + "tints": { + "description": "Add the four 50 % tint patches. Default true.", + "type": "boolean" + } + }, + "type": "object" + } + ], + "description": "Colour control strip in the bleed (C M Y K solids + their 50 % tints): true for defaults. Off by default; needs a bleed of about 5 mm (14.17 pt) and is skipped when the strip would not fit." + }, + "crop": { + "description": "Corner crop (trim) marks. Default true.", + "type": "boolean" + }, + "length": { + "description": "Mark length in points. Default 14.", + "maximum": 100, + "minimum": 1, + "type": "number" + }, + "offset": { + "description": "Gap between TrimBox and marks in points. Default 5.", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "registration": { + "description": "Edge-midpoint registration targets. Default true.", + "type": "boolean" + }, + "weight": { + "description": "Stroke width in points. Default 0.25.", + "maximum": 5, + "minimum": 0.05, + "type": "number" + } + }, + "type": "object" + } +] - changed
Input schema / properties / strict / descriptionPrevious value: -"Fail with PDF_A_COMPLIANCE_VIOLATION instead of producing a non-conformant PDF/A file (e.g. PDFA_NO_FONT_ENTRIES without embedFonts). Pair with embedFonts=true."New value: +"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true." - added
Input schema / properties / typographyAdded value: +{ + "additionalProperties": false, + "description": "Fine typography, all opt-in (omitted = unchanged bytes). kerning, fontFeatures and the 'fr' narrow space need embedFonts:true. No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt.", + "properties": { + "bindShortWords": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "maxLength": { + "maximum": 3, + "minimum": 1, + "type": "integer" + }, + "words": { + "items": { + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + ], + "description": "Never end a line on a short word: up to maxLength letters (default 1), or exactly the listed words." + }, + "fontFeatures": { + "description": "OpenType features, later wins. tnum / lnum are no-ops on Noto Sans (TYPOGRAPHY_FEATURE_INEFFECTIVE).", + "items": { + "enum": [ + "tnum", + "pnum", + "lnum", + "onum", + "zero", + "ordn", + "sups", + "subs", + "smcp", + "c2sc", + "case" + ], + "type": "string" + }, + "maxItems": 11, + "type": "array", + "uniqueItems": true + }, + "hyphenationLanguage": { + "description": "BCP 47 tag; no effect here (no hyphenation provider installed).", + "maxLength": 35, + "pattern": "^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$", + "type": "string" + }, + "keepHeadingsWithNext": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "minLines": { + "maximum": 10, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + } + ], + "description": "Never strand a heading at a page foot. true = { minLines: 2 }." + }, + "kerning": { + "description": "Pair kerning (GPOS).", + "type": "boolean" + }, + "metrics": { + "description": "Base-14 text: 'exact' uses the AFM widths (different wraps). Default 'approximate'.", + "enum": [ + "approximate", + "exact" + ], + "type": "string" + }, + "opticalMargins": { + "description": "Hang punctuation into the margin of align:'justify' text.", + "type": "boolean" + }, + "orphans": { + "description": "Min lines left at a page foot (default 2; needs splitParagraphs).", + "maximum": 10, + "minimum": 1, + "type": "integer" + }, + "punctuationSpacing": { + "anyOf": [ + { + "enum": [ + "fr", + "fr-CA" + ], + "type": "string" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "char": { + "maxLength": 2, + "minLength": 1, + "type": "string" + }, + "side": { + "enum": [ + "before", + "after" + ], + "type": "string" + }, + "space": { + "description": "U+00A0 / U+202F (narrow needs embedFonts).", + "enum": [ + "nbsp", + "narrow" + ], + "type": "string" + } + }, + "required": [ + "char", + "side", + "space" + ], + "type": "object" + }, + "maxItems": 32, + "type": "array" + } + ], + "description": "No-break spaces next to punctuation (existing spaces only). 'fr': narrow before ; ! ?, no-break before ':' and inside « ». 'fr-CA': ':' and « » only. Or explicit rules." + }, + "splitParagraphs": { + "description": "Paragraphs may break across pages at a line boundary (default: atomic).", + "type": "boolean" + }, + "unitBinding": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "units": { + "items": { + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + ], + "description": "No-break space between a number and its unit ('150 €', '12 kg'); units replaces the built-in list." + }, + "widows": { + "description": "Min lines carried over (default 2; needs splitParagraphs).", + "maximum": 10, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" +} - changed
Output schema / properties / diagnostics / descriptionPrevious value: -"PDF/A diagnostics (when includeDiagnostics=true)."New value: +"Engine diagnostics (when includeDiagnostics=true)."
- Changed
add_ltv1 field changed- changed
Output schema / properties / diagnostics / descriptionPrevious value: -"PDF/A diagnostics (when includeDiagnostics=true)."New value: +"Engine diagnostics (when includeDiagnostics=true)."
- Changed
add_table32 fields changed- added
Input schema / properties / cellBorders / properties / color / anyOfAdded value: +[ + { + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - removed
Input schema / properties / cellBorders / properties / color / typeRemoved value: -"string" - changed
Input schema / properties / creationDate / descriptionPrevious value: -"ISO-8601 instant for /CreationDate (+ XMP). Pin it for byte-identical output across calls (same host TZ); omitted = wall clock, so every call differs."New value: +"ISO-8601 instant for /CreationDate (+ XMP, the trailer /ID and the {date} placeholder), written in UTC. Pin it for byte-identical output across calls and hosts; omitted = wall clock, so every call differs." - changed
Input schema / properties / embedFonts / descriptionPrevious value: -"Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A claim (ISO 19005 §6.2.11.4.1) and for strict=true; adds ~0.3 MiB."New value: +"Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A or PDF/X claim (every font embedded) and for strict=true; adds ~0.3 MiB." - changed
Input schema / properties / footerTemplate / properties / center / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - added
Input schema / properties / footerTemplate / properties / color / anyOfAdded value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - changed
Input schema / properties / footerTemplate / properties / color / descriptionPrevious value: -"Hex colour."New value: +"Hex colour (#RRGGBB)." - removed
Input schema / properties / footerTemplate / properties / color / patternRemoved value: -"^#[0-9a-fA-F]{6}$" - removed
Input schema / properties / footerTemplate / properties / color / typeRemoved value: -"string" - changed
Input schema / properties / footerTemplate / properties / left / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / footerTemplate / properties / right / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / headerTemplate / properties / center / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - added
Input schema / properties / headerTemplate / properties / color / anyOfAdded value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - changed
Input schema / properties / headerTemplate / properties / color / descriptionPrevious value: -"Hex colour."New value: +"Hex colour (#RRGGBB)." - removed
Input schema / properties / headerTemplate / properties / color / patternRemoved value: -"^#[0-9a-fA-F]{6}$" - removed
Input schema / properties / headerTemplate / properties / color / typeRemoved value: -"string" - changed
Input schema / properties / headerTemplate / properties / left / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / headerTemplate / properties / right / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / includeDiagnostics / descriptionPrevious value: -"Return the PDF/A diagnostics raised while building as `diagnostics[]` (possibly empty)."New value: +"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*) as `diagnostics[]` (possibly empty)." - changed
Input schema / properties / outputIntent / descriptionPrevious value: -"Custom PDF/A OutputIntent: an RGB ICC profile + condition strings replacing the built-in sRGB intent (CMYK rejected)."New value: +"Custom OutputIntent (under pdfA or pdfx): an RGB, CMYK or Gray ICC profile + condition strings, replacing the built-in sRGB intent. The profile must be a real ICC file ('acsp' signature, consistent size — PRINT_ERROR otherwise); pdfx needs device class 'prtr'. Under a CMYK / Gray intent RGB content is mapped through a calibrated default space." - changed
Input schema / properties / outputIntent / properties / iccProfileBase64 / descriptionPrevious value: -"ICC profile bytes, base64 (RGB, ≤ 8 MiB)."New value: +"ICC profile bytes, base64 (RGB, CMYK or Gray; ≤ 8 MiB)." - added
Input schema / properties / pdfxAdded value: +{ + "description": "PDF/X-4 print exchange (ISO 15930-7). REQUIRES outputIntent with the printer's ICC profile (device class 'prtr'; CMYK or Gray — none is bundled); needs embedFonts:true for a conformant file (PDFX_NO_FONT_ENTRIES otherwise, strict:true refuses). Exclusive with pdfA and encrypt; metadata.trapped must be 'True' or 'False'; TrimBox or ArtBox, not both. Links and form fields are reported (PDFX_ANNOTATIONS). Check with validate_pdf standard:'pdf-x-4'. See the print_ready prompt.", + "enum": [ + "pdfx4" + ], + "type": "string" +} - changed
Input schema / properties / print / properties / marks / oneOfPrevious value: -[ - { - "type": "boolean" - }, - { - "additionalProperties": false, - "properties": { - "crop": { - "description": "Corner crop (trim) marks. Default true.", - "type": "boolean" - }, - "length": { - "description": "Mark length in points. Default 14.", - "maximum": 100, - "minimum": 1, - "type": "number" - }, - "offset": { - "description": "Gap between TrimBox and marks in points. Default 5.", - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "registration": { - "description": "Edge-midpoint registration targets. Default true.", - "type": "boolean" - }, - "weight": { - "description": "Stroke width in points. Default 0.25.", - "maximum": 5, - "minimum": 0.05, - "type": "number" - } - }, - "type": "object" - } -]New value: +[ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "colourBars": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "size": { + "description": "Patch size in points. Default 12.", + "maximum": 72, + "minimum": 4, + "type": "number" + }, + "tints": { + "description": "Add the four 50 % tint patches. Default true.", + "type": "boolean" + } + }, + "type": "object" + } + ], + "description": "Colour control strip in the bleed (C M Y K solids + their 50 % tints): true for defaults. Off by default; needs a bleed of about 5 mm (14.17 pt) and is skipped when the strip would not fit." + }, + "crop": { + "description": "Corner crop (trim) marks. Default true.", + "type": "boolean" + }, + "length": { + "description": "Mark length in points. Default 14.", + "maximum": 100, + "minimum": 1, + "type": "number" + }, + "offset": { + "description": "Gap between TrimBox and marks in points. Default 5.", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "registration": { + "description": "Edge-midpoint registration targets. Default true.", + "type": "boolean" + }, + "weight": { + "description": "Stroke width in points. Default 0.25.", + "maximum": 5, + "minimum": 0.05, + "type": "number" + } + }, + "type": "object" + } +] - changed
Input schema / properties / strict / descriptionPrevious value: -"Fail with PDF_A_COMPLIANCE_VIOLATION instead of producing a non-conformant PDF/A file (e.g. PDFA_NO_FONT_ENTRIES without embedFonts). Pair with embedFonts=true."New value: +"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true." - added
Input schema / properties / typographyAdded value: +{ + "additionalProperties": false, + "description": "Fine typography, all opt-in (omitted = unchanged bytes). kerning, fontFeatures and the 'fr' narrow space need embedFonts:true. No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt.", + "properties": { + "bindShortWords": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "maxLength": { + "maximum": 3, + "minimum": 1, + "type": "integer" + }, + "words": { + "items": { + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + ], + "description": "Never end a line on a short word: up to maxLength letters (default 1), or exactly the listed words." + }, + "fontFeatures": { + "description": "OpenType features, later wins. tnum / lnum are no-ops on Noto Sans (TYPOGRAPHY_FEATURE_INEFFECTIVE).", + "items": { + "enum": [ + "tnum", + "pnum", + "lnum", + "onum", + "zero", + "ordn", + "sups", + "subs", + "smcp", + "c2sc", + "case" + ], + "type": "string" + }, + "maxItems": 11, + "type": "array", + "uniqueItems": true + }, + "hyphenationLanguage": { + "description": "BCP 47 tag; no effect here (no hyphenation provider installed).", + "maxLength": 35, + "pattern": "^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$", + "type": "string" + }, + "keepHeadingsWithNext": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "minLines": { + "maximum": 10, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + } + ], + "description": "Never strand a heading at a page foot. true = { minLines: 2 }." + }, + "kerning": { + "description": "Pair kerning (GPOS).", + "type": "boolean" + }, + "metrics": { + "description": "Base-14 text: 'exact' uses the AFM widths (different wraps). Default 'approximate'.", + "enum": [ + "approximate", + "exact" + ], + "type": "string" + }, + "opticalMargins": { + "description": "Hang punctuation into the margin of align:'justify' text.", + "type": "boolean" + }, + "orphans": { + "description": "Min lines left at a page foot (default 2; needs splitParagraphs).", + "maximum": 10, + "minimum": 1, + "type": "integer" + }, + "punctuationSpacing": { + "anyOf": [ + { + "enum": [ + "fr", + "fr-CA" + ], + "type": "string" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "char": { + "maxLength": 2, + "minLength": 1, + "type": "string" + }, + "side": { + "enum": [ + "before", + "after" + ], + "type": "string" + }, + "space": { + "description": "U+00A0 / U+202F (narrow needs embedFonts).", + "enum": [ + "nbsp", + "narrow" + ], + "type": "string" + } + }, + "required": [ + "char", + "side", + "space" + ], + "type": "object" + }, + "maxItems": 32, + "type": "array" + } + ], + "description": "No-break spaces next to punctuation (existing spaces only). 'fr': narrow before ; ! ?, no-break before ':' and inside « ». 'fr-CA': ':' and « » only. Or explicit rules." + }, + "splitParagraphs": { + "description": "Paragraphs may break across pages at a line boundary (default: atomic).", + "type": "boolean" + }, + "unitBinding": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "units": { + "items": { + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + ], + "description": "No-break space between a number and its unit ('150 €', '12 kg'); units replaces the built-in list." + }, + "widows": { + "description": "Min lines carried over (default 2; needs splitParagraphs).", + "maximum": 10, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" +} - added
Input schema / properties / watermark / properties / color / anyOfAdded value: +[ + { + "items": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - changed
Input schema / properties / watermark / properties / color / descriptionPrevious value: -"Text RGB colour as a [r, g, b] triple in the 0.0–1.0 range. Default light gray [0.75, 0.75, 0.75]."New value: +"Text colour. RGB as a [r, g, b] triple in the 0.0–1.0 range; default light gray [0.75, 0.75, 0.75]." - removed
Input schema / properties / watermark / properties / color / itemsRemoved value: -{ - "maximum": 1, - "minimum": 0, - "type": "number" -} - removed
Input schema / properties / watermark / properties / color / maxItemsRemoved value: -3 - removed
Input schema / properties / watermark / properties / color / minItemsRemoved value: -3 - removed
Input schema / properties / watermark / properties / color / typeRemoved value: -"array" - changed
Output schema / properties / diagnostics / descriptionPrevious value: -"PDF/A diagnostics (when includeDiagnostics=true)."New value: +"Engine diagnostics (when includeDiagnostics=true)."
- Changed
annotate_pdf3 fields changed- changed
Input schema / properties / annotations / items / properties / color / oneOfPrevious value: -[ - { - "description": "Hex (e.g. \"#ffcc00\") or PDF operator string (\"R G B\").", - "type": "string" - }, - { - "description": "RGB tuple, 0.0–1.0.", - "items": { - "type": "number" - }, - "maxItems": 3, - "minItems": 3, - "type": "array" - } -]New value: +[ + { + "description": "Hex (e.g. \"#ffcc00\") or PDF operator string (\"R G B\", or \"C M Y K\" for DeviceCMYK), each operand 0.0–1.0.", + "type": "string" + }, + { + "description": "RGB tuple, 0.0–1.0.", + "items": { + "type": "number" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - changed
Input schema / properties / annotations / items / properties / interiorColor / oneOfPrevious value: -[ - { - "description": "Hex (e.g. \"#ffcc00\") or PDF operator string (\"R G B\").", - "type": "string" - }, - { - "description": "RGB tuple, 0.0–1.0.", - "items": { - "type": "number" - }, - "maxItems": 3, - "minItems": 3, - "type": "array" - } -]New value: +[ + { + "description": "Hex (e.g. \"#ffcc00\") or PDF operator string (\"R G B\", or \"C M Y K\" for DeviceCMYK), each operand 0.0–1.0.", + "type": "string" + }, + { + "description": "RGB tuple, 0.0–1.0.", + "items": { + "type": "number" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - changed
Output schema / properties / diagnostics / descriptionPrevious value: -"PDF/A diagnostics (when includeDiagnostics=true)."New value: +"Engine diagnostics (when includeDiagnostics=true)."
- Changed
decrypt_pdf1 field changed- changed
Output schema / properties / diagnostics / descriptionPrevious value: -"PDF/A diagnostics (when includeDiagnostics=true)."New value: +"Engine diagnostics (when includeDiagnostics=true)."
- Changed
embed_image24 fields changed- changed
Input schema / properties / creationDate / descriptionPrevious value: -"ISO-8601 instant for /CreationDate (+ XMP). Pin it for byte-identical output across calls (same host TZ); omitted = wall clock, so every call differs."New value: +"ISO-8601 instant for /CreationDate (+ XMP, the trailer /ID and the {date} placeholder), written in UTC. Pin it for byte-identical output across calls and hosts; omitted = wall clock, so every call differs." - changed
Input schema / properties / embedFonts / descriptionPrevious value: -"Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A claim (ISO 19005 §6.2.11.4.1) and for strict=true; adds ~0.3 MiB."New value: +"Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A or PDF/X claim (every font embedded) and for strict=true; adds ~0.3 MiB." - changed
Input schema / properties / footerTemplate / properties / center / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - added
Input schema / properties / footerTemplate / properties / color / anyOfAdded value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - changed
Input schema / properties / footerTemplate / properties / color / descriptionPrevious value: -"Hex colour."New value: +"Hex colour (#RRGGBB)." - removed
Input schema / properties / footerTemplate / properties / color / patternRemoved value: -"^#[0-9a-fA-F]{6}$" - removed
Input schema / properties / footerTemplate / properties / color / typeRemoved value: -"string" - changed
Input schema / properties / footerTemplate / properties / left / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / footerTemplate / properties / right / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / headerTemplate / properties / center / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - added
Input schema / properties / headerTemplate / properties / color / anyOfAdded value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - changed
Input schema / properties / headerTemplate / properties / color / descriptionPrevious value: -"Hex colour."New value: +"Hex colour (#RRGGBB)." - removed
Input schema / properties / headerTemplate / properties / color / patternRemoved value: -"^#[0-9a-fA-F]{6}$" - removed
Input schema / properties / headerTemplate / properties / color / typeRemoved value: -"string" - changed
Input schema / properties / headerTemplate / properties / left / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / headerTemplate / properties / right / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / includeDiagnostics / descriptionPrevious value: -"Return the PDF/A diagnostics raised while building as `diagnostics[]` (possibly empty)."New value: +"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*) as `diagnostics[]` (possibly empty)." - changed
Input schema / properties / outputIntent / descriptionPrevious value: -"Custom PDF/A OutputIntent: an RGB ICC profile + condition strings replacing the built-in sRGB intent (CMYK rejected)."New value: +"Custom OutputIntent (under pdfA or pdfx): an RGB, CMYK or Gray ICC profile + condition strings, replacing the built-in sRGB intent. The profile must be a real ICC file ('acsp' signature, consistent size — PRINT_ERROR otherwise); pdfx needs device class 'prtr'. Under a CMYK / Gray intent RGB content is mapped through a calibrated default space." - changed
Input schema / properties / outputIntent / properties / iccProfileBase64 / descriptionPrevious value: -"ICC profile bytes, base64 (RGB, ≤ 8 MiB)."New value: +"ICC profile bytes, base64 (RGB, CMYK or Gray; ≤ 8 MiB)." - added
Input schema / properties / pdfxAdded value: +{ + "description": "PDF/X-4 print exchange (ISO 15930-7). REQUIRES outputIntent with the printer's ICC profile (device class 'prtr'; CMYK or Gray — none is bundled); needs embedFonts:true for a conformant file (PDFX_NO_FONT_ENTRIES otherwise, strict:true refuses). Exclusive with pdfA and encrypt; metadata.trapped must be 'True' or 'False'; TrimBox or ArtBox, not both. Links and form fields are reported (PDFX_ANNOTATIONS). Check with validate_pdf standard:'pdf-x-4'. See the print_ready prompt.", + "enum": [ + "pdfx4" + ], + "type": "string" +} - changed
Input schema / properties / print / properties / marks / oneOfPrevious value: -[ - { - "type": "boolean" - }, - { - "additionalProperties": false, - "properties": { - "crop": { - "description": "Corner crop (trim) marks. Default true.", - "type": "boolean" - }, - "length": { - "description": "Mark length in points. Default 14.", - "maximum": 100, - "minimum": 1, - "type": "number" - }, - "offset": { - "description": "Gap between TrimBox and marks in points. Default 5.", - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "registration": { - "description": "Edge-midpoint registration targets. Default true.", - "type": "boolean" - }, - "weight": { - "description": "Stroke width in points. Default 0.25.", - "maximum": 5, - "minimum": 0.05, - "type": "number" - } - }, - "type": "object" - } -]New value: +[ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "colourBars": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "size": { + "description": "Patch size in points. Default 12.", + "maximum": 72, + "minimum": 4, + "type": "number" + }, + "tints": { + "description": "Add the four 50 % tint patches. Default true.", + "type": "boolean" + } + }, + "type": "object" + } + ], + "description": "Colour control strip in the bleed (C M Y K solids + their 50 % tints): true for defaults. Off by default; needs a bleed of about 5 mm (14.17 pt) and is skipped when the strip would not fit." + }, + "crop": { + "description": "Corner crop (trim) marks. Default true.", + "type": "boolean" + }, + "length": { + "description": "Mark length in points. Default 14.", + "maximum": 100, + "minimum": 1, + "type": "number" + }, + "offset": { + "description": "Gap between TrimBox and marks in points. Default 5.", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "registration": { + "description": "Edge-midpoint registration targets. Default true.", + "type": "boolean" + }, + "weight": { + "description": "Stroke width in points. Default 0.25.", + "maximum": 5, + "minimum": 0.05, + "type": "number" + } + }, + "type": "object" + } +] - changed
Input schema / properties / strict / descriptionPrevious value: -"Fail with PDF_A_COMPLIANCE_VIOLATION instead of producing a non-conformant PDF/A file (e.g. PDFA_NO_FONT_ENTRIES without embedFonts). Pair with embedFonts=true."New value: +"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true." - added
Input schema / properties / typographyAdded value: +{ + "additionalProperties": false, + "description": "Fine typography, all opt-in (omitted = unchanged bytes). kerning, fontFeatures and the 'fr' narrow space need embedFonts:true. No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt.", + "properties": { + "bindShortWords": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "maxLength": { + "maximum": 3, + "minimum": 1, + "type": "integer" + }, + "words": { + "items": { + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + ], + "description": "Never end a line on a short word: up to maxLength letters (default 1), or exactly the listed words." + }, + "fontFeatures": { + "description": "OpenType features, later wins. tnum / lnum are no-ops on Noto Sans (TYPOGRAPHY_FEATURE_INEFFECTIVE).", + "items": { + "enum": [ + "tnum", + "pnum", + "lnum", + "onum", + "zero", + "ordn", + "sups", + "subs", + "smcp", + "c2sc", + "case" + ], + "type": "string" + }, + "maxItems": 11, + "type": "array", + "uniqueItems": true + }, + "hyphenationLanguage": { + "description": "BCP 47 tag; no effect here (no hyphenation provider installed).", + "maxLength": 35, + "pattern": "^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$", + "type": "string" + }, + "keepHeadingsWithNext": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "minLines": { + "maximum": 10, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + } + ], + "description": "Never strand a heading at a page foot. true = { minLines: 2 }." + }, + "kerning": { + "description": "Pair kerning (GPOS).", + "type": "boolean" + }, + "metrics": { + "description": "Base-14 text: 'exact' uses the AFM widths (different wraps). Default 'approximate'.", + "enum": [ + "approximate", + "exact" + ], + "type": "string" + }, + "opticalMargins": { + "description": "Hang punctuation into the margin of align:'justify' text.", + "type": "boolean" + }, + "orphans": { + "description": "Min lines left at a page foot (default 2; needs splitParagraphs).", + "maximum": 10, + "minimum": 1, + "type": "integer" + }, + "punctuationSpacing": { + "anyOf": [ + { + "enum": [ + "fr", + "fr-CA" + ], + "type": "string" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "char": { + "maxLength": 2, + "minLength": 1, + "type": "string" + }, + "side": { + "enum": [ + "before", + "after" + ], + "type": "string" + }, + "space": { + "description": "U+00A0 / U+202F (narrow needs embedFonts).", + "enum": [ + "nbsp", + "narrow" + ], + "type": "string" + } + }, + "required": [ + "char", + "side", + "space" + ], + "type": "object" + }, + "maxItems": 32, + "type": "array" + } + ], + "description": "No-break spaces next to punctuation (existing spaces only). 'fr': narrow before ; ! ?, no-break before ':' and inside « ». 'fr-CA': ':' and « » only. Or explicit rules." + }, + "splitParagraphs": { + "description": "Paragraphs may break across pages at a line boundary (default: atomic).", + "type": "boolean" + }, + "unitBinding": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "units": { + "items": { + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + ], + "description": "No-break space between a number and its unit ('150 €', '12 kg'); units replaces the built-in list." + }, + "widows": { + "description": "Min lines carried over (default 2; needs splitParagraphs).", + "maximum": 10, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" +} - changed
Output schema / properties / diagnostics / descriptionPrevious value: -"PDF/A diagnostics (when includeDiagnostics=true)."New value: +"Engine diagnostics (when includeDiagnostics=true)."
- Changed
encrypt_pdf1 field changed- changed
Output schema / properties / diagnostics / descriptionPrevious value: -"PDF/A diagnostics (when includeDiagnostics=true)."New value: +"Engine diagnostics (when includeDiagnostics=true)."
- Changed
extract_pages1 field changed- changed
Output schema / properties / diagnostics / descriptionPrevious value: -"PDF/A diagnostics (when includeDiagnostics=true)."New value: +"Engine diagnostics (when includeDiagnostics=true)."
- Changed
fill_form1 field changed- changed
Output schema / properties / diagnostics / descriptionPrevious value: -"PDF/A diagnostics (when includeDiagnostics=true)."New value: +"Engine diagnostics (when includeDiagnostics=true)."
- Changed
generate_basic_pdf32 fields changed- changed
Input schema / properties / blocks / items / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "level": { - "enum": [ - 1, - 2, - 3 - ], - "type": "integer" - }, - "text": { - "maxLength": 500, - "minLength": 1, - "type": "string" - }, - "type": { - "const": "heading" - } - }, - "required": [ - "type", - "text", - "level" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "text": { - "description": "Paragraph text. Embedded newlines ('\\n') are automatically split into separate paragraphs — no need to pre-split; never emit a literal newline expecting a soft line break.", - "maxLength": 50000, - "minLength": 1, - "type": "string" - }, - "type": { - "const": "paragraph" - } - }, - "required": [ - "type", - "text" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "description": "List items. A string is a leaf; an object { text, items } nests a sub-list (bullets/numbers indent; numbered sub-lists restart at 1).", - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "style": { - "default": "bullet", - "enum": [ - "bullet", - "numbered" - ], - "type": "string" - }, - "type": { - "const": "list" - } - }, - "required": [ - "type", - "items" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "type": { - "const": "pageBreak" - } - }, - "required": [ - "type" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "height": { - "maximum": 500, - "minimum": 1, - "type": "number" - }, - "type": { - "const": "spacer" - } - }, - "required": [ - "type", - "height" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Native vector chart rendered as pure PDF path operators — bar / horizontal-bar / stacked-bar / line / area / scatter / pie / donut (pdfnative 1.7 charts v2: time and log axes, data labels, secondary axis, legends). Same body as add_chart.", - "properties": { - "align": { - "description": "Horizontal alignment within the content width. Default 'left'.", - "enum": [ - "left", - "center", - "right" - ], - "type": "string" - }, - "altText": { - "description": "Alt text for the tagged-PDF /Figure /Alt. Auto-generated when omitted.", - "maxLength": 500, - "type": "string" - }, - "axis": { - "additionalProperties": false, - "description": "Value-axis options (bar/line only).", - "properties": { - "grid": { - "description": "Draw horizontal gridlines.", - "type": "boolean" - }, - "scale": { - "description": "Value-axis scale. 'log' requires strictly positive values and is not available for stacked charts.", - "enum": [ - "linear", - "log" - ], - "type": "string" - }, - "ticks": { - "description": "Target tick count (nice 1/2/5×10ⁿ steps).", - "maximum": 20, - "minimum": 2, - "type": "integer" - }, - "yMax": { - "description": "Force the axis maximum (values are clamped to the plot band).", - "type": "number" - }, - "yMin": { - "description": "Force the axis minimum (values are clamped to the plot band).", - "type": "number" - } - }, - "type": "object" - }, - "axis2": { - "additionalProperties": false, - "description": "Secondary RIGHT value axis (drawn only when a series sets yAxis:'right').", - "properties": { - "scale": { - "enum": [ - "linear", - "log" - ], - "type": "string" - }, - "ticks": { - "maximum": 20, - "minimum": 2, - "type": "integer" - }, - "yMax": { - "type": "number" - }, - "yMin": { - "type": "number" - } - }, - "type": "object" - }, - "categories": { - "description": "Category / slice labels (x-axis). Defaults to 1-based indices when omitted.", - "items": { - "maxLength": 200, - "type": "string" - }, - "maxItems": 1000, - "type": "array" - }, - "chartType": { - "description": "Chart kind. 'pie'/'donut' use exactly one series; 'bar'/'barH'/'stackedBar'/'stackedBarH'/'line'/'area'/'scatter' support multiple series. 'scatter' requires xValues on every series and a positional xAxis.type ('linear' or 'time').", - "enum": [ - "bar", - "barH", - "stackedBar", - "stackedBarH", - "line", - "area", - "scatter", - "pie", - "donut" - ], - "type": "string" - }, - "colors": { - "description": "Palette override (per-series for bar/line, per-slice for pie/donut).", - "items": { - "description": "CSS-style hex colour, e.g. \"#3366cc\".", - "pattern": "^#?[0-9a-fA-F]{6}$", - "type": "string" - }, - "maxItems": 50, - "type": "array" - }, - "dataLabels": { - "description": "Per-point value labels: true for defaults, or an object to format them.", - "oneOf": [ - { - "type": "boolean" - }, - { - "additionalProperties": false, - "properties": { - "decimals": { - "maximum": 6, - "minimum": 0, - "type": "integer" - }, - "prefix": { - "maxLength": 16, - "type": "string" - }, - "suffix": { - "maxLength": 16, - "type": "string" - } - }, - "type": "object" - } - ] - }, - "height": { - "description": "Plot-area height in points. Default 240.", - "maximum": 2000, - "minimum": 50, - "type": "number" - }, - "labelRotation": { - "description": "Rotate category labels counter-clockwise by this many degrees (disables the automatic stride).", - "maximum": 90, - "minimum": 0, - "type": "number" - }, - "labelStride": { - "description": "Draw every Nth category label. Default: automatic (measured non-overlap); 1 draws every label.", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "legend": { - "description": "Legend placement. Defaults to 'bottom' for multi-series/pie, else 'none'.", - "enum": [ - "bottom", - "none" - ], - "type": "string" - }, - "markers": { - "description": "Draw point markers on line series. Default false.", - "type": "boolean" - }, - "series": { - "description": "Data series. Pie/donut charts use exactly one series (each value becomes a slice).", - "items": { - "additionalProperties": false, - "properties": { - "color": { - "description": "CSS-style hex colour, e.g. \"#3366cc\".", - "pattern": "^#?[0-9a-fA-F]{6}$", - "type": "string" - }, - "label": { - "description": "Series label (shown in the legend).", - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "values": { - "description": "Numeric values, one per category. Negative values are supported for bar/line.", - "items": { - "type": "number" - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "xValues": { - "description": "Per-point x positions (same length as values) for scatter charts and for line/area charts with xAxis.type 'linear' or 'time'.", - "items": { - "description": "Positional x value: a number (linear axis) or an ISO-8601 date / epoch milliseconds (time axis).", - "maxLength": 64, - "type": [ - "number", - "string" - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "yAxis": { - "description": "Bind the series to the left (default) or the secondary right value axis (cartesian charts only; configure its range with 'axis2').", - "enum": [ - "left", - "right" - ], - "type": "string" - } - }, - "required": [ - "label", - "values" - ], - "type": "object" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "title": { - "description": "Chart title rendered above the plot.", - "maxLength": 200, - "type": "string" - }, - "type": { - "const": "chart" - }, - "width": { - "description": "Plot width in points (clamped to content width). Default 460.", - "maximum": 2000, - "minimum": 50, - "type": "number" - }, - "xAxis": { - "additionalProperties": false, - "description": "Horizontal axis. 'category' (default) positions points by index; 'linear' / 'time' position them by series xValues (line/area/scatter only). Time ticks are UTC-deterministic.", - "properties": { - "grid": { - "description": "Draw vertical gridlines.", - "type": "boolean" - }, - "max": { - "description": "Axis maximum (number, or ISO-8601 / epoch ms for time axes).", - "maxLength": 64, - "type": [ - "number", - "string" - ] - }, - "min": { - "description": "Axis minimum (number, or ISO-8601 / epoch ms for time axes).", - "maxLength": 64, - "type": [ - "number", - "string" - ] - }, - "ticks": { - "maximum": 20, - "minimum": 2, - "type": "integer" - }, - "type": { - "enum": [ - "category", - "linear", - "time" - ], - "type": "string" - } - }, - "type": "object" - } - }, - "required": [ - "type", - "chartType", - "series" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Inline smart table — same body as add_table (every row must have exactly as many cells as headers).", - "properties": { - "autoFitColumns": { - "description": "Auto-fit column widths to content. Output bytes then depend on text metrics (not byte-deterministic across content changes).", - "type": "boolean" - }, - "caption": { - "description": "Caption rendered above the table (tagged as /Caption under PDF/A).", - "maxLength": 200, - "type": "string" - }, - "cellBorders": { - "additionalProperties": false, - "description": "Per-cell vector borders (pure strokes, PDF/A-safe). Choose individual sides or `all`.", - "properties": { - "all": { - "description": "Draw all four edges (overrides the individual side flags).", - "type": "boolean" - }, - "bottom": { - "type": "boolean" - }, - "color": { - "description": "Stroke colour as a PDF operator string ('0.8 0.8 0.8') or hex. Default light grey.", - "type": "string" - }, - "left": { - "type": "boolean" - }, - "right": { - "type": "boolean" - }, - "style": { - "description": "Stroke style (default 'solid').", - "enum": [ - "solid", - "dashed", - "dotted" - ], - "type": "string" - }, - "top": { - "type": "boolean" - }, - "width": { - "description": "Stroke width in points (default 0.5).", - "maximum": 10, - "minimum": 0, - "type": "number" - } - }, - "type": "object" - }, - "cellPadding": { - "description": "Horizontal cell padding in points (default 3).", - "maximum": 50, - "minimum": 0, - "type": "number" - }, - "cellVAlign": { - "description": "Vertical alignment of cell content.", - "enum": [ - "top", - "middle", - "bottom" - ], - "type": "string" - }, - "clipCells": { - "description": "Clip cell contents to the column bounds (PDF clip operators). Recommended for PDF/A and visual safety.", - "type": "boolean" - }, - "headers": { - "description": "Column header labels. Must have the same length as each row in `rows`.", - "items": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "minRowHeight": { - "description": "Minimum row height in points (default 12).", - "maximum": 200, - "minimum": 1, - "type": "number" - }, - "repeatHeader": { - "description": "Repeat the header row on every continuation page (default true).", - "type": "boolean" - }, - "rows": { - "description": "Data rows. Each row is an array of cell strings with the same length as `headers`.", - "items": { - "items": { - "maxLength": 500, - "type": "string" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "maxItems": 5000, - "minItems": 1, - "type": "array" - }, - "type": { - "const": "table" - }, - "wrap": { - "description": "Cell wrap policy: 'auto' (default) wraps only overflowing cells; 'always' wraps every cell; 'never' truncates.", - "enum": [ - "auto", - "always", - "never" - ], - "type": "string" - }, - "zebra": { - "description": "Alternate-row light tint (static fill, PDF/A-1b safe).", - "type": "boolean" - } - }, - "required": [ - "type", - "headers", - "rows" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Inline JPEG/PNG image. Without width/height the pixel size is used as points and clamped to the content width; with one dimension the aspect ratio is kept. The decoded bytes of all image blocks in one call are capped at 24 MiB (a watermark image has its own 8 MiB cap).", - "properties": { - "align": { - "default": "left", - "description": "Horizontal placement inside the content width.", - "enum": [ - "left", - "center", - "right" - ], - "type": "string" - }, - "alt": { - "description": "Accessible description (tagged /Figure /Alt). Always provide it for non-decorative content under PDF/A or PDF/UA.", - "maxLength": 500, - "type": "string" - }, - "height": { - "description": "Render height in points.", - "maximum": 1000, - "minimum": 10, - "type": "number" - }, - "imageBase64": { - "description": "Base64 image bytes. JPEG (baseline; 1, 3 or 4 components — CMYK raises PDFA_DEVICE_CMYK_IMAGE under PDF/A) or PNG (8-bit greyscale/RGB, non-interlaced; alpha-channel and palette PNGs are rejected with a remedy). No data: URI.", - "maxLength": 12000000, - "minLength": 4, - "type": "string" - }, - "mimeType": { - "description": "MIME type of the image. Must match the actual encoding of imageBase64 (magic bytes are checked).", - "enum": [ - "image/jpeg", - "image/png" - ], - "type": "string" - }, - "type": { - "const": "image" - }, - "width": { - "description": "Render width in points.", - "maximum": 800, - "minimum": 10, - "type": "number" - } - }, - "required": [ - "type", - "imageBase64", - "mimeType" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Clickable external link (/URI action). Only http:, https: and mailto: URLs are accepted.", - "properties": { - "color": { - "description": "Hex colour (#RGB or #RRGGBB).", - "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$", - "type": "string" - }, - "fontSize": { - "description": "Default 10.", - "maximum": 48, - "minimum": 6, - "type": "number" - }, - "text": { - "maxLength": 500, - "minLength": 1, - "type": "string" - }, - "type": { - "const": "link" - }, - "url": { - "description": "http(s):// or mailto: URL.", - "maxLength": 2048, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "type", - "text", - "url" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Printed table of contents generated from the document's heading blocks (internal /GoTo links with dot leaders). Pairs with outline:'auto' for the bookmark pane.", - "properties": { - "fontSize": { - "description": "Default 10.", - "maximum": 24, - "minimum": 6, - "type": "number" - }, - "indent": { - "description": "Points of indent per heading level (default 15).", - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxLevel": { - "description": "Deepest heading level listed (default 3).", - "enum": [ - 1, - 2, - 3 - ], - "type": "integer" - }, - "title": { - "description": "Default 'Table of Contents'.", - "maxLength": 200, - "type": "string" - }, - "type": { - "const": "toc" - } - }, - "required": [ - "type" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Inline barcode — same body as add_barcode (pure vector, no /Alt available in the engine).", - "properties": { - "align": { - "default": "left", - "description": "Horizontal placement inside the content width.", - "enum": [ - "left", - "center", - "right" - ], - "type": "string" - }, - "data": { - "description": "Raw payload to encode — do NOT URL-encode. For QR/URL pass e.g. \"https://example.com\" verbatim. EAN-13 must be 12 or 13 digits (13th is auto-computed). Code 128 accepts ASCII alphanumerics.", - "maxLength": 4296, - "minLength": 1, - "type": "string" - }, - "ecLevel": { - "default": "M", - "description": "QR ONLY. Error correction level (L=7%, M=15%, Q=25%, H=30%). Ignored for code128/ean13/datamatrix/pdf417. Use H for printed media that may get smudged or partially covered (e.g. logo overlay).", - "enum": [ - "L", - "M", - "Q", - "H" - ], - "type": "string" - }, - "format": { - "description": "Barcode symbology to render.", - "enum": [ - "qr", - "code128", - "ean13", - "datamatrix", - "pdf417" - ], - "type": "string" - }, - "height": { - "default": 200, - "description": "Barcode height in PDF points (ignored for square symbologies like QR/Data Matrix).", - "maximum": 500, - "minimum": 30, - "type": "number" - }, - "type": { - "const": "barcode" - }, - "width": { - "default": 200, - "description": "Barcode width in PDF points.", - "maximum": 500, - "minimum": 30, - "type": "number" - } - }, - "required": [ - "type", - "format", - "data" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Vector drawing from an SVG path `d` string or SVG markup. Supported: <path> <rect> (rx/ry) <circle> <ellipse> <line> <polyline> <polygon> and <text>/<tspan> (x, y, font-size, fill, text-anchor, dx/dy); fill / stroke / stroke-width attributes; double-quoted attributes only. NOT supported (silently ignored): transform, <g>, <use>, <image>, <defs>/<clipPath>, gradients, opacity, CSS/style, dash patterns, text word-wrap. No external reference is ever fetched (no XML parser: entities other than & < > " ' &#n; are dropped). Pure path operators — PDF/A-safe at every level.", - "properties": { - "align": { - "default": "left", - "description": "Horizontal placement inside the content width.", - "enum": [ - "left", - "center", - "right" - ], - "type": "string" - }, - "alt": { - "description": "Accessible description (tagged /Figure /Alt). Always provide it for non-decorative content under PDF/A or PDF/UA.", - "maxLength": 500, - "type": "string" - }, - "data": { - "description": "Path `d` string or SVG markup (≤ 100 000 characters).", - "maxLength": 100000, - "minLength": 1, - "type": "string" - }, - "fill": { - "description": "Hex colour or 'none' (default black).", - "pattern": "^(?:none|#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}))$", - "type": "string" - }, - "height": { - "description": "Render height in points (default 200).", - "maximum": 1000, - "minimum": 10, - "type": "number" - }, - "stroke": { - "description": "Hex colour or 'none' (default none).", - "pattern": "^(?:none|#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}))$", - "type": "string" - }, - "strokeWidth": { - "description": "Stroke width in SVG user units (default 1).", - "maximum": 50, - "minimum": 0, - "type": "number" - }, - "type": { - "const": "svg" - }, - "viewBox": { - "description": "[minX, minY, width, height] — overrides the viewBox of the markup; required for a bare path string that is not 0-based.", - "items": { - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - }, - "width": { - "description": "Render width in points (default 200).", - "maximum": 800, - "minimum": 10, - "type": "number" - } - }, - "required": [ - "type", - "data" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Inline AcroForm field — same body as an add_form field. Under a PDF/A claim the widget appearance font is not embedded (PDFA_UNEMBEDDED_FORM_FONT; strict:true fails the call).", - "properties": { - "checked": { - "description": "Initial checked state for checkbox / radio fields.", - "type": "boolean" - }, - "fieldType": { - "description": "Type of form control to render. Radio fields sharing a name form one radio group.", - "enum": [ - "text", - "textarea", - "checkbox", - "radio", - "dropdown", - "listbox" - ], - "type": "string" - }, - "fontSize": { - "description": "Font size for text rendering inside the field.", - "maximum": 48, - "minimum": 6, - "type": "number" - }, - "height": { - "description": "Field height in points (default depends on the type).", - "maximum": 300, - "minimum": 10, - "type": "number" - }, - "label": { - "description": "Human-readable label shown above the field.", - "maxLength": 200, - "type": "string" - }, - "maxLength": { - "description": "Maximum character length for text/textarea fields.", - "maximum": 32767, - "minimum": 1, - "type": "integer" - }, - "name": { - "description": "Unique field name used as the PDF annotation identifier (/T).", - "maxLength": 100, - "minLength": 1, - "type": "string" - }, - "options": { - "description": "Choices for dropdown, listbox or radio fields.", - "items": { - "maxLength": 200, - "type": "string" - }, - "maxItems": 100, - "type": "array" - }, - "placeholder": { - "description": "Hint text shown while the field is empty.", - "maxLength": 200, - "type": "string" - }, - "readOnly": { - "description": "Prevent editing of this field.", - "type": "boolean" - }, - "required": { - "description": "Mark field as required.", - "type": "boolean" - }, - "type": { - "const": "formField" - }, - "value": { - "description": "Default value pre-filled in the field.", - "maxLength": 2000, - "type": "string" - }, - "width": { - "description": "Field width in points (default: full content width).", - "maximum": 500, - "minimum": 10, - "type": "number" - } - }, - "required": [ - "type", - "fieldType", - "name" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "keepWithNext": { + "description": "Keep this heading on the same page as the block that follows. Overrides typography.keepHeadingsWithNext for this block, either way.", + "type": "boolean" + }, + "level": { + "enum": [ + 1, + 2, + 3 + ], + "type": "integer" + }, + "text": { + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "heading" + } + }, + "required": [ + "type", + "text", + "level" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "align": { + "description": "Text alignment (default left). 'justify' spans every line but the last across the measure; pair it with typography.opticalMargins.", + "enum": [ + "left", + "right", + "center", + "justify" + ], + "type": "string" + }, + "keepWithNext": { + "description": "Keep this paragraph on the same page as the block that follows (a lead-in line before a table or figure). Default false.", + "type": "boolean" + }, + "splittable": { + "description": "Allow / forbid this paragraph breaking across pages, overriding typography.splitParagraphs for this block.", + "type": "boolean" + }, + "text": { + "description": "Paragraph text. Embedded newlines ('\\n') are automatically split into separate paragraphs — no need to pre-split; never emit a literal newline expecting a soft line break.", + "maxLength": 50000, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "paragraph" + } + }, + "required": [ + "type", + "text" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "description": "List items. A string is a leaf; an object { text, items } nests a sub-list (bullets/numbers indent; numbered sub-lists restart at 1).", + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "style": { + "default": "bullet", + "enum": [ + "bullet", + "numbered" + ], + "type": "string" + }, + "type": { + "const": "list" + } + }, + "required": [ + "type", + "items" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "type": { + "const": "pageBreak" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "height": { + "maximum": 500, + "minimum": 1, + "type": "number" + }, + "type": { + "const": "spacer" + } + }, + "required": [ + "type", + "height" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Native vector chart rendered as pure PDF path operators — bar / horizontal-bar / stacked-bar / line / area / scatter / pie / donut (pdfnative 1.7 charts v2: time and log axes, data labels, secondary axis, legends). Same body as add_chart.", + "properties": { + "align": { + "description": "Horizontal alignment within the content width. Default 'left'.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + }, + "altText": { + "description": "Alt text for the tagged-PDF /Figure /Alt. Auto-generated when omitted.", + "maxLength": 500, + "type": "string" + }, + "axis": { + "additionalProperties": false, + "description": "Value-axis options (bar/line only).", + "properties": { + "grid": { + "description": "Draw horizontal gridlines.", + "type": "boolean" + }, + "scale": { + "description": "Value-axis scale. 'log' requires strictly positive values and is not available for stacked charts.", + "enum": [ + "linear", + "log" + ], + "type": "string" + }, + "ticks": { + "description": "Target tick count (nice 1/2/5×10ⁿ steps).", + "maximum": 20, + "minimum": 2, + "type": "integer" + }, + "yMax": { + "description": "Force the axis maximum (values are clamped to the plot band).", + "type": "number" + }, + "yMin": { + "description": "Force the axis minimum (values are clamped to the plot band).", + "type": "number" + } + }, + "type": "object" + }, + "axis2": { + "additionalProperties": false, + "description": "Secondary RIGHT value axis (drawn only when a series sets yAxis:'right').", + "properties": { + "scale": { + "enum": [ + "linear", + "log" + ], + "type": "string" + }, + "ticks": { + "maximum": 20, + "minimum": 2, + "type": "integer" + }, + "yMax": { + "type": "number" + }, + "yMin": { + "type": "number" + } + }, + "type": "object" + }, + "categories": { + "description": "Category / slice labels (x-axis). Defaults to 1-based indices when omitted.", + "items": { + "maxLength": 200, + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "chartType": { + "description": "Chart kind. 'pie'/'donut' use exactly one series; 'bar'/'barH'/'stackedBar'/'stackedBarH'/'line'/'area'/'scatter' support multiple series. 'scatter' requires xValues on every series and a positional xAxis.type ('linear' or 'time').", + "enum": [ + "bar", + "barH", + "stackedBar", + "stackedBarH", + "line", + "area", + "scatter", + "pie", + "donut" + ], + "type": "string" + }, + "colors": { + "description": "Palette override (per-series for bar/line, per-slice for pie/donut).", + "items": { + "anyOf": [ + { + "pattern": "^#?[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } + ], + "description": "CSS-style hex colour, e.g. \"#3366cc\"." + }, + "maxItems": 50, + "type": "array" + }, + "dataLabels": { + "description": "Per-point value labels: true for defaults, or an object to format them.", + "oneOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "decimals": { + "maximum": 6, + "minimum": 0, + "type": "integer" + }, + "prefix": { + "maxLength": 16, + "type": "string" + }, + "suffix": { + "maxLength": 16, + "type": "string" + } + }, + "type": "object" + } + ] + }, + "height": { + "description": "Plot-area height in points. Default 240.", + "maximum": 2000, + "minimum": 50, + "type": "number" + }, + "labelRotation": { + "description": "Rotate category labels counter-clockwise by this many degrees (disables the automatic stride).", + "maximum": 90, + "minimum": 0, + "type": "number" + }, + "labelStride": { + "description": "Draw every Nth category label. Default: automatic (measured non-overlap); 1 draws every label.", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "legend": { + "description": "Legend placement. Defaults to 'bottom' for multi-series/pie, else 'none'.", + "enum": [ + "bottom", + "none" + ], + "type": "string" + }, + "markers": { + "description": "Draw point markers on line series. Default false.", + "type": "boolean" + }, + "series": { + "description": "Data series. Pie/donut charts use exactly one series (each value becomes a slice).", + "items": { + "additionalProperties": false, + "properties": { + "color": { + "anyOf": [ + { + "pattern": "^#?[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } + ], + "description": "CSS-style hex colour, e.g. \"#3366cc\"." + }, + "label": { + "description": "Series label (shown in the legend).", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "values": { + "description": "Numeric values, one per category. Negative values are supported for bar/line.", + "items": { + "type": "number" + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "xValues": { + "description": "Per-point x positions (same length as values) for scatter charts and for line/area charts with xAxis.type 'linear' or 'time'.", + "items": { + "description": "Positional x value: a number (linear axis) or an ISO-8601 date / epoch milliseconds (time axis).", + "maxLength": 64, + "type": [ + "number", + "string" + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "yAxis": { + "description": "Bind the series to the left (default) or the secondary right value axis (cartesian charts only; configure its range with 'axis2').", + "enum": [ + "left", + "right" + ], + "type": "string" + } + }, + "required": [ + "label", + "values" + ], + "type": "object" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "title": { + "description": "Chart title rendered above the plot.", + "maxLength": 200, + "type": "string" + }, + "type": { + "const": "chart" + }, + "width": { + "description": "Plot width in points (clamped to content width). Default 460.", + "maximum": 2000, + "minimum": 50, + "type": "number" + }, + "xAxis": { + "additionalProperties": false, + "description": "Horizontal axis. 'category' (default) positions points by index; 'linear' / 'time' position them by series xValues (line/area/scatter only). Time ticks are UTC-deterministic.", + "properties": { + "grid": { + "description": "Draw vertical gridlines.", + "type": "boolean" + }, + "max": { + "description": "Axis maximum (number, or ISO-8601 / epoch ms for time axes).", + "maxLength": 64, + "type": [ + "number", + "string" + ] + }, + "min": { + "description": "Axis minimum (number, or ISO-8601 / epoch ms for time axes).", + "maxLength": 64, + "type": [ + "number", + "string" + ] + }, + "ticks": { + "maximum": 20, + "minimum": 2, + "type": "integer" + }, + "type": { + "enum": [ + "category", + "linear", + "time" + ], + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "type", + "chartType", + "series" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Inline smart table — same body as add_table (every row must have exactly as many cells as headers).", + "properties": { + "autoFitColumns": { + "description": "Auto-fit column widths to content. Output bytes then depend on text metrics (not byte-deterministic across content changes).", + "type": "boolean" + }, + "caption": { + "description": "Caption rendered above the table (tagged as /Caption under PDF/A).", + "maxLength": 200, + "type": "string" + }, + "cellBorders": { + "additionalProperties": false, + "description": "Per-cell vector borders (pure strokes, PDF/A-safe). Choose individual sides or `all`.", + "properties": { + "all": { + "description": "Draw all four edges (overrides the individual side flags).", + "type": "boolean" + }, + "bottom": { + "type": "boolean" + }, + "color": { + "anyOf": [ + { + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } + ], + "description": "Stroke colour as a PDF operator string ('0.8 0.8 0.8') or hex. Default light grey." + }, + "left": { + "type": "boolean" + }, + "right": { + "type": "boolean" + }, + "style": { + "description": "Stroke style (default 'solid').", + "enum": [ + "solid", + "dashed", + "dotted" + ], + "type": "string" + }, + "top": { + "type": "boolean" + }, + "width": { + "description": "Stroke width in points (default 0.5).", + "maximum": 10, + "minimum": 0, + "type": "number" + } + }, + "type": "object" + }, + "cellPadding": { + "description": "Horizontal cell padding in points (default 3).", + "maximum": 50, + "minimum": 0, + "type": "number" + }, + "cellVAlign": { + "description": "Vertical alignment of cell content.", + "enum": [ + "top", + "middle", + "bottom" + ], + "type": "string" + }, + "clipCells": { + "description": "Clip cell contents to the column bounds (PDF clip operators). Recommended for PDF/A and visual safety.", + "type": "boolean" + }, + "headers": { + "description": "Column header labels. Must have the same length as each row in `rows`.", + "items": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "minRowHeight": { + "description": "Minimum row height in points (default 12).", + "maximum": 200, + "minimum": 1, + "type": "number" + }, + "repeatHeader": { + "description": "Repeat the header row on every continuation page (default true).", + "type": "boolean" + }, + "rows": { + "description": "Data rows. Each row is an array of cell strings with the same length as `headers`.", + "items": { + "items": { + "maxLength": 500, + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "maxItems": 5000, + "minItems": 1, + "type": "array" + }, + "type": { + "const": "table" + }, + "wrap": { + "description": "Cell wrap policy: 'auto' (default) wraps only overflowing cells; 'always' wraps every cell; 'never' truncates.", + "enum": [ + "auto", + "always", + "never" + ], + "type": "string" + }, + "zebra": { + "description": "Alternate-row light tint (static fill, PDF/A-1b safe).", + "type": "boolean" + } + }, + "required": [ + "type", + "headers", + "rows" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Inline JPEG/PNG image. Without width/height the pixel size is used as points and clamped to the content width; with one dimension the aspect ratio is kept. The decoded bytes of all image blocks in one call are capped at 24 MiB (a watermark image has its own 8 MiB cap).", + "properties": { + "align": { + "default": "left", + "description": "Horizontal placement inside the content width.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + }, + "alt": { + "description": "Accessible description (tagged /Figure /Alt). Always provide it for non-decorative content under PDF/A or PDF/UA.", + "maxLength": 500, + "type": "string" + }, + "height": { + "description": "Render height in points.", + "maximum": 1000, + "minimum": 10, + "type": "number" + }, + "imageBase64": { + "description": "Base64 image bytes. JPEG (baseline; 1, 3 or 4 components — CMYK raises PDFA_DEVICE_CMYK_IMAGE under PDF/A) or PNG (8-bit greyscale/RGB, non-interlaced; alpha-channel and palette PNGs are rejected with a remedy). No data: URI.", + "maxLength": 12000000, + "minLength": 4, + "type": "string" + }, + "mimeType": { + "description": "MIME type of the image. Must match the actual encoding of imageBase64 (magic bytes are checked).", + "enum": [ + "image/jpeg", + "image/png" + ], + "type": "string" + }, + "type": { + "const": "image" + }, + "width": { + "description": "Render width in points.", + "maximum": 800, + "minimum": 10, + "type": "number" + } + }, + "required": [ + "type", + "imageBase64", + "mimeType" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Clickable external link (/URI action). Only http:, https: and mailto: URLs are accepted.", + "properties": { + "color": { + "anyOf": [ + { + "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } + ], + "description": "Hex colour (#RGB or #RRGGBB)." + }, + "fontSize": { + "description": "Default 10.", + "maximum": 48, + "minimum": 6, + "type": "number" + }, + "text": { + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "link" + }, + "url": { + "description": "http(s):// or mailto: URL.", + "maxLength": 2048, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "type", + "text", + "url" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Printed table of contents generated from the document's heading blocks (internal /GoTo links with dot leaders). Pairs with outline:'auto' for the bookmark pane.", + "properties": { + "fontSize": { + "description": "Default 10.", + "maximum": 24, + "minimum": 6, + "type": "number" + }, + "indent": { + "description": "Points of indent per heading level (default 15).", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxLevel": { + "description": "Deepest heading level listed (default 3).", + "enum": [ + 1, + 2, + 3 + ], + "type": "integer" + }, + "title": { + "description": "Default 'Table of Contents'.", + "maxLength": 200, + "type": "string" + }, + "type": { + "const": "toc" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Inline barcode — same body as add_barcode (pure vector, no /Alt available in the engine).", + "properties": { + "align": { + "default": "left", + "description": "Horizontal placement inside the content width.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + }, + "data": { + "description": "Raw payload to encode — do NOT URL-encode. For QR/URL pass e.g. \"https://example.com\" verbatim. EAN-13 must be 12 or 13 digits (13th is auto-computed). Code 128 accepts ASCII alphanumerics.", + "maxLength": 4296, + "minLength": 1, + "type": "string" + }, + "ecLevel": { + "default": "M", + "description": "QR ONLY. Error correction level (L=7%, M=15%, Q=25%, H=30%). Ignored for code128/ean13/datamatrix/pdf417. Use H for printed media that may get smudged or partially covered (e.g. logo overlay).", + "enum": [ + "L", + "M", + "Q", + "H" + ], + "type": "string" + }, + "format": { + "description": "Barcode symbology to render.", + "enum": [ + "qr", + "code128", + "ean13", + "datamatrix", + "pdf417" + ], + "type": "string" + }, + "height": { + "default": 200, + "description": "Barcode height in PDF points (ignored for square symbologies like QR/Data Matrix).", + "maximum": 500, + "minimum": 30, + "type": "number" + }, + "type": { + "const": "barcode" + }, + "width": { + "default": 200, + "description": "Barcode width in PDF points.", + "maximum": 500, + "minimum": 30, + "type": "number" + } + }, + "required": [ + "type", + "format", + "data" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Vector drawing from an SVG path `d` string or SVG markup. Supported: <path> <rect> (rx/ry) <circle> <ellipse> <line> <polyline> <polygon> and <text>/<tspan> (x, y, font-size, fill, text-anchor, dx/dy); fill / stroke / stroke-width attributes; double-quoted attributes only. NOT supported (silently ignored): transform, <g>, <use>, <image>, <defs>/<clipPath>, gradients, opacity, CSS/style, dash patterns, text word-wrap. No external reference is ever fetched (no XML parser: entities other than & < > " ' &#n; are dropped). Pure path operators — PDF/A-safe at every level.", + "properties": { + "align": { + "default": "left", + "description": "Horizontal placement inside the content width.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + }, + "alt": { + "description": "Accessible description (tagged /Figure /Alt). Always provide it for non-decorative content under PDF/A or PDF/UA.", + "maxLength": 500, + "type": "string" + }, + "data": { + "description": "Path `d` string or SVG markup (≤ 100 000 characters).", + "maxLength": 100000, + "minLength": 1, + "type": "string" + }, + "fill": { + "anyOf": [ + { + "pattern": "^(?:none|#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}))$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } + ], + "description": "Hex colour or 'none' (default black)." + }, + "height": { + "description": "Render height in points (default 200).", + "maximum": 1000, + "minimum": 10, + "type": "number" + }, + "stroke": { + "anyOf": [ + { + "pattern": "^(?:none|#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}))$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } + ], + "description": "Hex colour or 'none' (default none)." + }, + "strokeWidth": { + "description": "Stroke width in SVG user units (default 1).", + "maximum": 50, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "svg" + }, + "viewBox": { + "description": "[minX, minY, width, height] — overrides the viewBox of the markup; required for a bare path string that is not 0-based.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "width": { + "description": "Render width in points (default 200).", + "maximum": 800, + "minimum": 10, + "type": "number" + } + }, + "required": [ + "type", + "data" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Inline AcroForm field — same body as an add_form field. Under a PDF/A claim pass embedFonts:true so the field font is embedded too (PDFA_UNEMBEDDED_FORM_FONT otherwise; strict:true then fails the call).", + "properties": { + "checked": { + "description": "Initial checked state for checkbox / radio fields.", + "type": "boolean" + }, + "fieldType": { + "description": "Type of form control to render. Radio fields sharing a name form one radio group.", + "enum": [ + "text", + "textarea", + "checkbox", + "radio", + "dropdown", + "listbox" + ], + "type": "string" + }, + "fontSize": { + "description": "Font size for text rendering inside the field.", + "maximum": 48, + "minimum": 6, + "type": "number" + }, + "height": { + "description": "Field height in points (default depends on the type).", + "maximum": 300, + "minimum": 10, + "type": "number" + }, + "label": { + "description": "Human-readable label shown above the field.", + "maxLength": 200, + "type": "string" + }, + "maxLength": { + "description": "Maximum character length for text/textarea fields.", + "maximum": 32767, + "minimum": 1, + "type": "integer" + }, + "name": { + "description": "Unique field name used as the PDF annotation identifier (/T).", + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "options": { + "description": "Choices for dropdown, listbox or radio fields.", + "items": { + "maxLength": 200, + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "placeholder": { + "description": "Hint text shown while the field is empty.", + "maxLength": 200, + "type": "string" + }, + "readOnly": { + "description": "Prevent editing of this field.", + "type": "boolean" + }, + "required": { + "description": "Mark field as required.", + "type": "boolean" + }, + "type": { + "const": "formField" + }, + "value": { + "description": "Pre-filled value. The key is 'value' (there is no defaultValue).", + "maxLength": 2000, + "type": "string" + }, + "width": { + "description": "Field width in points (default: full content width).", + "maximum": 500, + "minimum": 10, + "type": "number" + } + }, + "required": [ + "type", + "fieldType", + "name" + ], + "type": "object" + } +] - changed
Input schema / properties / creationDate / descriptionPrevious value: -"ISO-8601 instant for /CreationDate (+ XMP). Pin it for byte-identical output across calls (same host TZ); omitted = wall clock, so every call differs."New value: +"ISO-8601 instant for /CreationDate (+ XMP, the trailer /ID and the {date} placeholder), written in UTC. Pin it for byte-identical output across calls and hosts; omitted = wall clock, so every call differs." - changed
Input schema / properties / embedFonts / descriptionPrevious value: -"Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A claim (ISO 19005 §6.2.11.4.1) and for strict=true; adds ~0.3 MiB."New value: +"Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A or PDF/X claim (every font embedded) and for strict=true; adds ~0.3 MiB." - changed
Input schema / properties / footerTemplate / properties / center / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - added
Input schema / properties / footerTemplate / properties / color / anyOfAdded value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - changed
Input schema / properties / footerTemplate / properties / color / descriptionPrevious value: -"Hex colour."New value: +"Hex colour (#RRGGBB)." - removed
Input schema / properties / footerTemplate / properties / color / patternRemoved value: -"^#[0-9a-fA-F]{6}$" - removed
Input schema / properties / footerTemplate / properties / color / typeRemoved value: -"string" - changed
Input schema / properties / footerTemplate / properties / left / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / footerTemplate / properties / right / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / headerTemplate / properties / center / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - added
Input schema / properties / headerTemplate / properties / color / anyOfAdded value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - changed
Input schema / properties / headerTemplate / properties / color / descriptionPrevious value: -"Hex colour."New value: +"Hex colour (#RRGGBB)." - removed
Input schema / properties / headerTemplate / properties / color / patternRemoved value: -"^#[0-9a-fA-F]{6}$" - removed
Input schema / properties / headerTemplate / properties / color / typeRemoved value: -"string" - changed
Input schema / properties / headerTemplate / properties / left / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / headerTemplate / properties / right / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / includeDiagnostics / descriptionPrevious value: -"Return the PDF/A diagnostics raised while building as `diagnostics[]` (possibly empty)."New value: +"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*) as `diagnostics[]` (possibly empty)." - changed
Input schema / properties / outline / oneOfPrevious value: -[ - { - "enum": [ - "auto" - ], - "type": "string" - }, - { - "items": { - "additionalProperties": false, - "properties": { - "bold": { - "type": "boolean" - }, - "children": { - "items": { - "additionalProperties": false, - "properties": { - "bold": { - "type": "boolean" - }, - "children": { - "items": { - "additionalProperties": false, - "properties": { - "bold": { - "type": "boolean" - }, - "children": { - "items": { - "additionalProperties": false, - "properties": { - "bold": { - "type": "boolean" - }, - "children": { - "items": { - "additionalProperties": false, - "properties": { - "bold": { - "type": "boolean" - }, - "children": { - "items": { - "additionalProperties": false, - "properties": { - "bold": { - "type": "boolean" - }, - "color": { - "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1').", - "type": "string" - }, - "italic": { - "type": "boolean" - }, - "open": { - "description": "Initial expansion state (default true). false renders the branch collapsed.", - "type": "boolean" - }, - "pageIndex": { - "description": "0-based destination page index.", - "minimum": 0, - "type": "integer" - }, - "title": { - "description": "Bookmark label.", - "maxLength": 500, - "minLength": 1, - "type": "string" - }, - "y": { - "description": "Destination Y coordinate in points (default: top of page).", - "type": "number" - } - }, - "required": [ - "title", - "pageIndex" - ], - "type": "object" - }, - "maxItems": 1000, - "type": "array" - }, - "color": { - "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1').", - "type": "string" - }, - "italic": { - "type": "boolean" - }, - "open": { - "description": "Initial expansion state (default true). false renders the branch collapsed.", - "type": "boolean" - }, - "pageIndex": { - "description": "0-based destination page index.", - "minimum": 0, - "type": "integer" - }, - "title": { - "description": "Bookmark label.", - "maxLength": 500, - "minLength": 1, - "type": "string" - }, - "y": { - "description": "Destination Y coordinate in points (default: top of page).", - "type": "number" - } - }, - "required": [ - "title", - "pageIndex" - ], - "type": "object" - }, - "maxItems": 1000, - "type": "array" - }, - "color": { - "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1').", - "type": "string" - }, - "italic": { - "type": "boolean" - }, - "open": { - "description": "Initial expansion state (default true). false renders the branch collapsed.", - "type": "boolean" - }, - "pageIndex": { - "description": "0-based destination page index.", - "minimum": 0, - "type": "integer" - }, - "title": { - "description": "Bookmark label.", - "maxLength": 500, - "minLength": 1, - "type": "string" - }, - "y": { - "description": "Destination Y coordinate in points (default: top of page).", - "type": "number" - } - }, - "required": [ - "title", - "pageIndex" - ], - "type": "object" - }, - "maxItems": 1000, - "type": "array" - }, - "color": { - "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1').", - "type": "string" - }, - "italic": { - "type": "boolean" - }, - "open": { - "description": "Initial expansion state (default true). false renders the branch collapsed.", - "type": "boolean" - }, - "pageIndex": { - "description": "0-based destination page index.", - "minimum": 0, - "type": "integer" - }, - "title": { - "description": "Bookmark label.", - "maxLength": 500, - "minLength": 1, - "type": "string" - }, - "y": { - "description": "Destination Y coordinate in points (default: top of page).", - "type": "number" - } - }, - "required": [ - "title", - "pageIndex" - ], - "type": "object" - }, - "maxItems": 1000, - "type": "array" - }, - "color": { - "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1').", - "type": "string" - }, - "italic": { - "type": "boolean" - }, - "open": { - "description": "Initial expansion state (default true). false renders the branch collapsed.", - "type": "boolean" - }, - "pageIndex": { - "description": "0-based destination page index.", - "minimum": 0, - "type": "integer" - }, - "title": { - "description": "Bookmark label.", - "maxLength": 500, - "minLength": 1, - "type": "string" - }, - "y": { - "description": "Destination Y coordinate in points (default: top of page).", - "type": "number" - } - }, - "required": [ - "title", - "pageIndex" - ], - "type": "object" - }, - "maxItems": 1000, - "type": "array" - }, - "color": { - "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1').", - "type": "string" - }, - "italic": { - "type": "boolean" - }, - "open": { - "description": "Initial expansion state (default true). false renders the branch collapsed.", - "type": "boolean" - }, - "pageIndex": { - "description": "0-based destination page index.", - "minimum": 0, - "type": "integer" - }, - "title": { - "description": "Bookmark label.", - "maxLength": 500, - "minLength": 1, - "type": "string" - }, - "y": { - "description": "Destination Y coordinate in points (default: top of page).", - "type": "number" - } - }, - "required": [ - "title", - "pageIndex" - ], - "type": "object" - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - } -]New value: +[ + { + "enum": [ + "auto" + ], + "type": "string" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "bold": { + "type": "boolean" + }, + "children": { + "items": { + "additionalProperties": false, + "properties": { + "bold": { + "type": "boolean" + }, + "children": { + "items": { + "additionalProperties": false, + "properties": { + "bold": { + "type": "boolean" + }, + "children": { + "items": { + "additionalProperties": false, + "properties": { + "bold": { + "type": "boolean" + }, + "children": { + "items": { + "additionalProperties": false, + "properties": { + "bold": { + "type": "boolean" + }, + "children": { + "items": { + "additionalProperties": false, + "properties": { + "bold": { + "type": "boolean" + }, + "color": { + "anyOf": [ + { + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } + ], + "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1'). An outline label is RGB by definition (/C): a CMYK value is converted for on-screen display." + }, + "italic": { + "type": "boolean" + }, + "open": { + "description": "Initial expansion state (default true). false renders the branch collapsed.", + "type": "boolean" + }, + "pageIndex": { + "description": "0-based destination page index.", + "minimum": 0, + "type": "integer" + }, + "title": { + "description": "Bookmark label.", + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "y": { + "description": "Destination Y coordinate in points (default: top of page).", + "type": "number" + } + }, + "required": [ + "title", + "pageIndex" + ], + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "color": { + "anyOf": [ + { + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } + ], + "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1'). An outline label is RGB by definition (/C): a CMYK value is converted for on-screen display." + }, + "italic": { + "type": "boolean" + }, + "open": { + "description": "Initial expansion state (default true). false renders the branch collapsed.", + "type": "boolean" + }, + "pageIndex": { + "description": "0-based destination page index.", + "minimum": 0, + "type": "integer" + }, + "title": { + "description": "Bookmark label.", + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "y": { + "description": "Destination Y coordinate in points (default: top of page).", + "type": "number" + } + }, + "required": [ + "title", + "pageIndex" + ], + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "color": { + "anyOf": [ + { + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } + ], + "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1'). An outline label is RGB by definition (/C): a CMYK value is converted for on-screen display." + }, + "italic": { + "type": "boolean" + }, + "open": { + "description": "Initial expansion state (default true). false renders the branch collapsed.", + "type": "boolean" + }, + "pageIndex": { + "description": "0-based destination page index.", + "minimum": 0, + "type": "integer" + }, + "title": { + "description": "Bookmark label.", + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "y": { + "description": "Destination Y coordinate in points (default: top of page).", + "type": "number" + } + }, + "required": [ + "title", + "pageIndex" + ], + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "color": { + "anyOf": [ + { + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } + ], + "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1'). An outline label is RGB by definition (/C): a CMYK value is converted for on-screen display." + }, + "italic": { + "type": "boolean" + }, + "open": { + "description": "Initial expansion state (default true). false renders the branch collapsed.", + "type": "boolean" + }, + "pageIndex": { + "description": "0-based destination page index.", + "minimum": 0, + "type": "integer" + }, + "title": { + "description": "Bookmark label.", + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "y": { + "description": "Destination Y coordinate in points (default: top of page).", + "type": "number" + } + }, + "required": [ + "title", + "pageIndex" + ], + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "color": { + "anyOf": [ + { + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } + ], + "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1'). An outline label is RGB by definition (/C): a CMYK value is converted for on-screen display." + }, + "italic": { + "type": "boolean" + }, + "open": { + "description": "Initial expansion state (default true). false renders the branch collapsed.", + "type": "boolean" + }, + "pageIndex": { + "description": "0-based destination page index.", + "minimum": 0, + "type": "integer" + }, + "title": { + "description": "Bookmark label.", + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "y": { + "description": "Destination Y coordinate in points (default: top of page).", + "type": "number" + } + }, + "required": [ + "title", + "pageIndex" + ], + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "color": { + "anyOf": [ + { + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } + ], + "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1'). An outline label is RGB by definition (/C): a CMYK value is converted for on-screen display." + }, + "italic": { + "type": "boolean" + }, + "open": { + "description": "Initial expansion state (default true). false renders the branch collapsed.", + "type": "boolean" + }, + "pageIndex": { + "description": "0-based destination page index.", + "minimum": 0, + "type": "integer" + }, + "title": { + "description": "Bookmark label.", + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "y": { + "description": "Destination Y coordinate in points (default: top of page).", + "type": "number" + } + }, + "required": [ + "title", + "pageIndex" + ], + "type": "object" + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + } +] - changed
Input schema / properties / outputIntent / descriptionPrevious value: -"Custom PDF/A OutputIntent: an RGB ICC profile + condition strings replacing the built-in sRGB intent (CMYK rejected)."New value: +"Custom OutputIntent (under pdfA or pdfx): an RGB, CMYK or Gray ICC profile + condition strings, replacing the built-in sRGB intent. The profile must be a real ICC file ('acsp' signature, consistent size — PRINT_ERROR otherwise); pdfx needs device class 'prtr'. Under a CMYK / Gray intent RGB content is mapped through a calibrated default space." - changed
Input schema / properties / outputIntent / properties / iccProfileBase64 / descriptionPrevious value: -"ICC profile bytes, base64 (RGB, ≤ 8 MiB)."New value: +"ICC profile bytes, base64 (RGB, CMYK or Gray; ≤ 8 MiB)." - added
Input schema / properties / pdfxAdded value: +{ + "description": "PDF/X-4 print exchange (ISO 15930-7). REQUIRES outputIntent with the printer's ICC profile (device class 'prtr'; CMYK or Gray — none is bundled); needs embedFonts:true for a conformant file (PDFX_NO_FONT_ENTRIES otherwise, strict:true refuses). Exclusive with pdfA and encrypt; metadata.trapped must be 'True' or 'False'; TrimBox or ArtBox, not both. Links and form fields are reported (PDFX_ANNOTATIONS). Check with validate_pdf standard:'pdf-x-4'. See the print_ready prompt.", + "enum": [ + "pdfx4" + ], + "type": "string" +} - changed
Input schema / properties / print / properties / marks / oneOfPrevious value: -[ - { - "type": "boolean" - }, - { - "additionalProperties": false, - "properties": { - "crop": { - "description": "Corner crop (trim) marks. Default true.", - "type": "boolean" - }, - "length": { - "description": "Mark length in points. Default 14.", - "maximum": 100, - "minimum": 1, - "type": "number" - }, - "offset": { - "description": "Gap between TrimBox and marks in points. Default 5.", - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "registration": { - "description": "Edge-midpoint registration targets. Default true.", - "type": "boolean" - }, - "weight": { - "description": "Stroke width in points. Default 0.25.", - "maximum": 5, - "minimum": 0.05, - "type": "number" - } - }, - "type": "object" - } -]New value: +[ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "colourBars": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "size": { + "description": "Patch size in points. Default 12.", + "maximum": 72, + "minimum": 4, + "type": "number" + }, + "tints": { + "description": "Add the four 50 % tint patches. Default true.", + "type": "boolean" + } + }, + "type": "object" + } + ], + "description": "Colour control strip in the bleed (C M Y K solids + their 50 % tints): true for defaults. Off by default; needs a bleed of about 5 mm (14.17 pt) and is skipped when the strip would not fit." + }, + "crop": { + "description": "Corner crop (trim) marks. Default true.", + "type": "boolean" + }, + "length": { + "description": "Mark length in points. Default 14.", + "maximum": 100, + "minimum": 1, + "type": "number" + }, + "offset": { + "description": "Gap between TrimBox and marks in points. Default 5.", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "registration": { + "description": "Edge-midpoint registration targets. Default true.", + "type": "boolean" + }, + "weight": { + "description": "Stroke width in points. Default 0.25.", + "maximum": 5, + "minimum": 0.05, + "type": "number" + } + }, + "type": "object" + } +] - changed
Input schema / properties / strict / descriptionPrevious value: -"Fail with PDF_A_COMPLIANCE_VIOLATION instead of producing a non-conformant PDF/A file (e.g. PDFA_NO_FONT_ENTRIES without embedFonts). Pair with embedFonts=true."New value: +"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true." - added
Input schema / properties / typographyAdded value: +{ + "additionalProperties": false, + "description": "Fine typography, all opt-in (omitted = unchanged bytes). kerning, fontFeatures and the 'fr' narrow space need embedFonts:true. No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt.", + "properties": { + "bindShortWords": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "maxLength": { + "maximum": 3, + "minimum": 1, + "type": "integer" + }, + "words": { + "items": { + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + ], + "description": "Never end a line on a short word: up to maxLength letters (default 1), or exactly the listed words." + }, + "fontFeatures": { + "description": "OpenType features, later wins. tnum / lnum are no-ops on Noto Sans (TYPOGRAPHY_FEATURE_INEFFECTIVE).", + "items": { + "enum": [ + "tnum", + "pnum", + "lnum", + "onum", + "zero", + "ordn", + "sups", + "subs", + "smcp", + "c2sc", + "case" + ], + "type": "string" + }, + "maxItems": 11, + "type": "array", + "uniqueItems": true + }, + "hyphenationLanguage": { + "description": "BCP 47 tag; no effect here (no hyphenation provider installed).", + "maxLength": 35, + "pattern": "^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$", + "type": "string" + }, + "keepHeadingsWithNext": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "minLines": { + "maximum": 10, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + } + ], + "description": "Never strand a heading at a page foot. true = { minLines: 2 }." + }, + "kerning": { + "description": "Pair kerning (GPOS).", + "type": "boolean" + }, + "metrics": { + "description": "Base-14 text: 'exact' uses the AFM widths (different wraps). Default 'approximate'.", + "enum": [ + "approximate", + "exact" + ], + "type": "string" + }, + "opticalMargins": { + "description": "Hang punctuation into the margin of align:'justify' text.", + "type": "boolean" + }, + "orphans": { + "description": "Min lines left at a page foot (default 2; needs splitParagraphs).", + "maximum": 10, + "minimum": 1, + "type": "integer" + }, + "punctuationSpacing": { + "anyOf": [ + { + "enum": [ + "fr", + "fr-CA" + ], + "type": "string" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "char": { + "maxLength": 2, + "minLength": 1, + "type": "string" + }, + "side": { + "enum": [ + "before", + "after" + ], + "type": "string" + }, + "space": { + "description": "U+00A0 / U+202F (narrow needs embedFonts).", + "enum": [ + "nbsp", + "narrow" + ], + "type": "string" + } + }, + "required": [ + "char", + "side", + "space" + ], + "type": "object" + }, + "maxItems": 32, + "type": "array" + } + ], + "description": "No-break spaces next to punctuation (existing spaces only). 'fr': narrow before ; ! ?, no-break before ':' and inside « ». 'fr-CA': ':' and « » only. Or explicit rules." + }, + "splitParagraphs": { + "description": "Paragraphs may break across pages at a line boundary (default: atomic).", + "type": "boolean" + }, + "unitBinding": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "units": { + "items": { + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + ], + "description": "No-break space between a number and its unit ('150 €', '12 kg'); units replaces the built-in list." + }, + "widows": { + "description": "Min lines carried over (default 2; needs splitParagraphs).", + "maximum": 10, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" +} - added
Input schema / properties / watermark / properties / color / anyOfAdded value: +[ + { + "items": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - changed
Input schema / properties / watermark / properties / color / descriptionPrevious value: -"Text RGB colour as a [r, g, b] triple in the 0.0–1.0 range. Default light gray [0.75, 0.75, 0.75]."New value: +"Text colour. RGB as a [r, g, b] triple in the 0.0–1.0 range; default light gray [0.75, 0.75, 0.75]." - removed
Input schema / properties / watermark / properties / color / itemsRemoved value: -{ - "maximum": 1, - "minimum": 0, - "type": "number" -} - removed
Input schema / properties / watermark / properties / color / maxItemsRemoved value: -3 - removed
Input schema / properties / watermark / properties / color / minItemsRemoved value: -3 - removed
Input schema / properties / watermark / properties / color / typeRemoved value: -"array" - changed
Output schema / properties / diagnostics / descriptionPrevious value: -"PDF/A diagnostics (when includeDiagnostics=true)."New value: +"Engine diagnostics (when includeDiagnostics=true)."
- Changed
inspect_layout17 fields changed- changed
Input schema / properties / blocks / items / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "level": { - "enum": [ - 1, - 2, - 3 - ], - "type": "integer" - }, - "text": { - "maxLength": 500, - "minLength": 1, - "type": "string" - }, - "type": { - "const": "heading" - } - }, - "required": [ - "type", - "text", - "level" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "text": { - "description": "Paragraph text. Embedded newlines ('\\n') are automatically split into separate paragraphs — no need to pre-split; never emit a literal newline expecting a soft line break.", - "maxLength": 50000, - "minLength": 1, - "type": "string" - }, - "type": { - "const": "paragraph" - } - }, - "required": [ - "type", - "text" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "description": "List items. A string is a leaf; an object { text, items } nests a sub-list (bullets/numbers indent; numbered sub-lists restart at 1).", - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "style": { - "default": "bullet", - "enum": [ - "bullet", - "numbered" - ], - "type": "string" - }, - "type": { - "const": "list" - } - }, - "required": [ - "type", - "items" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "type": { - "const": "pageBreak" - } - }, - "required": [ - "type" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "height": { - "maximum": 500, - "minimum": 1, - "type": "number" - }, - "type": { - "const": "spacer" - } - }, - "required": [ - "type", - "height" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Native vector chart rendered as pure PDF path operators — bar / horizontal-bar / stacked-bar / line / area / scatter / pie / donut (pdfnative 1.7 charts v2: time and log axes, data labels, secondary axis, legends). Same body as add_chart.", - "properties": { - "align": { - "description": "Horizontal alignment within the content width. Default 'left'.", - "enum": [ - "left", - "center", - "right" - ], - "type": "string" - }, - "altText": { - "description": "Alt text for the tagged-PDF /Figure /Alt. Auto-generated when omitted.", - "maxLength": 500, - "type": "string" - }, - "axis": { - "additionalProperties": false, - "description": "Value-axis options (bar/line only).", - "properties": { - "grid": { - "description": "Draw horizontal gridlines.", - "type": "boolean" - }, - "scale": { - "description": "Value-axis scale. 'log' requires strictly positive values and is not available for stacked charts.", - "enum": [ - "linear", - "log" - ], - "type": "string" - }, - "ticks": { - "description": "Target tick count (nice 1/2/5×10ⁿ steps).", - "maximum": 20, - "minimum": 2, - "type": "integer" - }, - "yMax": { - "description": "Force the axis maximum (values are clamped to the plot band).", - "type": "number" - }, - "yMin": { - "description": "Force the axis minimum (values are clamped to the plot band).", - "type": "number" - } - }, - "type": "object" - }, - "axis2": { - "additionalProperties": false, - "description": "Secondary RIGHT value axis (drawn only when a series sets yAxis:'right').", - "properties": { - "scale": { - "enum": [ - "linear", - "log" - ], - "type": "string" - }, - "ticks": { - "maximum": 20, - "minimum": 2, - "type": "integer" - }, - "yMax": { - "type": "number" - }, - "yMin": { - "type": "number" - } - }, - "type": "object" - }, - "categories": { - "description": "Category / slice labels (x-axis). Defaults to 1-based indices when omitted.", - "items": { - "maxLength": 200, - "type": "string" - }, - "maxItems": 1000, - "type": "array" - }, - "chartType": { - "description": "Chart kind. 'pie'/'donut' use exactly one series; 'bar'/'barH'/'stackedBar'/'stackedBarH'/'line'/'area'/'scatter' support multiple series. 'scatter' requires xValues on every series and a positional xAxis.type ('linear' or 'time').", - "enum": [ - "bar", - "barH", - "stackedBar", - "stackedBarH", - "line", - "area", - "scatter", - "pie", - "donut" - ], - "type": "string" - }, - "colors": { - "description": "Palette override (per-series for bar/line, per-slice for pie/donut).", - "items": { - "description": "CSS-style hex colour, e.g. \"#3366cc\".", - "pattern": "^#?[0-9a-fA-F]{6}$", - "type": "string" - }, - "maxItems": 50, - "type": "array" - }, - "dataLabels": { - "description": "Per-point value labels: true for defaults, or an object to format them.", - "oneOf": [ - { - "type": "boolean" - }, - { - "additionalProperties": false, - "properties": { - "decimals": { - "maximum": 6, - "minimum": 0, - "type": "integer" - }, - "prefix": { - "maxLength": 16, - "type": "string" - }, - "suffix": { - "maxLength": 16, - "type": "string" - } - }, - "type": "object" - } - ] - }, - "height": { - "description": "Plot-area height in points. Default 240.", - "maximum": 2000, - "minimum": 50, - "type": "number" - }, - "labelRotation": { - "description": "Rotate category labels counter-clockwise by this many degrees (disables the automatic stride).", - "maximum": 90, - "minimum": 0, - "type": "number" - }, - "labelStride": { - "description": "Draw every Nth category label. Default: automatic (measured non-overlap); 1 draws every label.", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "legend": { - "description": "Legend placement. Defaults to 'bottom' for multi-series/pie, else 'none'.", - "enum": [ - "bottom", - "none" - ], - "type": "string" - }, - "markers": { - "description": "Draw point markers on line series. Default false.", - "type": "boolean" - }, - "series": { - "description": "Data series. Pie/donut charts use exactly one series (each value becomes a slice).", - "items": { - "additionalProperties": false, - "properties": { - "color": { - "description": "CSS-style hex colour, e.g. \"#3366cc\".", - "pattern": "^#?[0-9a-fA-F]{6}$", - "type": "string" - }, - "label": { - "description": "Series label (shown in the legend).", - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "values": { - "description": "Numeric values, one per category. Negative values are supported for bar/line.", - "items": { - "type": "number" - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "xValues": { - "description": "Per-point x positions (same length as values) for scatter charts and for line/area charts with xAxis.type 'linear' or 'time'.", - "items": { - "description": "Positional x value: a number (linear axis) or an ISO-8601 date / epoch milliseconds (time axis).", - "maxLength": 64, - "type": [ - "number", - "string" - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "yAxis": { - "description": "Bind the series to the left (default) or the secondary right value axis (cartesian charts only; configure its range with 'axis2').", - "enum": [ - "left", - "right" - ], - "type": "string" - } - }, - "required": [ - "label", - "values" - ], - "type": "object" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "title": { - "description": "Chart title rendered above the plot.", - "maxLength": 200, - "type": "string" - }, - "type": { - "const": "chart" - }, - "width": { - "description": "Plot width in points (clamped to content width). Default 460.", - "maximum": 2000, - "minimum": 50, - "type": "number" - }, - "xAxis": { - "additionalProperties": false, - "description": "Horizontal axis. 'category' (default) positions points by index; 'linear' / 'time' position them by series xValues (line/area/scatter only). Time ticks are UTC-deterministic.", - "properties": { - "grid": { - "description": "Draw vertical gridlines.", - "type": "boolean" - }, - "max": { - "description": "Axis maximum (number, or ISO-8601 / epoch ms for time axes).", - "maxLength": 64, - "type": [ - "number", - "string" - ] - }, - "min": { - "description": "Axis minimum (number, or ISO-8601 / epoch ms for time axes).", - "maxLength": 64, - "type": [ - "number", - "string" - ] - }, - "ticks": { - "maximum": 20, - "minimum": 2, - "type": "integer" - }, - "type": { - "enum": [ - "category", - "linear", - "time" - ], - "type": "string" - } - }, - "type": "object" - } - }, - "required": [ - "type", - "chartType", - "series" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Inline smart table — same body as add_table (every row must have exactly as many cells as headers).", - "properties": { - "autoFitColumns": { - "description": "Auto-fit column widths to content. Output bytes then depend on text metrics (not byte-deterministic across content changes).", - "type": "boolean" - }, - "caption": { - "description": "Caption rendered above the table (tagged as /Caption under PDF/A).", - "maxLength": 200, - "type": "string" - }, - "cellBorders": { - "additionalProperties": false, - "description": "Per-cell vector borders (pure strokes, PDF/A-safe). Choose individual sides or `all`.", - "properties": { - "all": { - "description": "Draw all four edges (overrides the individual side flags).", - "type": "boolean" - }, - "bottom": { - "type": "boolean" - }, - "color": { - "description": "Stroke colour as a PDF operator string ('0.8 0.8 0.8') or hex. Default light grey.", - "type": "string" - }, - "left": { - "type": "boolean" - }, - "right": { - "type": "boolean" - }, - "style": { - "description": "Stroke style (default 'solid').", - "enum": [ - "solid", - "dashed", - "dotted" - ], - "type": "string" - }, - "top": { - "type": "boolean" - }, - "width": { - "description": "Stroke width in points (default 0.5).", - "maximum": 10, - "minimum": 0, - "type": "number" - } - }, - "type": "object" - }, - "cellPadding": { - "description": "Horizontal cell padding in points (default 3).", - "maximum": 50, - "minimum": 0, - "type": "number" - }, - "cellVAlign": { - "description": "Vertical alignment of cell content.", - "enum": [ - "top", - "middle", - "bottom" - ], - "type": "string" - }, - "clipCells": { - "description": "Clip cell contents to the column bounds (PDF clip operators). Recommended for PDF/A and visual safety.", - "type": "boolean" - }, - "headers": { - "description": "Column header labels. Must have the same length as each row in `rows`.", - "items": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "minRowHeight": { - "description": "Minimum row height in points (default 12).", - "maximum": 200, - "minimum": 1, - "type": "number" - }, - "repeatHeader": { - "description": "Repeat the header row on every continuation page (default true).", - "type": "boolean" - }, - "rows": { - "description": "Data rows. Each row is an array of cell strings with the same length as `headers`.", - "items": { - "items": { - "maxLength": 500, - "type": "string" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "maxItems": 5000, - "minItems": 1, - "type": "array" - }, - "type": { - "const": "table" - }, - "wrap": { - "description": "Cell wrap policy: 'auto' (default) wraps only overflowing cells; 'always' wraps every cell; 'never' truncates.", - "enum": [ - "auto", - "always", - "never" - ], - "type": "string" - }, - "zebra": { - "description": "Alternate-row light tint (static fill, PDF/A-1b safe).", - "type": "boolean" - } - }, - "required": [ - "type", - "headers", - "rows" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Inline JPEG/PNG image. Without width/height the pixel size is used as points and clamped to the content width; with one dimension the aspect ratio is kept. The decoded bytes of all image blocks in one call are capped at 24 MiB (a watermark image has its own 8 MiB cap).", - "properties": { - "align": { - "default": "left", - "description": "Horizontal placement inside the content width.", - "enum": [ - "left", - "center", - "right" - ], - "type": "string" - }, - "alt": { - "description": "Accessible description (tagged /Figure /Alt). Always provide it for non-decorative content under PDF/A or PDF/UA.", - "maxLength": 500, - "type": "string" - }, - "height": { - "description": "Render height in points.", - "maximum": 1000, - "minimum": 10, - "type": "number" - }, - "imageBase64": { - "description": "Base64 image bytes. JPEG (baseline; 1, 3 or 4 components — CMYK raises PDFA_DEVICE_CMYK_IMAGE under PDF/A) or PNG (8-bit greyscale/RGB, non-interlaced; alpha-channel and palette PNGs are rejected with a remedy). No data: URI.", - "maxLength": 12000000, - "minLength": 4, - "type": "string" - }, - "mimeType": { - "description": "MIME type of the image. Must match the actual encoding of imageBase64 (magic bytes are checked).", - "enum": [ - "image/jpeg", - "image/png" - ], - "type": "string" - }, - "type": { - "const": "image" - }, - "width": { - "description": "Render width in points.", - "maximum": 800, - "minimum": 10, - "type": "number" - } - }, - "required": [ - "type", - "imageBase64", - "mimeType" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Clickable external link (/URI action). Only http:, https: and mailto: URLs are accepted.", - "properties": { - "color": { - "description": "Hex colour (#RGB or #RRGGBB).", - "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$", - "type": "string" - }, - "fontSize": { - "description": "Default 10.", - "maximum": 48, - "minimum": 6, - "type": "number" - }, - "text": { - "maxLength": 500, - "minLength": 1, - "type": "string" - }, - "type": { - "const": "link" - }, - "url": { - "description": "http(s):// or mailto: URL.", - "maxLength": 2048, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "type", - "text", - "url" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Printed table of contents generated from the document's heading blocks (internal /GoTo links with dot leaders). Pairs with outline:'auto' for the bookmark pane.", - "properties": { - "fontSize": { - "description": "Default 10.", - "maximum": 24, - "minimum": 6, - "type": "number" - }, - "indent": { - "description": "Points of indent per heading level (default 15).", - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "maxLevel": { - "description": "Deepest heading level listed (default 3).", - "enum": [ - 1, - 2, - 3 - ], - "type": "integer" - }, - "title": { - "description": "Default 'Table of Contents'.", - "maxLength": 200, - "type": "string" - }, - "type": { - "const": "toc" - } - }, - "required": [ - "type" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Inline barcode — same body as add_barcode (pure vector, no /Alt available in the engine).", - "properties": { - "align": { - "default": "left", - "description": "Horizontal placement inside the content width.", - "enum": [ - "left", - "center", - "right" - ], - "type": "string" - }, - "data": { - "description": "Raw payload to encode — do NOT URL-encode. For QR/URL pass e.g. \"https://example.com\" verbatim. EAN-13 must be 12 or 13 digits (13th is auto-computed). Code 128 accepts ASCII alphanumerics.", - "maxLength": 4296, - "minLength": 1, - "type": "string" - }, - "ecLevel": { - "default": "M", - "description": "QR ONLY. Error correction level (L=7%, M=15%, Q=25%, H=30%). Ignored for code128/ean13/datamatrix/pdf417. Use H for printed media that may get smudged or partially covered (e.g. logo overlay).", - "enum": [ - "L", - "M", - "Q", - "H" - ], - "type": "string" - }, - "format": { - "description": "Barcode symbology to render.", - "enum": [ - "qr", - "code128", - "ean13", - "datamatrix", - "pdf417" - ], - "type": "string" - }, - "height": { - "default": 200, - "description": "Barcode height in PDF points (ignored for square symbologies like QR/Data Matrix).", - "maximum": 500, - "minimum": 30, - "type": "number" - }, - "type": { - "const": "barcode" - }, - "width": { - "default": 200, - "description": "Barcode width in PDF points.", - "maximum": 500, - "minimum": 30, - "type": "number" - } - }, - "required": [ - "type", - "format", - "data" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Vector drawing from an SVG path `d` string or SVG markup. Supported: <path> <rect> (rx/ry) <circle> <ellipse> <line> <polyline> <polygon> and <text>/<tspan> (x, y, font-size, fill, text-anchor, dx/dy); fill / stroke / stroke-width attributes; double-quoted attributes only. NOT supported (silently ignored): transform, <g>, <use>, <image>, <defs>/<clipPath>, gradients, opacity, CSS/style, dash patterns, text word-wrap. No external reference is ever fetched (no XML parser: entities other than & < > " ' &#n; are dropped). Pure path operators — PDF/A-safe at every level.", - "properties": { - "align": { - "default": "left", - "description": "Horizontal placement inside the content width.", - "enum": [ - "left", - "center", - "right" - ], - "type": "string" - }, - "alt": { - "description": "Accessible description (tagged /Figure /Alt). Always provide it for non-decorative content under PDF/A or PDF/UA.", - "maxLength": 500, - "type": "string" - }, - "data": { - "description": "Path `d` string or SVG markup (≤ 100 000 characters).", - "maxLength": 100000, - "minLength": 1, - "type": "string" - }, - "fill": { - "description": "Hex colour or 'none' (default black).", - "pattern": "^(?:none|#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}))$", - "type": "string" - }, - "height": { - "description": "Render height in points (default 200).", - "maximum": 1000, - "minimum": 10, - "type": "number" - }, - "stroke": { - "description": "Hex colour or 'none' (default none).", - "pattern": "^(?:none|#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}))$", - "type": "string" - }, - "strokeWidth": { - "description": "Stroke width in SVG user units (default 1).", - "maximum": 50, - "minimum": 0, - "type": "number" - }, - "type": { - "const": "svg" - }, - "viewBox": { - "description": "[minX, minY, width, height] — overrides the viewBox of the markup; required for a bare path string that is not 0-based.", - "items": { - "type": "number" - }, - "maxItems": 4, - "minItems": 4, - "type": "array" - }, - "width": { - "description": "Render width in points (default 200).", - "maximum": 800, - "minimum": 10, - "type": "number" - } - }, - "required": [ - "type", - "data" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Inline AcroForm field — same body as an add_form field. Under a PDF/A claim the widget appearance font is not embedded (PDFA_UNEMBEDDED_FORM_FONT; strict:true fails the call).", - "properties": { - "checked": { - "description": "Initial checked state for checkbox / radio fields.", - "type": "boolean" - }, - "fieldType": { - "description": "Type of form control to render. Radio fields sharing a name form one radio group.", - "enum": [ - "text", - "textarea", - "checkbox", - "radio", - "dropdown", - "listbox" - ], - "type": "string" - }, - "fontSize": { - "description": "Font size for text rendering inside the field.", - "maximum": 48, - "minimum": 6, - "type": "number" - }, - "height": { - "description": "Field height in points (default depends on the type).", - "maximum": 300, - "minimum": 10, - "type": "number" - }, - "label": { - "description": "Human-readable label shown above the field.", - "maxLength": 200, - "type": "string" - }, - "maxLength": { - "description": "Maximum character length for text/textarea fields.", - "maximum": 32767, - "minimum": 1, - "type": "integer" - }, - "name": { - "description": "Unique field name used as the PDF annotation identifier (/T).", - "maxLength": 100, - "minLength": 1, - "type": "string" - }, - "options": { - "description": "Choices for dropdown, listbox or radio fields.", - "items": { - "maxLength": 200, - "type": "string" - }, - "maxItems": 100, - "type": "array" - }, - "placeholder": { - "description": "Hint text shown while the field is empty.", - "maxLength": 200, - "type": "string" - }, - "readOnly": { - "description": "Prevent editing of this field.", - "type": "boolean" - }, - "required": { - "description": "Mark field as required.", - "type": "boolean" - }, - "type": { - "const": "formField" - }, - "value": { - "description": "Default value pre-filled in the field.", - "maxLength": 2000, - "type": "string" - }, - "width": { - "description": "Field width in points (default: full content width).", - "maximum": 500, - "minimum": 10, - "type": "number" - } - }, - "required": [ - "type", - "fieldType", - "name" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "keepWithNext": { + "description": "Keep this heading on the same page as the block that follows. Overrides typography.keepHeadingsWithNext for this block, either way.", + "type": "boolean" + }, + "level": { + "enum": [ + 1, + 2, + 3 + ], + "type": "integer" + }, + "text": { + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "heading" + } + }, + "required": [ + "type", + "text", + "level" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "align": { + "description": "Text alignment (default left). 'justify' spans every line but the last across the measure; pair it with typography.opticalMargins.", + "enum": [ + "left", + "right", + "center", + "justify" + ], + "type": "string" + }, + "keepWithNext": { + "description": "Keep this paragraph on the same page as the block that follows (a lead-in line before a table or figure). Default false.", + "type": "boolean" + }, + "splittable": { + "description": "Allow / forbid this paragraph breaking across pages, overriding typography.splitParagraphs for this block.", + "type": "boolean" + }, + "text": { + "description": "Paragraph text. Embedded newlines ('\\n') are automatically split into separate paragraphs — no need to pre-split; never emit a literal newline expecting a soft line break.", + "maxLength": 50000, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "paragraph" + } + }, + "required": [ + "type", + "text" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "description": "List items. A string is a leaf; an object { text, items } nests a sub-list (bullets/numbers indent; numbered sub-lists restart at 1).", + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "style": { + "default": "bullet", + "enum": [ + "bullet", + "numbered" + ], + "type": "string" + }, + "type": { + "const": "list" + } + }, + "required": [ + "type", + "items" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "type": { + "const": "pageBreak" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "height": { + "maximum": 500, + "minimum": 1, + "type": "number" + }, + "type": { + "const": "spacer" + } + }, + "required": [ + "type", + "height" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Native vector chart rendered as pure PDF path operators — bar / horizontal-bar / stacked-bar / line / area / scatter / pie / donut (pdfnative 1.7 charts v2: time and log axes, data labels, secondary axis, legends). Same body as add_chart.", + "properties": { + "align": { + "description": "Horizontal alignment within the content width. Default 'left'.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + }, + "altText": { + "description": "Alt text for the tagged-PDF /Figure /Alt. Auto-generated when omitted.", + "maxLength": 500, + "type": "string" + }, + "axis": { + "additionalProperties": false, + "description": "Value-axis options (bar/line only).", + "properties": { + "grid": { + "description": "Draw horizontal gridlines.", + "type": "boolean" + }, + "scale": { + "description": "Value-axis scale. 'log' requires strictly positive values and is not available for stacked charts.", + "enum": [ + "linear", + "log" + ], + "type": "string" + }, + "ticks": { + "description": "Target tick count (nice 1/2/5×10ⁿ steps).", + "maximum": 20, + "minimum": 2, + "type": "integer" + }, + "yMax": { + "description": "Force the axis maximum (values are clamped to the plot band).", + "type": "number" + }, + "yMin": { + "description": "Force the axis minimum (values are clamped to the plot band).", + "type": "number" + } + }, + "type": "object" + }, + "axis2": { + "additionalProperties": false, + "description": "Secondary RIGHT value axis (drawn only when a series sets yAxis:'right').", + "properties": { + "scale": { + "enum": [ + "linear", + "log" + ], + "type": "string" + }, + "ticks": { + "maximum": 20, + "minimum": 2, + "type": "integer" + }, + "yMax": { + "type": "number" + }, + "yMin": { + "type": "number" + } + }, + "type": "object" + }, + "categories": { + "description": "Category / slice labels (x-axis). Defaults to 1-based indices when omitted.", + "items": { + "maxLength": 200, + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "chartType": { + "description": "Chart kind. 'pie'/'donut' use exactly one series; 'bar'/'barH'/'stackedBar'/'stackedBarH'/'line'/'area'/'scatter' support multiple series. 'scatter' requires xValues on every series and a positional xAxis.type ('linear' or 'time').", + "enum": [ + "bar", + "barH", + "stackedBar", + "stackedBarH", + "line", + "area", + "scatter", + "pie", + "donut" + ], + "type": "string" + }, + "colors": { + "description": "Palette override (per-series for bar/line, per-slice for pie/donut).", + "items": { + "anyOf": [ + { + "pattern": "^#?[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } + ], + "description": "CSS-style hex colour, e.g. \"#3366cc\"." + }, + "maxItems": 50, + "type": "array" + }, + "dataLabels": { + "description": "Per-point value labels: true for defaults, or an object to format them.", + "oneOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "decimals": { + "maximum": 6, + "minimum": 0, + "type": "integer" + }, + "prefix": { + "maxLength": 16, + "type": "string" + }, + "suffix": { + "maxLength": 16, + "type": "string" + } + }, + "type": "object" + } + ] + }, + "height": { + "description": "Plot-area height in points. Default 240.", + "maximum": 2000, + "minimum": 50, + "type": "number" + }, + "labelRotation": { + "description": "Rotate category labels counter-clockwise by this many degrees (disables the automatic stride).", + "maximum": 90, + "minimum": 0, + "type": "number" + }, + "labelStride": { + "description": "Draw every Nth category label. Default: automatic (measured non-overlap); 1 draws every label.", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "legend": { + "description": "Legend placement. Defaults to 'bottom' for multi-series/pie, else 'none'.", + "enum": [ + "bottom", + "none" + ], + "type": "string" + }, + "markers": { + "description": "Draw point markers on line series. Default false.", + "type": "boolean" + }, + "series": { + "description": "Data series. Pie/donut charts use exactly one series (each value becomes a slice).", + "items": { + "additionalProperties": false, + "properties": { + "color": { + "anyOf": [ + { + "pattern": "^#?[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } + ], + "description": "CSS-style hex colour, e.g. \"#3366cc\"." + }, + "label": { + "description": "Series label (shown in the legend).", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "values": { + "description": "Numeric values, one per category. Negative values are supported for bar/line.", + "items": { + "type": "number" + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "xValues": { + "description": "Per-point x positions (same length as values) for scatter charts and for line/area charts with xAxis.type 'linear' or 'time'.", + "items": { + "description": "Positional x value: a number (linear axis) or an ISO-8601 date / epoch milliseconds (time axis).", + "maxLength": 64, + "type": [ + "number", + "string" + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "yAxis": { + "description": "Bind the series to the left (default) or the secondary right value axis (cartesian charts only; configure its range with 'axis2').", + "enum": [ + "left", + "right" + ], + "type": "string" + } + }, + "required": [ + "label", + "values" + ], + "type": "object" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "title": { + "description": "Chart title rendered above the plot.", + "maxLength": 200, + "type": "string" + }, + "type": { + "const": "chart" + }, + "width": { + "description": "Plot width in points (clamped to content width). Default 460.", + "maximum": 2000, + "minimum": 50, + "type": "number" + }, + "xAxis": { + "additionalProperties": false, + "description": "Horizontal axis. 'category' (default) positions points by index; 'linear' / 'time' position them by series xValues (line/area/scatter only). Time ticks are UTC-deterministic.", + "properties": { + "grid": { + "description": "Draw vertical gridlines.", + "type": "boolean" + }, + "max": { + "description": "Axis maximum (number, or ISO-8601 / epoch ms for time axes).", + "maxLength": 64, + "type": [ + "number", + "string" + ] + }, + "min": { + "description": "Axis minimum (number, or ISO-8601 / epoch ms for time axes).", + "maxLength": 64, + "type": [ + "number", + "string" + ] + }, + "ticks": { + "maximum": 20, + "minimum": 2, + "type": "integer" + }, + "type": { + "enum": [ + "category", + "linear", + "time" + ], + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "type", + "chartType", + "series" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Inline smart table — same body as add_table (every row must have exactly as many cells as headers).", + "properties": { + "autoFitColumns": { + "description": "Auto-fit column widths to content. Output bytes then depend on text metrics (not byte-deterministic across content changes).", + "type": "boolean" + }, + "caption": { + "description": "Caption rendered above the table (tagged as /Caption under PDF/A).", + "maxLength": 200, + "type": "string" + }, + "cellBorders": { + "additionalProperties": false, + "description": "Per-cell vector borders (pure strokes, PDF/A-safe). Choose individual sides or `all`.", + "properties": { + "all": { + "description": "Draw all four edges (overrides the individual side flags).", + "type": "boolean" + }, + "bottom": { + "type": "boolean" + }, + "color": { + "anyOf": [ + { + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } + ], + "description": "Stroke colour as a PDF operator string ('0.8 0.8 0.8') or hex. Default light grey." + }, + "left": { + "type": "boolean" + }, + "right": { + "type": "boolean" + }, + "style": { + "description": "Stroke style (default 'solid').", + "enum": [ + "solid", + "dashed", + "dotted" + ], + "type": "string" + }, + "top": { + "type": "boolean" + }, + "width": { + "description": "Stroke width in points (default 0.5).", + "maximum": 10, + "minimum": 0, + "type": "number" + } + }, + "type": "object" + }, + "cellPadding": { + "description": "Horizontal cell padding in points (default 3).", + "maximum": 50, + "minimum": 0, + "type": "number" + }, + "cellVAlign": { + "description": "Vertical alignment of cell content.", + "enum": [ + "top", + "middle", + "bottom" + ], + "type": "string" + }, + "clipCells": { + "description": "Clip cell contents to the column bounds (PDF clip operators). Recommended for PDF/A and visual safety.", + "type": "boolean" + }, + "headers": { + "description": "Column header labels. Must have the same length as each row in `rows`.", + "items": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "minRowHeight": { + "description": "Minimum row height in points (default 12).", + "maximum": 200, + "minimum": 1, + "type": "number" + }, + "repeatHeader": { + "description": "Repeat the header row on every continuation page (default true).", + "type": "boolean" + }, + "rows": { + "description": "Data rows. Each row is an array of cell strings with the same length as `headers`.", + "items": { + "items": { + "maxLength": 500, + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "maxItems": 5000, + "minItems": 1, + "type": "array" + }, + "type": { + "const": "table" + }, + "wrap": { + "description": "Cell wrap policy: 'auto' (default) wraps only overflowing cells; 'always' wraps every cell; 'never' truncates.", + "enum": [ + "auto", + "always", + "never" + ], + "type": "string" + }, + "zebra": { + "description": "Alternate-row light tint (static fill, PDF/A-1b safe).", + "type": "boolean" + } + }, + "required": [ + "type", + "headers", + "rows" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Inline JPEG/PNG image. Without width/height the pixel size is used as points and clamped to the content width; with one dimension the aspect ratio is kept. The decoded bytes of all image blocks in one call are capped at 24 MiB (a watermark image has its own 8 MiB cap).", + "properties": { + "align": { + "default": "left", + "description": "Horizontal placement inside the content width.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + }, + "alt": { + "description": "Accessible description (tagged /Figure /Alt). Always provide it for non-decorative content under PDF/A or PDF/UA.", + "maxLength": 500, + "type": "string" + }, + "height": { + "description": "Render height in points.", + "maximum": 1000, + "minimum": 10, + "type": "number" + }, + "imageBase64": { + "description": "Base64 image bytes. JPEG (baseline; 1, 3 or 4 components — CMYK raises PDFA_DEVICE_CMYK_IMAGE under PDF/A) or PNG (8-bit greyscale/RGB, non-interlaced; alpha-channel and palette PNGs are rejected with a remedy). No data: URI.", + "maxLength": 12000000, + "minLength": 4, + "type": "string" + }, + "mimeType": { + "description": "MIME type of the image. Must match the actual encoding of imageBase64 (magic bytes are checked).", + "enum": [ + "image/jpeg", + "image/png" + ], + "type": "string" + }, + "type": { + "const": "image" + }, + "width": { + "description": "Render width in points.", + "maximum": 800, + "minimum": 10, + "type": "number" + } + }, + "required": [ + "type", + "imageBase64", + "mimeType" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Clickable external link (/URI action). Only http:, https: and mailto: URLs are accepted.", + "properties": { + "color": { + "anyOf": [ + { + "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } + ], + "description": "Hex colour (#RGB or #RRGGBB)." + }, + "fontSize": { + "description": "Default 10.", + "maximum": 48, + "minimum": 6, + "type": "number" + }, + "text": { + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "link" + }, + "url": { + "description": "http(s):// or mailto: URL.", + "maxLength": 2048, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "type", + "text", + "url" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Printed table of contents generated from the document's heading blocks (internal /GoTo links with dot leaders). Pairs with outline:'auto' for the bookmark pane.", + "properties": { + "fontSize": { + "description": "Default 10.", + "maximum": 24, + "minimum": 6, + "type": "number" + }, + "indent": { + "description": "Points of indent per heading level (default 15).", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxLevel": { + "description": "Deepest heading level listed (default 3).", + "enum": [ + 1, + 2, + 3 + ], + "type": "integer" + }, + "title": { + "description": "Default 'Table of Contents'.", + "maxLength": 200, + "type": "string" + }, + "type": { + "const": "toc" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Inline barcode — same body as add_barcode (pure vector, no /Alt available in the engine).", + "properties": { + "align": { + "default": "left", + "description": "Horizontal placement inside the content width.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + }, + "data": { + "description": "Raw payload to encode — do NOT URL-encode. For QR/URL pass e.g. \"https://example.com\" verbatim. EAN-13 must be 12 or 13 digits (13th is auto-computed). Code 128 accepts ASCII alphanumerics.", + "maxLength": 4296, + "minLength": 1, + "type": "string" + }, + "ecLevel": { + "default": "M", + "description": "QR ONLY. Error correction level (L=7%, M=15%, Q=25%, H=30%). Ignored for code128/ean13/datamatrix/pdf417. Use H for printed media that may get smudged or partially covered (e.g. logo overlay).", + "enum": [ + "L", + "M", + "Q", + "H" + ], + "type": "string" + }, + "format": { + "description": "Barcode symbology to render.", + "enum": [ + "qr", + "code128", + "ean13", + "datamatrix", + "pdf417" + ], + "type": "string" + }, + "height": { + "default": 200, + "description": "Barcode height in PDF points (ignored for square symbologies like QR/Data Matrix).", + "maximum": 500, + "minimum": 30, + "type": "number" + }, + "type": { + "const": "barcode" + }, + "width": { + "default": 200, + "description": "Barcode width in PDF points.", + "maximum": 500, + "minimum": 30, + "type": "number" + } + }, + "required": [ + "type", + "format", + "data" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Vector drawing from an SVG path `d` string or SVG markup. Supported: <path> <rect> (rx/ry) <circle> <ellipse> <line> <polyline> <polygon> and <text>/<tspan> (x, y, font-size, fill, text-anchor, dx/dy); fill / stroke / stroke-width attributes; double-quoted attributes only. NOT supported (silently ignored): transform, <g>, <use>, <image>, <defs>/<clipPath>, gradients, opacity, CSS/style, dash patterns, text word-wrap. No external reference is ever fetched (no XML parser: entities other than & < > " ' &#n; are dropped). Pure path operators — PDF/A-safe at every level.", + "properties": { + "align": { + "default": "left", + "description": "Horizontal placement inside the content width.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + }, + "alt": { + "description": "Accessible description (tagged /Figure /Alt). Always provide it for non-decorative content under PDF/A or PDF/UA.", + "maxLength": 500, + "type": "string" + }, + "data": { + "description": "Path `d` string or SVG markup (≤ 100 000 characters).", + "maxLength": 100000, + "minLength": 1, + "type": "string" + }, + "fill": { + "anyOf": [ + { + "pattern": "^(?:none|#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}))$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } + ], + "description": "Hex colour or 'none' (default black)." + }, + "height": { + "description": "Render height in points (default 200).", + "maximum": 1000, + "minimum": 10, + "type": "number" + }, + "stroke": { + "anyOf": [ + { + "pattern": "^(?:none|#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}))$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } + ], + "description": "Hex colour or 'none' (default none)." + }, + "strokeWidth": { + "description": "Stroke width in SVG user units (default 1).", + "maximum": 50, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "svg" + }, + "viewBox": { + "description": "[minX, minY, width, height] — overrides the viewBox of the markup; required for a bare path string that is not 0-based.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "width": { + "description": "Render width in points (default 200).", + "maximum": 800, + "minimum": 10, + "type": "number" + } + }, + "required": [ + "type", + "data" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Inline AcroForm field — same body as an add_form field. Under a PDF/A claim pass embedFonts:true so the field font is embedded too (PDFA_UNEMBEDDED_FORM_FONT otherwise; strict:true then fails the call).", + "properties": { + "checked": { + "description": "Initial checked state for checkbox / radio fields.", + "type": "boolean" + }, + "fieldType": { + "description": "Type of form control to render. Radio fields sharing a name form one radio group.", + "enum": [ + "text", + "textarea", + "checkbox", + "radio", + "dropdown", + "listbox" + ], + "type": "string" + }, + "fontSize": { + "description": "Font size for text rendering inside the field.", + "maximum": 48, + "minimum": 6, + "type": "number" + }, + "height": { + "description": "Field height in points (default depends on the type).", + "maximum": 300, + "minimum": 10, + "type": "number" + }, + "label": { + "description": "Human-readable label shown above the field.", + "maxLength": 200, + "type": "string" + }, + "maxLength": { + "description": "Maximum character length for text/textarea fields.", + "maximum": 32767, + "minimum": 1, + "type": "integer" + }, + "name": { + "description": "Unique field name used as the PDF annotation identifier (/T).", + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "options": { + "description": "Choices for dropdown, listbox or radio fields.", + "items": { + "maxLength": 200, + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "placeholder": { + "description": "Hint text shown while the field is empty.", + "maxLength": 200, + "type": "string" + }, + "readOnly": { + "description": "Prevent editing of this field.", + "type": "boolean" + }, + "required": { + "description": "Mark field as required.", + "type": "boolean" + }, + "type": { + "const": "formField" + }, + "value": { + "description": "Pre-filled value. The key is 'value' (there is no defaultValue).", + "maxLength": 2000, + "type": "string" + }, + "width": { + "description": "Field width in points (default: full content width).", + "maximum": 500, + "minimum": 10, + "type": "number" + } + }, + "required": [ + "type", + "fieldType", + "name" + ], + "type": "object" + } +] - changed
Input schema / properties / embedFonts / descriptionPrevious value: -"Measure with the embedded Noto Sans Latin metrics instead of Helvetica — pass the same value you will give generate_basic_pdf. (Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A claim (ISO 19005 §6.2.11.4.1) and for strict=true; adds ~0.3 MiB.)"New value: +"Measure with the embedded Noto Sans Latin metrics instead of Helvetica — pass the same value you will give generate_basic_pdf. (Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A or PDF/X claim (every font embedded) and for strict=true; adds ~0.3 MiB.)" - changed
Input schema / properties / footerTemplate / properties / center / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - added
Input schema / properties / footerTemplate / properties / color / anyOfAdded value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - changed
Input schema / properties / footerTemplate / properties / color / descriptionPrevious value: -"Hex colour."New value: +"Hex colour (#RRGGBB)." - removed
Input schema / properties / footerTemplate / properties / color / patternRemoved value: -"^#[0-9a-fA-F]{6}$" - removed
Input schema / properties / footerTemplate / properties / color / typeRemoved value: -"string" - changed
Input schema / properties / footerTemplate / properties / left / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / footerTemplate / properties / right / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / headerTemplate / properties / center / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - added
Input schema / properties / headerTemplate / properties / color / anyOfAdded value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - changed
Input schema / properties / headerTemplate / properties / color / descriptionPrevious value: -"Hex colour."New value: +"Hex colour (#RRGGBB)." - removed
Input schema / properties / headerTemplate / properties / color / patternRemoved value: -"^#[0-9a-fA-F]{6}$" - removed
Input schema / properties / headerTemplate / properties / color / typeRemoved value: -"string" - changed
Input schema / properties / headerTemplate / properties / left / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / headerTemplate / properties / right / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - added
Input schema / properties / typographyAdded value: +{ + "additionalProperties": false, + "description": "Fine typography, all opt-in (omitted = unchanged bytes). kerning, fontFeatures and the 'fr' narrow space need embedFonts:true. No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt.", + "properties": { + "bindShortWords": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "maxLength": { + "maximum": 3, + "minimum": 1, + "type": "integer" + }, + "words": { + "items": { + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + ], + "description": "Never end a line on a short word: up to maxLength letters (default 1), or exactly the listed words." + }, + "fontFeatures": { + "description": "OpenType features, later wins. tnum / lnum are no-ops on Noto Sans (TYPOGRAPHY_FEATURE_INEFFECTIVE).", + "items": { + "enum": [ + "tnum", + "pnum", + "lnum", + "onum", + "zero", + "ordn", + "sups", + "subs", + "smcp", + "c2sc", + "case" + ], + "type": "string" + }, + "maxItems": 11, + "type": "array", + "uniqueItems": true + }, + "hyphenationLanguage": { + "description": "BCP 47 tag; no effect here (no hyphenation provider installed).", + "maxLength": 35, + "pattern": "^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$", + "type": "string" + }, + "keepHeadingsWithNext": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "minLines": { + "maximum": 10, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + } + ], + "description": "Never strand a heading at a page foot. true = { minLines: 2 }." + }, + "kerning": { + "description": "Pair kerning (GPOS).", + "type": "boolean" + }, + "metrics": { + "description": "Base-14 text: 'exact' uses the AFM widths (different wraps). Default 'approximate'.", + "enum": [ + "approximate", + "exact" + ], + "type": "string" + }, + "opticalMargins": { + "description": "Hang punctuation into the margin of align:'justify' text.", + "type": "boolean" + }, + "orphans": { + "description": "Min lines left at a page foot (default 2; needs splitParagraphs).", + "maximum": 10, + "minimum": 1, + "type": "integer" + }, + "punctuationSpacing": { + "anyOf": [ + { + "enum": [ + "fr", + "fr-CA" + ], + "type": "string" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "char": { + "maxLength": 2, + "minLength": 1, + "type": "string" + }, + "side": { + "enum": [ + "before", + "after" + ], + "type": "string" + }, + "space": { + "description": "U+00A0 / U+202F (narrow needs embedFonts).", + "enum": [ + "nbsp", + "narrow" + ], + "type": "string" + } + }, + "required": [ + "char", + "side", + "space" + ], + "type": "object" + }, + "maxItems": 32, + "type": "array" + } + ], + "description": "No-break spaces next to punctuation (existing spaces only). 'fr': narrow before ; ! ?, no-break before ':' and inside « ». 'fr-CA': ':' and « » only. Or explicit rules." + }, + "splitParagraphs": { + "description": "Paragraphs may break across pages at a line boundary (default: atomic).", + "type": "boolean" + }, + "unitBinding": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "units": { + "items": { + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + ], + "description": "No-break space between a number and its unit ('150 €', '12 kg'); units replaces the built-in list." + }, + "widows": { + "description": "Min lines carried over (default 2; needs splitParagraphs).", + "maximum": 10, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" +}
- Changed
inspect_pdf5 fields changed- changed
Input schema / properties / check / descriptionPrevious value: -"CI assertions → checks (requested keys only) + checksPassed (all hold). 'signed' = a signature field with signed content exists (structural; validity is verify_pdf's job), 'placeholder' = an unsigned placeholder exists, 'dss' = /DSS present, 'docTimestamp' = a /DocTimeStamp exists, 'trapped' = /Info /Trapped set, 'annotations' = at least one page annotation exists."New value: +"CI assertions → checks (requested keys only) + checksPassed (all hold). 'signed' = a signature field with signed content exists (structural; validity is verify_pdf's job), 'placeholder' = an unsigned placeholder exists, 'dss' = /DSS present, 'docTimestamp' = a /DocTimeStamp exists, 'trapped' = /Info /Trapped set, 'annotations' = at least one page annotation exists, 'pdfx' = the XMP claims PDF/X (the claim, not its validity — validate_pdf standard:'pdf-x-4')." - changed
Input schema / properties / check / items / enumPrevious value: -[ - "pdfa", - "signed", - "encrypted", - "placeholder", - "attachments", - "dss", - "docTimestamp", - "trapped", - "annotations" -]New value: +[ + "pdfa", + "signed", + "encrypted", + "placeholder", + "attachments", + "dss", + "docTimestamp", + "trapped", + "annotations", + "pdfx" +] - changed
Input schema / properties / check / maxItemsPrevious value: -9New value: +10 - changed
Input schema / properties / verbosity / descriptionPrevious value: -"'full' (default) or 'summary' (scalars only: version, pageCount, encryption, pdfA, signatureCount, hasSignaturePlaceholder, attachmentCount, + docTimestampCount / trapped / checksPassed when present; arrays and dss dropped)."New value: +"'full' (default) or 'summary' (scalars only: version, pageCount, encryption, pdfA, signatureCount, hasSignaturePlaceholder, attachmentCount, + docTimestampCount / trapped / pdfX / checksPassed when present; arrays and dss dropped)." - added
Output schema / properties / pdfXAdded value: +{ + "description": "PDF/X claim from XMP (pdfxid:GTS_PDFXVersion, e.g. 'PDF/X-4'), present only when the document makes one. A claim, not a verdict: validate_pdf standard:'pdf-x-4' checks it.", + "type": "string" +}
- Changed
merge_pdfs1 field changed- changed
Output schema / properties / diagnostics / descriptionPrevious value: -"PDF/A diagnostics (when includeDiagnostics=true)."New value: +"Engine diagnostics (when includeDiagnostics=true)."
- Changed
prepare_signature_placeholder23 fields changed- changed
Input schema / properties / creationDate / descriptionPrevious value: -"ISO-8601 instant for /CreationDate (+ XMP). Pin it for byte-identical output across calls (same host TZ); omitted = wall clock, so every call differs."New value: +"ISO-8601 instant for /CreationDate (+ XMP, the trailer /ID and the {date} placeholder), written in UTC. Pin it for byte-identical output across calls and hosts; omitted = wall clock, so every call differs." - changed
Input schema / properties / embedFonts / descriptionPrevious value: -"Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A claim (ISO 19005 §6.2.11.4.1) and for strict=true; adds ~0.3 MiB."New value: +"Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A or PDF/X claim (every font embedded) and for strict=true; adds ~0.3 MiB." - changed
Input schema / properties / footerTemplate / properties / center / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - added
Input schema / properties / footerTemplate / properties / color / anyOfAdded value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - changed
Input schema / properties / footerTemplate / properties / color / descriptionPrevious value: -"Hex colour."New value: +"Hex colour (#RRGGBB)." - removed
Input schema / properties / footerTemplate / properties / color / patternRemoved value: -"^#[0-9a-fA-F]{6}$" - removed
Input schema / properties / footerTemplate / properties / color / typeRemoved value: -"string" - changed
Input schema / properties / footerTemplate / properties / left / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / footerTemplate / properties / right / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / headerTemplate / properties / center / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - added
Input schema / properties / headerTemplate / properties / color / anyOfAdded value: +[ + { + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + { + "description": "DeviceCMYK operands 'C M Y K', each 0.0–1.0.", + "pattern": "^(?:0(?:\\.\\d+)?|1(?:\\.0+)?)(?: (?:0(?:\\.\\d+)?|1(?:\\.0+)?)){3}$", + "type": "string" + }, + { + "description": "DeviceCMYK ink percentages [c, m, y, k], each 0–100.", + "items": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + } +] - changed
Input schema / properties / headerTemplate / properties / color / descriptionPrevious value: -"Hex colour."New value: +"Hex colour (#RRGGBB)." - removed
Input schema / properties / headerTemplate / properties / color / patternRemoved value: -"^#[0-9a-fA-F]{6}$" - removed
Input schema / properties / headerTemplate / properties / color / typeRemoved value: -"string" - changed
Input schema / properties / headerTemplate / properties / left / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / headerTemplate / properties / right / descriptionPrevious value: -"Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate)."New value: +"Placeholders: {page} {pages} {title} {date} (UTC date of creationDate when pinned, else of the build)." - changed
Input schema / properties / includeDiagnostics / descriptionPrevious value: -"Return the PDF/A diagnostics raised while building as `diagnostics[]` (possibly empty)."New value: +"Return the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*) as `diagnostics[]` (possibly empty)." - changed
Input schema / properties / outputIntent / descriptionPrevious value: -"Custom PDF/A OutputIntent: an RGB ICC profile + condition strings replacing the built-in sRGB intent (CMYK rejected)."New value: +"Custom OutputIntent (under pdfA or pdfx): an RGB, CMYK or Gray ICC profile + condition strings, replacing the built-in sRGB intent. The profile must be a real ICC file ('acsp' signature, consistent size — PRINT_ERROR otherwise); pdfx needs device class 'prtr'. Under a CMYK / Gray intent RGB content is mapped through a calibrated default space." - changed
Input schema / properties / outputIntent / properties / iccProfileBase64 / descriptionPrevious value: -"ICC profile bytes, base64 (RGB, ≤ 8 MiB)."New value: +"ICC profile bytes, base64 (RGB, CMYK or Gray; ≤ 8 MiB)." - changed
Input schema / properties / print / properties / marks / oneOfPrevious value: -[ - { - "type": "boolean" - }, - { - "additionalProperties": false, - "properties": { - "crop": { - "description": "Corner crop (trim) marks. Default true.", - "type": "boolean" - }, - "length": { - "description": "Mark length in points. Default 14.", - "maximum": 100, - "minimum": 1, - "type": "number" - }, - "offset": { - "description": "Gap between TrimBox and marks in points. Default 5.", - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "registration": { - "description": "Edge-midpoint registration targets. Default true.", - "type": "boolean" - }, - "weight": { - "description": "Stroke width in points. Default 0.25.", - "maximum": 5, - "minimum": 0.05, - "type": "number" - } - }, - "type": "object" - } -]New value: +[ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "colourBars": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "size": { + "description": "Patch size in points. Default 12.", + "maximum": 72, + "minimum": 4, + "type": "number" + }, + "tints": { + "description": "Add the four 50 % tint patches. Default true.", + "type": "boolean" + } + }, + "type": "object" + } + ], + "description": "Colour control strip in the bleed (C M Y K solids + their 50 % tints): true for defaults. Off by default; needs a bleed of about 5 mm (14.17 pt) and is skipped when the strip would not fit." + }, + "crop": { + "description": "Corner crop (trim) marks. Default true.", + "type": "boolean" + }, + "length": { + "description": "Mark length in points. Default 14.", + "maximum": 100, + "minimum": 1, + "type": "number" + }, + "offset": { + "description": "Gap between TrimBox and marks in points. Default 5.", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "registration": { + "description": "Edge-midpoint registration targets. Default true.", + "type": "boolean" + }, + "weight": { + "description": "Stroke width in points. Default 0.25.", + "maximum": 5, + "minimum": 0.05, + "type": "number" + } + }, + "type": "object" + } +] - changed
Input schema / properties / strict / descriptionPrevious value: -"Fail with PDF_A_COMPLIANCE_VIOLATION instead of producing a non-conformant PDF/A file (e.g. PDFA_NO_FONT_ENTRIES without embedFonts). Pair with embedFonts=true."New value: +"Fail instead of producing a file the engine warns about: a PDFA_* diagnostic → PDF_A_COMPLIANCE_VIOLATION (e.g. PDFA_NO_FONT_ENTRIES without embedFonts), a PDFX_* one → PDF_X_COMPLIANCE_VIOLATION, any other → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true." - added
Input schema / properties / typographyAdded value: +{ + "additionalProperties": false, + "description": "Fine typography, all opt-in (omitted = unchanged bytes). kerning, fontFeatures and the 'fr' narrow space need embedFonts:true. No hyphenation dictionary is installed: use soft hyphens (U+00AD). See the typography prompt.", + "properties": { + "bindShortWords": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "maxLength": { + "maximum": 3, + "minimum": 1, + "type": "integer" + }, + "words": { + "items": { + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + ], + "description": "Never end a line on a short word: up to maxLength letters (default 1), or exactly the listed words." + }, + "fontFeatures": { + "description": "OpenType features, later wins. tnum / lnum are no-ops on Noto Sans (TYPOGRAPHY_FEATURE_INEFFECTIVE).", + "items": { + "enum": [ + "tnum", + "pnum", + "lnum", + "onum", + "zero", + "ordn", + "sups", + "subs", + "smcp", + "c2sc", + "case" + ], + "type": "string" + }, + "maxItems": 11, + "type": "array", + "uniqueItems": true + }, + "hyphenationLanguage": { + "description": "BCP 47 tag; no effect here (no hyphenation provider installed).", + "maxLength": 35, + "pattern": "^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$", + "type": "string" + }, + "keepHeadingsWithNext": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "minLines": { + "maximum": 10, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + } + ], + "description": "Never strand a heading at a page foot. true = { minLines: 2 }." + }, + "kerning": { + "description": "Pair kerning (GPOS).", + "type": "boolean" + }, + "metrics": { + "description": "Base-14 text: 'exact' uses the AFM widths (different wraps). Default 'approximate'.", + "enum": [ + "approximate", + "exact" + ], + "type": "string" + }, + "opticalMargins": { + "description": "Hang punctuation into the margin of align:'justify' text.", + "type": "boolean" + }, + "orphans": { + "description": "Min lines left at a page foot (default 2; needs splitParagraphs).", + "maximum": 10, + "minimum": 1, + "type": "integer" + }, + "punctuationSpacing": { + "anyOf": [ + { + "enum": [ + "fr", + "fr-CA" + ], + "type": "string" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "char": { + "maxLength": 2, + "minLength": 1, + "type": "string" + }, + "side": { + "enum": [ + "before", + "after" + ], + "type": "string" + }, + "space": { + "description": "U+00A0 / U+202F (narrow needs embedFonts).", + "enum": [ + "nbsp", + "narrow" + ], + "type": "string" + } + }, + "required": [ + "char", + "side", + "space" + ], + "type": "object" + }, + "maxItems": 32, + "type": "array" + } + ], + "description": "No-break spaces next to punctuation (existing spaces only). 'fr': narrow before ; ! ?, no-break before ':' and inside « ». 'fr-CA': ':' and « » only. Or explicit rules." + }, + "splitParagraphs": { + "description": "Paragraphs may break across pages at a line boundary (default: atomic).", + "type": "boolean" + }, + "unitBinding": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "units": { + "items": { + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + ], + "description": "No-break space between a number and its unit ('150 €', '12 kg'); units replaces the built-in list." + }, + "widows": { + "description": "Min lines carried over (default 2; needs splitParagraphs).", + "maximum": 10, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" +} - changed
Output schema / properties / diagnostics / descriptionPrevious value: -"PDF/A diagnostics (when includeDiagnostics=true)."New value: +"Engine diagnostics (when includeDiagnostics=true)."
- Changed
sign_pdf4 fields changed- changed
Input schema / properties / certDerBase64 / descriptionPrevious value: -"Base64 of the signer X.509 certificate in DER form. Convert from PEM with: openssl x509 -in cert.pem -outform DER | base64 -w0"New value: +"Base64 of the signer X.509 certificate in DER form. Convert from PEM with: openssl x509 -in cert.pem -outform DER | openssl base64 -A" - changed
Input schema / properties / ecPrivateKeyDerBase64 / descriptionPrevious value: -"Base64 of an ECDSA P-256 private key in SEC1 (RFC 5915) or PKCS#8 (RFC 5208) DER form. Convert from PEM with: openssl pkey -in key.pem -outform DER | base64 -w0 Mutually exclusive with ecPrivateScalarHex."New value: +"Base64 of an ECDSA P-256 private key in SEC1 (RFC 5915) or PKCS#8 (RFC 5208) DER form. Convert from PEM with: openssl pkey -in key.pem -outform DER | openssl base64 -A Mutually exclusive with ecPrivateScalarHex." - changed
Input schema / properties / rsaKeyPkcs1DerBase64 / descriptionPrevious value: -"Base64 of the RSA private key in DER form — PKCS#1 RSAPrivateKey (openssl rsa -in key.pem -outform DER -traditional | base64 -w0) or PKCS#8 PrivateKeyInfo (openssl pkey -in key.pem -outform DER | base64 -w0). NOT PEM. Required for the rsa-* algorithms."New value: +"Base64 of the RSA private key in DER form — PKCS#1 RSAPrivateKey (openssl rsa -in key.pem -outform DER -traditional | openssl base64 -A) or PKCS#8 PrivateKeyInfo (openssl pkey -in key.pem -outform DER | openssl base64 -A). NOT PEM. Required for the rsa-* algorithms." - changed
Output schema / properties / diagnostics / descriptionPrevious value: -"PDF/A diagnostics (when includeDiagnostics=true)."New value: +"Engine diagnostics (when includeDiagnostics=true)."
- Changed
timestamp_pdf1 field changed- changed
Output schema / properties / diagnostics / descriptionPrevious value: -"PDF/A diagnostics (when includeDiagnostics=true)."New value: +"Engine diagnostics (when includeDiagnostics=true)."
- Changed
update_metadata1 field changed- changed
Output schema / properties / diagnostics / descriptionPrevious value: -"PDF/A diagnostics (when includeDiagnostics=true)."New value: +"Engine diagnostics (when includeDiagnostics=true)."
- Changed
validate_pdf7 fields changed- changed
Input schema / properties / pdfBase64 / descriptionPrevious value: -"Base64-encoded PDF bytes to validate for PDF/UA (ISO 14289-1) structural conformance."New value: +"Base64-encoded PDF bytes to validate for structural conformance." - added
Input schema / properties / standardAdded value: +{ + "default": "pdf-ua-1", + "description": "Rule set. 'pdf-ua-1' (default): PDF/UA accessibility structure (ISO 14289-1). 'pdf-x-4': PDF/X-4 print exchange (ISO 15930-7) — OutputIntent + prtr ICC profile, TrimBox, embedded fonts, no annotations / JavaScript / embedded files; structural prerequisites only, not a certified preflight (see caveats[]).", + "enum": [ + "pdf-ua-1", + "pdf-x-4" + ], + "type": "string" +} - changed
Output schema / descriptionPrevious value: -"Structured PDF/UA validation result. Every property is optional because the result can be projected: verbosity:'summary' returns only the scalar summary fields, fields:[...] keeps a dot-path subset. Defaults return the full shape."New value: +"Structured PDF/UA or PDF/X-4 validation result. Every property is optional because the result can be projected: verbosity:'summary' returns only the scalar summary fields, fields:[...] keeps a dot-path subset. Defaults return the full shape." - added
Output schema / properties / caveatsAdded value: +{ + "description": "standard 'pdf-x-4' only: what a valid verdict does NOT establish.", + "items": { + "type": "string" + }, + "type": "array" +} - changed
Output schema / properties / errors / descriptionPrevious value: -"Blocking PDF/UA conformance violations. Empty when valid is true."New value: +"Blocking conformance violations. Empty when valid is true." - changed
Output schema / properties / standard / descriptionPrevious value: -"Conformance standard checked (ISO 14289-1)."New value: +"Conformance standard checked (ISO 14289-1 or ISO 15930-7)." - changed
Output schema / properties / standard / enumPrevious value: -[ - "pdf-ua-1" -]New value: +[ + "pdf-ua-1", + "pdf-x-4" +]
27 tool updates
- Changed
add_attachment19 fields changed- added
Input schema / properties / compressAdded value: +{ + "description": "FlateDecode the streams (smaller file, different bytes; PDF/A unaffected, XMP stays plain). Default false.", + "type": "boolean" +} - added
Input schema / properties / creationDateAdded value: +{ + "description": "ISO-8601 instant for /CreationDate (+ XMP). Pin it for byte-identical output across calls (same host TZ); omitted = wall clock, so every call differs.", + "format": "date-time", + "type": "string" +} - added
Input schema / properties / debugAdded value: +{ + "description": "Draw margin / block / cell guide rectangles (unmarked content — not for PDF/UA output). Geometry unchanged. Default false.", + "type": "boolean" +} - added
Input schema / properties / embedFontsAdded value: +{ + "default": false, + "description": "Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A claim (ISO 19005 §6.2.11.4.1) and for strict=true; adds ~0.3 MiB.", + "type": "boolean" +} - added
Input schema / properties / footerTemplateAdded value: +{ + "additionalProperties": false, + "description": "Running footer on every page. Replaces the default footer: footerText is then ignored and page numbers appear only via {page}/{pages}.", + "properties": { + "center": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "color": { + "description": "Hex colour.", + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + "fontSize": { + "description": "Default 7.", + "maximum": 14, + "minimum": 6, + "type": "number" + }, + "left": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "right": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / headerTemplateAdded value: +{ + "additionalProperties": false, + "description": "Running header on every page (left / center / right zones); reserves 15 pt.", + "properties": { + "center": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "color": { + "description": "Hex colour.", + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + "fontSize": { + "description": "Default 7.", + "maximum": 14, + "minimum": 6, + "type": "number" + }, + "left": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "right": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / includeDiagnosticsAdded value: +{ + "default": false, + "description": "Return the PDF/A diagnostics raised while building as `diagnostics[]` (possibly empty).", + "type": "boolean" +} - added
Input schema / properties / marginsAdded value: +{ + "additionalProperties": false, + "description": "Margins in points, all four required (0–200). Default 45 / 36 / 35 / 36.", + "properties": { + "bottom": { + "maximum": 200, + "minimum": 0, + "type": "number" + }, + "left": { + "maximum": 200, + "minimum": 0, + "type": "number" + }, + "right": { + "maximum": 200, + "minimum": 0, + "type": "number" + }, + "top": { + "maximum": 200, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "top", + "right", + "bottom", + "left" + ], + "type": "object" +} - added
Input schema / properties / metadataAdded value: +{ + "additionalProperties": false, + "description": "/Info (+ XMP under PDF/A): author, subject, keywords, /Trapped.", + "properties": { + "author": { + "maxLength": 500, + "type": "string" + }, + "keywords": { + "maxLength": 1000, + "type": "string" + }, + "subject": { + "maxLength": 1000, + "type": "string" + }, + "trapped": { + "description": "/Trapped print flag.", + "enum": [ + "True", + "False", + "Unknown" + ], + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / outputIntentAdded value: +{ + "additionalProperties": false, + "description": "Custom PDF/A OutputIntent: an RGB ICC profile + condition strings replacing the built-in sRGB intent (CMYK rejected).", + "properties": { + "iccProfileBase64": { + "description": "ICC profile bytes, base64 (RGB, ≤ 8 MiB).", + "maxLength": 11000000, + "minLength": 1, + "type": "string" + }, + "info": { + "maxLength": 500, + "type": "string" + }, + "outputCondition": { + "maxLength": 200, + "type": "string" + }, + "outputConditionIdentifier": { + "description": "e.g. \"sRGB IEC61966-2.1\".", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "registryName": { + "description": "Default \"http://www.color.org\".", + "maxLength": 200, + "type": "string" + } + }, + "required": [ + "iccProfileBase64", + "outputConditionIdentifier" + ], + "type": "object" +} - added
Input schema / properties / outputMode / descriptionAdded value: +"'base64' (default) returns the PDF inline; 'file' writes it inside the PDFNATIVE_MCP_OUTPUT_DIR sandbox (SECURITY_VIOLATION when the sandbox is not configured)." - added
Input schema / properties / outputPath / descriptionAdded value: +"Required when outputMode='file'. Relative path inside the sandbox; must end with .pdf (no absolute paths, no '..')." - added
Input schema / properties / pageSizeAdded value: +{ + "description": "Portrait page preset (points): A4 595.28×841.89 (default), Letter 612×792, Legal 612×1008, A3 841.89×1190.55, Tabloid 792×1224. print.* boxes must fit it.", + "enum": [ + "A4", + "Letter", + "Legal", + "A3", + "Tabloid" + ], + "type": "string" +} - added
Input schema / properties / printAdded value: +{ + "additionalProperties": false, + "description": "Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b). See docs/guides/PRINT.md.", + "properties": { + "artBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "bleed": { + "description": "Bleed in points (8.5 = 3 mm); sets TrimBox = MediaBox inset. Exclusive with trimBox.", + "exclusiveMinimum": 0, + "maximum": 200, + "type": "number" + }, + "bleedBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "cropBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "marks": { + "description": "Printer's marks (needs bleed or trimBox): true for defaults, or an object.", + "oneOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "crop": { + "description": "Corner crop (trim) marks. Default true.", + "type": "boolean" + }, + "length": { + "description": "Mark length in points. Default 14.", + "maximum": 100, + "minimum": 1, + "type": "number" + }, + "offset": { + "description": "Gap between TrimBox and marks in points. Default 5.", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "registration": { + "description": "Edge-midpoint registration targets. Default true.", + "type": "boolean" + }, + "weight": { + "description": "Stroke width in points. Default 0.25.", + "maximum": 5, + "minimum": 0.05, + "type": "number" + } + }, + "type": "object" + } + ] + }, + "trimBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "userUnit": { + "description": "/UserUnit (multiples of 1/72 in) for pages over 14400 pt. Rejected under pdfa1b.", + "maximum": 75000, + "minimum": 1, + "type": "number" + } + }, + "type": "object" +} - added
Input schema / properties / strictAdded value: +{ + "default": false, + "description": "Fail with PDF_A_COMPLIANCE_VIOLATION instead of producing a non-conformant PDF/A file (e.g. PDFA_NO_FONT_ENTRIES without embedFonts). Pair with embedFonts=true.", + "type": "boolean" +} - changed
Output schema / descriptionPrevious value: -"Structured result of a PDF-producing tool. In base64 mode the PDF bytes are delivered out-of-band as an embedded `resource` content block (data: URI), NOT duplicated here, to keep responses token-frugal. In file mode `filePath` is the sandboxed absolute path."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`." - added
Output schema / properties / diagnosticsAdded value: +{ + "description": "PDF/A diagnostics (when includeDiagnostics=true).", + "items": { + "additionalProperties": false, + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "severity": { + "enum": [ + "warning" + ], + "type": "string" + } + }, + "required": [ + "code", + "message", + "severity" + ], + "type": "object" + }, + "type": "array" +} - changed
Output schema / properties / filePath / descriptionPrevious value: -"Absolute sandboxed file path (when mode='file')."New value: +"Sandboxed absolute path (file mode)." - added
Output schema / properties / summaryAdded value: +{ + "additionalProperties": true, + "description": "Tool-specific summary, when produced.", + "type": "object" +}
- Changed
add_barcode21 fields changed- added
Input schema / properties / compressAdded value: +{ + "description": "FlateDecode the streams (smaller file, different bytes; PDF/A unaffected, XMP stays plain). Default false.", + "type": "boolean" +} - added
Input schema / properties / creationDateAdded value: +{ + "description": "ISO-8601 instant for /CreationDate (+ XMP). Pin it for byte-identical output across calls (same host TZ); omitted = wall clock, so every call differs.", + "format": "date-time", + "type": "string" +} - added
Input schema / properties / debugAdded value: +{ + "description": "Draw margin / block / cell guide rectangles (unmarked content — not for PDF/UA output). Geometry unchanged. Default false.", + "type": "boolean" +} - added
Input schema / properties / embedFontsAdded value: +{ + "default": false, + "description": "Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A claim (ISO 19005 §6.2.11.4.1) and for strict=true; adds ~0.3 MiB.", + "type": "boolean" +} - added
Input schema / properties / encryptAdded value: +{ + "additionalProperties": false, + "description": "Encrypt at build time (AES-128 default / AES-256) and KEEP the AcroForm — unlike encrypt_pdf, which rebuilds the page tree. Exclusive with pdfA. Randomised output, never cached.", + "properties": { + "algorithm": { + "default": "aes128", + "description": "aes128 (V4/R4, widest compatibility) or aes256 (V5/R6).", + "enum": [ + "aes128", + "aes256" + ], + "type": "string" + }, + "ownerPassword": { + "description": "Owner password (full access).", + "maxLength": 4096, + "minLength": 1, + "type": "string" + }, + "permissions": { + "additionalProperties": false, + "description": "Permission flags; each defaults to allowed.", + "properties": { + "copy": { + "type": "boolean" + }, + "extractText": { + "type": "boolean" + }, + "modify": { + "type": "boolean" + }, + "print": { + "type": "boolean" + } + }, + "type": "object" + }, + "userPassword": { + "description": "Open password; omitted/empty = opens without a prompt.", + "maxLength": 4096, + "type": "string" + } + }, + "required": [ + "ownerPassword" + ], + "type": "object" +} - added
Input schema / properties / footerTemplateAdded value: +{ + "additionalProperties": false, + "description": "Running footer on every page. Replaces the default footer: footerText is then ignored and page numbers appear only via {page}/{pages}.", + "properties": { + "center": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "color": { + "description": "Hex colour.", + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + "fontSize": { + "description": "Default 7.", + "maximum": 14, + "minimum": 6, + "type": "number" + }, + "left": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "right": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / headerTemplateAdded value: +{ + "additionalProperties": false, + "description": "Running header on every page (left / center / right zones); reserves 15 pt.", + "properties": { + "center": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "color": { + "description": "Hex colour.", + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + "fontSize": { + "description": "Default 7.", + "maximum": 14, + "minimum": 6, + "type": "number" + }, + "left": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "right": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / includeDiagnosticsAdded value: +{ + "default": false, + "description": "Return the PDF/A diagnostics raised while building as `diagnostics[]` (possibly empty).", + "type": "boolean" +} - added
Input schema / properties / marginsAdded value: +{ + "additionalProperties": false, + "description": "Margins in points, all four required (0–200). Default 45 / 36 / 35 / 36.", + "properties": { + "bottom": { + "maximum": 200, + "minimum": 0, + "type": "number" + }, + "left": { + "maximum": 200, + "minimum": 0, + "type": "number" + }, + "right": { + "maximum": 200, + "minimum": 0, + "type": "number" + }, + "top": { + "maximum": 200, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "top", + "right", + "bottom", + "left" + ], + "type": "object" +} - added
Input schema / properties / metadataAdded value: +{ + "additionalProperties": false, + "description": "/Info (+ XMP under PDF/A): author, subject, keywords, /Trapped.", + "properties": { + "author": { + "maxLength": 500, + "type": "string" + }, + "keywords": { + "maxLength": 1000, + "type": "string" + }, + "subject": { + "maxLength": 1000, + "type": "string" + }, + "trapped": { + "description": "/Trapped print flag.", + "enum": [ + "True", + "False", + "Unknown" + ], + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / outputIntentAdded value: +{ + "additionalProperties": false, + "description": "Custom PDF/A OutputIntent: an RGB ICC profile + condition strings replacing the built-in sRGB intent (CMYK rejected).", + "properties": { + "iccProfileBase64": { + "description": "ICC profile bytes, base64 (RGB, ≤ 8 MiB).", + "maxLength": 11000000, + "minLength": 1, + "type": "string" + }, + "info": { + "maxLength": 500, + "type": "string" + }, + "outputCondition": { + "maxLength": 200, + "type": "string" + }, + "outputConditionIdentifier": { + "description": "e.g. \"sRGB IEC61966-2.1\".", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "registryName": { + "description": "Default \"http://www.color.org\".", + "maxLength": 200, + "type": "string" + } + }, + "required": [ + "iccProfileBase64", + "outputConditionIdentifier" + ], + "type": "object" +} - added
Input schema / properties / outputMode / descriptionAdded value: +"'base64' (default) returns the PDF inline; 'file' writes it inside the PDFNATIVE_MCP_OUTPUT_DIR sandbox (SECURITY_VIOLATION when the sandbox is not configured)." - added
Input schema / properties / outputPath / descriptionAdded value: +"Required when outputMode='file'. Relative path inside the sandbox; must end with .pdf (no absolute paths, no '..')." - added
Input schema / properties / pageSizeAdded value: +{ + "description": "Portrait page preset (points): A4 595.28×841.89 (default), Letter 612×792, Legal 612×1008, A3 841.89×1190.55, Tabloid 792×1224. print.* boxes must fit it.", + "enum": [ + "A4", + "Letter", + "Legal", + "A3", + "Tabloid" + ], + "type": "string" +} - changed
Input schema / properties / pdfA / descriptionPrevious value: -"Optional PDF/A conformance level (powered by pdfnative v1.2). Use 'pdfa1b' for archival of simple text+images, 'pdfa2b'/'pdfa2u' for richer content (2u guarantees Unicode mapping), 'pdfa3b' when embedding source attachments (Factur-X / ZUGFeRD). Mutually exclusive with PDF encryption. See docs/guides/PDFA.md."New value: +"PDF/A level: pdfa1b (simple text+images), pdfa2b/pdfa2u (richer; 2u = Unicode mapping), pdfa3b (attachments / Factur-X). Pair with embedFonts=true for a valid claim. Exclusive with encryption. See docs/guides/PDFA.md." - added
Input schema / properties / printAdded value: +{ + "additionalProperties": false, + "description": "Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b). See docs/guides/PRINT.md.", + "properties": { + "artBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "bleed": { + "description": "Bleed in points (8.5 = 3 mm); sets TrimBox = MediaBox inset. Exclusive with trimBox.", + "exclusiveMinimum": 0, + "maximum": 200, + "type": "number" + }, + "bleedBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "cropBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "marks": { + "description": "Printer's marks (needs bleed or trimBox): true for defaults, or an object.", + "oneOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "crop": { + "description": "Corner crop (trim) marks. Default true.", + "type": "boolean" + }, + "length": { + "description": "Mark length in points. Default 14.", + "maximum": 100, + "minimum": 1, + "type": "number" + }, + "offset": { + "description": "Gap between TrimBox and marks in points. Default 5.", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "registration": { + "description": "Edge-midpoint registration targets. Default true.", + "type": "boolean" + }, + "weight": { + "description": "Stroke width in points. Default 0.25.", + "maximum": 5, + "minimum": 0.05, + "type": "number" + } + }, + "type": "object" + } + ] + }, + "trimBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "userUnit": { + "description": "/UserUnit (multiples of 1/72 in) for pages over 14400 pt. Rejected under pdfa1b.", + "maximum": 75000, + "minimum": 1, + "type": "number" + } + }, + "type": "object" +} - added
Input schema / properties / strictAdded value: +{ + "default": false, + "description": "Fail with PDF_A_COMPLIANCE_VIOLATION instead of producing a non-conformant PDF/A file (e.g. PDFA_NO_FONT_ENTRIES without embedFonts). Pair with embedFonts=true.", + "type": "boolean" +} - changed
Output schema / descriptionPrevious value: -"Structured result of a PDF-producing tool. In base64 mode the PDF bytes are delivered out-of-band as an embedded `resource` content block (data: URI), NOT duplicated here, to keep responses token-frugal. In file mode `filePath` is the sandboxed absolute path."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`." - added
Output schema / properties / diagnosticsAdded value: +{ + "description": "PDF/A diagnostics (when includeDiagnostics=true).", + "items": { + "additionalProperties": false, + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "severity": { + "enum": [ + "warning" + ], + "type": "string" + } + }, + "required": [ + "code", + "message", + "severity" + ], + "type": "object" + }, + "type": "array" +} - changed
Output schema / properties / filePath / descriptionPrevious value: -"Absolute sandboxed file path (when mode='file')."New value: +"Sandboxed absolute path (file mode)." - added
Output schema / properties / summaryAdded value: +{ + "additionalProperties": true, + "description": "Tool-specific summary, when produced.", + "type": "object" +}
- Changed
add_chart29 fields changed- added
Input schema / properties / axis / properties / scaleAdded value: +{ + "description": "Value-axis scale. 'log' requires strictly positive values and is not available for stacked charts.", + "enum": [ + "linear", + "log" + ], + "type": "string" +} - added
Input schema / properties / axis2Added value: +{ + "additionalProperties": false, + "description": "Secondary RIGHT value axis (drawn only when a series sets yAxis:'right').", + "properties": { + "scale": { + "enum": [ + "linear", + "log" + ], + "type": "string" + }, + "ticks": { + "maximum": 20, + "minimum": 2, + "type": "integer" + }, + "yMax": { + "type": "number" + }, + "yMin": { + "type": "number" + } + }, + "type": "object" +} - changed
Input schema / properties / chartType / descriptionPrevious value: -"Chart kind. 'pie'/'donut' use exactly one series; 'bar'/'barH'/'line' support multiple series."New value: +"Chart kind. 'pie'/'donut' use exactly one series; 'bar'/'barH'/'stackedBar'/'stackedBarH'/'line'/'area'/'scatter' support multiple series. 'scatter' requires xValues on every series and a positional xAxis.type ('linear' or 'time')." - changed
Input schema / properties / chartType / enumPrevious value: -[ - "bar", - "barH", - "line", - "pie", - "donut" -]New value: +[ + "bar", + "barH", + "stackedBar", + "stackedBarH", + "line", + "area", + "scatter", + "pie", + "donut" +] - added
Input schema / properties / compressAdded value: +{ + "description": "FlateDecode the streams (smaller file, different bytes; PDF/A unaffected, XMP stays plain). Default false.", + "type": "boolean" +} - added
Input schema / properties / creationDateAdded value: +{ + "description": "ISO-8601 instant for /CreationDate (+ XMP). Pin it for byte-identical output across calls (same host TZ); omitted = wall clock, so every call differs.", + "format": "date-time", + "type": "string" +} - added
Input schema / properties / dataLabelsAdded value: +{ + "description": "Per-point value labels: true for defaults, or an object to format them.", + "oneOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "decimals": { + "maximum": 6, + "minimum": 0, + "type": "integer" + }, + "prefix": { + "maxLength": 16, + "type": "string" + }, + "suffix": { + "maxLength": 16, + "type": "string" + } + }, + "type": "object" + } + ] +} - added
Input schema / properties / debugAdded value: +{ + "description": "Draw margin / block / cell guide rectangles (unmarked content — not for PDF/UA output). Geometry unchanged. Default false.", + "type": "boolean" +} - added
Input schema / properties / embedFontsAdded value: +{ + "default": false, + "description": "Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A claim (ISO 19005 §6.2.11.4.1) and for strict=true; adds ~0.3 MiB.", + "type": "boolean" +} - added
Input schema / properties / encryptAdded value: +{ + "additionalProperties": false, + "description": "Encrypt at build time (AES-128 default / AES-256) and KEEP the AcroForm — unlike encrypt_pdf, which rebuilds the page tree. Exclusive with pdfA. Randomised output, never cached.", + "properties": { + "algorithm": { + "default": "aes128", + "description": "aes128 (V4/R4, widest compatibility) or aes256 (V5/R6).", + "enum": [ + "aes128", + "aes256" + ], + "type": "string" + }, + "ownerPassword": { + "description": "Owner password (full access).", + "maxLength": 4096, + "minLength": 1, + "type": "string" + }, + "permissions": { + "additionalProperties": false, + "description": "Permission flags; each defaults to allowed.", + "properties": { + "copy": { + "type": "boolean" + }, + "extractText": { + "type": "boolean" + }, + "modify": { + "type": "boolean" + }, + "print": { + "type": "boolean" + } + }, + "type": "object" + }, + "userPassword": { + "description": "Open password; omitted/empty = opens without a prompt.", + "maxLength": 4096, + "type": "string" + } + }, + "required": [ + "ownerPassword" + ], + "type": "object" +} - added
Input schema / properties / footerTemplateAdded value: +{ + "additionalProperties": false, + "description": "Running footer on every page. Replaces the default footer: footerText is then ignored and page numbers appear only via {page}/{pages}.", + "properties": { + "center": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "color": { + "description": "Hex colour.", + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + "fontSize": { + "description": "Default 7.", + "maximum": 14, + "minimum": 6, + "type": "number" + }, + "left": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "right": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / headerTemplateAdded value: +{ + "additionalProperties": false, + "description": "Running header on every page (left / center / right zones); reserves 15 pt.", + "properties": { + "center": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "color": { + "description": "Hex colour.", + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + "fontSize": { + "description": "Default 7.", + "maximum": 14, + "minimum": 6, + "type": "number" + }, + "left": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "right": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / includeDiagnosticsAdded value: +{ + "default": false, + "description": "Return the PDF/A diagnostics raised while building as `diagnostics[]` (possibly empty).", + "type": "boolean" +} - added
Input schema / properties / labelRotationAdded value: +{ + "description": "Rotate category labels counter-clockwise by this many degrees (disables the automatic stride).", + "maximum": 90, + "minimum": 0, + "type": "number" +} - added
Input schema / properties / labelStrideAdded value: +{ + "description": "Draw every Nth category label. Default: automatic (measured non-overlap); 1 draws every label.", + "maximum": 1000, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / marginsAdded value: +{ + "additionalProperties": false, + "description": "Margins in points, all four required (0–200). Default 45 / 36 / 35 / 36.", + "properties": { + "bottom": { + "maximum": 200, + "minimum": 0, + "type": "number" + }, + "left": { + "maximum": 200, + "minimum": 0, + "type": "number" + }, + "right": { + "maximum": 200, + "minimum": 0, + "type": "number" + }, + "top": { + "maximum": 200, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "top", + "right", + "bottom", + "left" + ], + "type": "object" +} - added
Input schema / properties / metadataAdded value: +{ + "additionalProperties": false, + "description": "/Info (+ XMP under PDF/A): author, subject, keywords, /Trapped.", + "properties": { + "author": { + "maxLength": 500, + "type": "string" + }, + "keywords": { + "maxLength": 1000, + "type": "string" + }, + "subject": { + "maxLength": 1000, + "type": "string" + }, + "trapped": { + "description": "/Trapped print flag.", + "enum": [ + "True", + "False", + "Unknown" + ], + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / outputIntentAdded value: +{ + "additionalProperties": false, + "description": "Custom PDF/A OutputIntent: an RGB ICC profile + condition strings replacing the built-in sRGB intent (CMYK rejected).", + "properties": { + "iccProfileBase64": { + "description": "ICC profile bytes, base64 (RGB, ≤ 8 MiB).", + "maxLength": 11000000, + "minLength": 1, + "type": "string" + }, + "info": { + "maxLength": 500, + "type": "string" + }, + "outputCondition": { + "maxLength": 200, + "type": "string" + }, + "outputConditionIdentifier": { + "description": "e.g. \"sRGB IEC61966-2.1\".", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "registryName": { + "description": "Default \"http://www.color.org\".", + "maxLength": 200, + "type": "string" + } + }, + "required": [ + "iccProfileBase64", + "outputConditionIdentifier" + ], + "type": "object" +} - added
Input schema / properties / pageSizeAdded value: +{ + "description": "Portrait page preset (points): A4 595.28×841.89 (default), Letter 612×792, Legal 612×1008, A3 841.89×1190.55, Tabloid 792×1224. print.* boxes must fit it.", + "enum": [ + "A4", + "Letter", + "Legal", + "A3", + "Tabloid" + ], + "type": "string" +} - changed
Input schema / properties / pdfA / descriptionPrevious value: -"Optional PDF/A conformance level (powered by pdfnative v1.2). Use 'pdfa1b' for archival of simple text+images, 'pdfa2b'/'pdfa2u' for richer content (2u guarantees Unicode mapping), 'pdfa3b' when embedding source attachments (Factur-X / ZUGFeRD). Mutually exclusive with PDF encryption. See docs/guides/PDFA.md."New value: +"PDF/A level: pdfa1b (simple text+images), pdfa2b/pdfa2u (richer; 2u = Unicode mapping), pdfa3b (attachments / Factur-X). Pair with embedFonts=true for a valid claim. Exclusive with encryption. See docs/guides/PDFA.md." - added
Input schema / properties / printAdded value: +{ + "additionalProperties": false, + "description": "Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b). See docs/guides/PRINT.md.", + "properties": { + "artBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "bleed": { + "description": "Bleed in points (8.5 = 3 mm); sets TrimBox = MediaBox inset. Exclusive with trimBox.", + "exclusiveMinimum": 0, + "maximum": 200, + "type": "number" + }, + "bleedBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "cropBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "marks": { + "description": "Printer's marks (needs bleed or trimBox): true for defaults, or an object.", + "oneOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "crop": { + "description": "Corner crop (trim) marks. Default true.", + "type": "boolean" + }, + "length": { + "description": "Mark length in points. Default 14.", + "maximum": 100, + "minimum": 1, + "type": "number" + }, + "offset": { + "description": "Gap between TrimBox and marks in points. Default 5.", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "registration": { + "description": "Edge-midpoint registration targets. Default true.", + "type": "boolean" + }, + "weight": { + "description": "Stroke width in points. Default 0.25.", + "maximum": 5, + "minimum": 0.05, + "type": "number" + } + }, + "type": "object" + } + ] + }, + "trimBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "userUnit": { + "description": "/UserUnit (multiples of 1/72 in) for pages over 14400 pt. Rejected under pdfa1b.", + "maximum": 75000, + "minimum": 1, + "type": "number" + } + }, + "type": "object" +} - added
Input schema / properties / series / items / properties / xValuesAdded value: +{ + "description": "Per-point x positions (same length as values) for scatter charts and for line/area charts with xAxis.type 'linear' or 'time'.", + "items": { + "description": "Positional x value: a number (linear axis) or an ISO-8601 date / epoch milliseconds (time axis).", + "maxLength": 64, + "type": [ + "number", + "string" + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" +} - added
Input schema / properties / series / items / properties / yAxisAdded value: +{ + "description": "Bind the series to the left (default) or the secondary right value axis (cartesian charts only; configure its range with 'axis2').", + "enum": [ + "left", + "right" + ], + "type": "string" +} - added
Input schema / properties / strictAdded value: +{ + "default": false, + "description": "Fail with PDF_A_COMPLIANCE_VIOLATION instead of producing a non-conformant PDF/A file (e.g. PDFA_NO_FONT_ENTRIES without embedFonts). Pair with embedFonts=true.", + "type": "boolean" +} - added
Input schema / properties / xAxisAdded value: +{ + "additionalProperties": false, + "description": "Horizontal axis. 'category' (default) positions points by index; 'linear' / 'time' position them by series xValues (line/area/scatter only). Time ticks are UTC-deterministic.", + "properties": { + "grid": { + "description": "Draw vertical gridlines.", + "type": "boolean" + }, + "max": { + "description": "Axis maximum (number, or ISO-8601 / epoch ms for time axes).", + "maxLength": 64, + "type": [ + "number", + "string" + ] + }, + "min": { + "description": "Axis minimum (number, or ISO-8601 / epoch ms for time axes).", + "maxLength": 64, + "type": [ + "number", + "string" + ] + }, + "ticks": { + "maximum": 20, + "minimum": 2, + "type": "integer" + }, + "type": { + "enum": [ + "category", + "linear", + "time" + ], + "type": "string" + } + }, + "type": "object" +} - changed
Output schema / descriptionPrevious value: -"Structured result of a PDF-producing tool. In base64 mode the PDF bytes are delivered out-of-band as an embedded `resource` content block (data: URI), NOT duplicated here, to keep responses token-frugal. In file mode `filePath` is the sandboxed absolute path."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`." - added
Output schema / properties / diagnosticsAdded value: +{ + "description": "PDF/A diagnostics (when includeDiagnostics=true).", + "items": { + "additionalProperties": false, + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "severity": { + "enum": [ + "warning" + ], + "type": "string" + } + }, + "required": [ + "code", + "message", + "severity" + ], + "type": "object" + }, + "type": "array" +} - changed
Output schema / properties / filePath / descriptionPrevious value: -"Absolute sandboxed file path (when mode='file')."New value: +"Sandboxed absolute path (file mode)." - added
Output schema / properties / summaryAdded value: +{ + "additionalProperties": true, + "description": "Tool-specific summary, when produced.", + "type": "object" +}
- Changed
add_form27 fields changed- added
Input schema / properties / compressAdded value: +{ + "description": "FlateDecode the streams (smaller file, different bytes; PDF/A unaffected, XMP stays plain). Default false.", + "type": "boolean" +} - added
Input schema / properties / creationDateAdded value: +{ + "description": "ISO-8601 instant for /CreationDate (+ XMP). Pin it for byte-identical output across calls (same host TZ); omitted = wall clock, so every call differs.", + "format": "date-time", + "type": "string" +} - added
Input schema / properties / debugAdded value: +{ + "description": "Draw margin / block / cell guide rectangles (unmarked content — not for PDF/UA output). Geometry unchanged. Default false.", + "type": "boolean" +} - added
Input schema / properties / embedFontsAdded value: +{ + "default": false, + "description": "Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A claim (ISO 19005 §6.2.11.4.1) and for strict=true; adds ~0.3 MiB.", + "type": "boolean" +} - added
Input schema / properties / encryptAdded value: +{ + "additionalProperties": false, + "description": "Encrypt at build time (AES-128 default / AES-256) and KEEP the AcroForm — unlike encrypt_pdf, which rebuilds the page tree. Exclusive with pdfA. Randomised output, never cached.", + "properties": { + "algorithm": { + "default": "aes128", + "description": "aes128 (V4/R4, widest compatibility) or aes256 (V5/R6).", + "enum": [ + "aes128", + "aes256" + ], + "type": "string" + }, + "ownerPassword": { + "description": "Owner password (full access).", + "maxLength": 4096, + "minLength": 1, + "type": "string" + }, + "permissions": { + "additionalProperties": false, + "description": "Permission flags; each defaults to allowed.", + "properties": { + "copy": { + "type": "boolean" + }, + "extractText": { + "type": "boolean" + }, + "modify": { + "type": "boolean" + }, + "print": { + "type": "boolean" + } + }, + "type": "object" + }, + "userPassword": { + "description": "Open password; omitted/empty = opens without a prompt.", + "maxLength": 4096, + "type": "string" + } + }, + "required": [ + "ownerPassword" + ], + "type": "object" +} - changed
Input schema / properties / fields / items / properties / checked / descriptionPrevious value: -"Initial checked state for checkbox fields."New value: +"Initial checked state for checkbox / radio fields." - changed
Input schema / properties / fields / items / properties / fieldType / descriptionPrevious value: -"Type of form control to render."New value: +"Type of form control to render. Radio fields sharing a name form one radio group." - changed
Input schema / properties / fields / items / properties / fieldType / enumPrevious value: -[ - "text", - "textarea", - "checkbox", - "radio", - "dropdown" -]New value: +[ + "text", + "textarea", + "checkbox", + "radio", + "dropdown", + "listbox" +] - changed
Input schema / properties / fields / items / properties / height / descriptionPrevious value: -"Field height in points (optional)."New value: +"Field height in points (default depends on the type)." - changed
Input schema / properties / fields / items / properties / name / descriptionPrevious value: -"Unique field name used as the PDF annotation identifier."New value: +"Unique field name used as the PDF annotation identifier (/T)." - changed
Input schema / properties / fields / items / properties / options / descriptionPrevious value: -"Choices for dropdown or radio fields."New value: +"Choices for dropdown, listbox or radio fields." - added
Input schema / properties / fields / items / properties / placeholderAdded value: +{ + "description": "Hint text shown while the field is empty.", + "maxLength": 200, + "type": "string" +} - changed
Input schema / properties / fields / items / properties / width / descriptionPrevious value: -"Field width in points (optional)."New value: +"Field width in points (default: full content width)." - added
Input schema / properties / footerTemplateAdded value: +{ + "additionalProperties": false, + "description": "Running footer on every page. Replaces the default footer: footerText is then ignored and page numbers appear only via {page}/{pages}.", + "properties": { + "center": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "color": { + "description": "Hex colour.", + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + "fontSize": { + "description": "Default 7.", + "maximum": 14, + "minimum": 6, + "type": "number" + }, + "left": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "right": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / headerTemplateAdded value: +{ + "additionalProperties": false, + "description": "Running header on every page (left / center / right zones); reserves 15 pt.", + "properties": { + "center": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "color": { + "description": "Hex colour.", + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + "fontSize": { + "description": "Default 7.", + "maximum": 14, + "minimum": 6, + "type": "number" + }, + "left": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "right": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / includeDiagnosticsAdded value: +{ + "default": false, + "description": "Return the PDF/A diagnostics raised while building as `diagnostics[]` (possibly empty).", + "type": "boolean" +} - added
Input schema / properties / marginsAdded value: +{ + "additionalProperties": false, + "description": "Margins in points, all four required (0–200). Default 45 / 36 / 35 / 36.", + "properties": { + "bottom": { + "maximum": 200, + "minimum": 0, + "type": "number" + }, + "left": { + "maximum": 200, + "minimum": 0, + "type": "number" + }, + "right": { + "maximum": 200, + "minimum": 0, + "type": "number" + }, + "top": { + "maximum": 200, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "top", + "right", + "bottom", + "left" + ], + "type": "object" +} - added
Input schema / properties / metadataAdded value: +{ + "additionalProperties": false, + "description": "/Info (+ XMP under PDF/A): author, subject, keywords, /Trapped.", + "properties": { + "author": { + "maxLength": 500, + "type": "string" + }, + "keywords": { + "maxLength": 1000, + "type": "string" + }, + "subject": { + "maxLength": 1000, + "type": "string" + }, + "trapped": { + "description": "/Trapped print flag.", + "enum": [ + "True", + "False", + "Unknown" + ], + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / outputIntentAdded value: +{ + "additionalProperties": false, + "description": "Custom PDF/A OutputIntent: an RGB ICC profile + condition strings replacing the built-in sRGB intent (CMYK rejected).", + "properties": { + "iccProfileBase64": { + "description": "ICC profile bytes, base64 (RGB, ≤ 8 MiB).", + "maxLength": 11000000, + "minLength": 1, + "type": "string" + }, + "info": { + "maxLength": 500, + "type": "string" + }, + "outputCondition": { + "maxLength": 200, + "type": "string" + }, + "outputConditionIdentifier": { + "description": "e.g. \"sRGB IEC61966-2.1\".", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "registryName": { + "description": "Default \"http://www.color.org\".", + "maxLength": 200, + "type": "string" + } + }, + "required": [ + "iccProfileBase64", + "outputConditionIdentifier" + ], + "type": "object" +} - added
Input schema / properties / pageSizeAdded value: +{ + "description": "Portrait page preset (points): A4 595.28×841.89 (default), Letter 612×792, Legal 612×1008, A3 841.89×1190.55, Tabloid 792×1224. print.* boxes must fit it.", + "enum": [ + "A4", + "Letter", + "Legal", + "A3", + "Tabloid" + ], + "type": "string" +} - changed
Input schema / properties / pdfA / descriptionPrevious value: -"Optional PDF/A conformance level (powered by pdfnative v1.2). Use 'pdfa1b' for archival of simple text+images, 'pdfa2b'/'pdfa2u' for richer content (2u guarantees Unicode mapping), 'pdfa3b' when embedding source attachments (Factur-X / ZUGFeRD). Mutually exclusive with PDF encryption. See docs/guides/PDFA.md."New value: +"PDF/A level: pdfa1b (simple text+images), pdfa2b/pdfa2u (richer; 2u = Unicode mapping), pdfa3b (attachments / Factur-X). Pair with embedFonts=true for a valid claim. Exclusive with encryption. See docs/guides/PDFA.md." - added
Input schema / properties / printAdded value: +{ + "additionalProperties": false, + "description": "Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b). See docs/guides/PRINT.md.", + "properties": { + "artBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "bleed": { + "description": "Bleed in points (8.5 = 3 mm); sets TrimBox = MediaBox inset. Exclusive with trimBox.", + "exclusiveMinimum": 0, + "maximum": 200, + "type": "number" + }, + "bleedBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "cropBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "marks": { + "description": "Printer's marks (needs bleed or trimBox): true for defaults, or an object.", + "oneOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "crop": { + "description": "Corner crop (trim) marks. Default true.", + "type": "boolean" + }, + "length": { + "description": "Mark length in points. Default 14.", + "maximum": 100, + "minimum": 1, + "type": "number" + }, + "offset": { + "description": "Gap between TrimBox and marks in points. Default 5.", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "registration": { + "description": "Edge-midpoint registration targets. Default true.", + "type": "boolean" + }, + "weight": { + "description": "Stroke width in points. Default 0.25.", + "maximum": 5, + "minimum": 0.05, + "type": "number" + } + }, + "type": "object" + } + ] + }, + "trimBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "userUnit": { + "description": "/UserUnit (multiples of 1/72 in) for pages over 14400 pt. Rejected under pdfa1b.", + "maximum": 75000, + "minimum": 1, + "type": "number" + } + }, + "type": "object" +} - added
Input schema / properties / strictAdded value: +{ + "default": false, + "description": "Fail with PDF_A_COMPLIANCE_VIOLATION instead of producing a non-conformant PDF/A file (e.g. PDFA_NO_FONT_ENTRIES without embedFonts). Pair with embedFonts=true.", + "type": "boolean" +} - changed
Output schema / descriptionPrevious value: -"Structured result of a PDF-producing tool. In base64 mode the PDF bytes are delivered out-of-band as an embedded `resource` content block (data: URI), NOT duplicated here, to keep responses token-frugal. In file mode `filePath` is the sandboxed absolute path."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`." - added
Output schema / properties / diagnosticsAdded value: +{ + "description": "PDF/A diagnostics (when includeDiagnostics=true).", + "items": { + "additionalProperties": false, + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "severity": { + "enum": [ + "warning" + ], + "type": "string" + } + }, + "required": [ + "code", + "message", + "severity" + ], + "type": "object" + }, + "type": "array" +} - changed
Output schema / properties / filePath / descriptionPrevious value: -"Absolute sandboxed file path (when mode='file')."New value: +"Sandboxed absolute path (file mode)." - added
Output schema / properties / summaryAdded value: +{ + "additionalProperties": true, + "description": "Tool-specific summary, when produced.", + "type": "object" +}
- Changed
add_international_text27 fields changed- added
Input schema / properties / compressAdded value: +{ + "description": "FlateDecode the streams (smaller file, different bytes; PDF/A unaffected, XMP stays plain). Default false.", + "type": "boolean" +} - added
Input schema / properties / creationDateAdded value: +{ + "description": "ISO-8601 instant for /CreationDate (+ XMP). Pin it for byte-identical output across calls (same host TZ); omitted = wall clock, so every call differs.", + "format": "date-time", + "type": "string" +} - added
Input schema / properties / debugAdded value: +{ + "description": "Draw margin / block / cell guide rectangles (unmarked content — not for PDF/UA output). Geometry unchanged. Default false.", + "type": "boolean" +} - added
Input schema / properties / encryptAdded value: +{ + "additionalProperties": false, + "description": "Encrypt at build time (AES-128 default / AES-256) and KEEP the AcroForm — unlike encrypt_pdf, which rebuilds the page tree. Exclusive with pdfA. Randomised output, never cached.", + "properties": { + "algorithm": { + "default": "aes128", + "description": "aes128 (V4/R4, widest compatibility) or aes256 (V5/R6).", + "enum": [ + "aes128", + "aes256" + ], + "type": "string" + }, + "ownerPassword": { + "description": "Owner password (full access).", + "maxLength": 4096, + "minLength": 1, + "type": "string" + }, + "permissions": { + "additionalProperties": false, + "description": "Permission flags; each defaults to allowed.", + "properties": { + "copy": { + "type": "boolean" + }, + "extractText": { + "type": "boolean" + }, + "modify": { + "type": "boolean" + }, + "print": { + "type": "boolean" + } + }, + "type": "object" + }, + "userPassword": { + "description": "Open password; omitted/empty = opens without a prompt.", + "maxLength": 4096, + "type": "string" + } + }, + "required": [ + "ownerPassword" + ], + "type": "object" +} - added
Input schema / properties / footerTemplateAdded value: +{ + "additionalProperties": false, + "description": "Running footer on every page. Replaces the default footer: footerText is then ignored and page numbers appear only via {page}/{pages}.", + "properties": { + "center": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "color": { + "description": "Hex colour.", + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + "fontSize": { + "description": "Default 7.", + "maximum": 14, + "minimum": 6, + "type": "number" + }, + "left": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "right": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / headerTemplateAdded value: +{ + "additionalProperties": false, + "description": "Running header on every page (left / center / right zones); reserves 15 pt.", + "properties": { + "center": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "color": { + "description": "Hex colour.", + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + "fontSize": { + "description": "Default 7.", + "maximum": 14, + "minimum": 6, + "type": "number" + }, + "left": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "right": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / includeDiagnosticsAdded value: +{ + "default": false, + "description": "Return the PDF/A diagnostics raised while building as `diagnostics[]` (possibly empty).", + "type": "boolean" +} - added
Input schema / properties / lang / anyOfAdded value: +[ + { + "enum": [ + "ar", + "he", + "th", + "ja", + "zh", + "ko", + "el", + "hi", + "bn", + "ta", + "ru", + "ka", + "hy", + "tr", + "pl", + "vi", + "latin", + "te", + "si", + "bo", + "km", + "my", + "am", + "emoji", + "math" + ], + "type": "string" + }, + { + "items": { + "enum": [ + "ar", + "he", + "th", + "ja", + "zh", + "ko", + "el", + "hi", + "bn", + "ta", + "ru", + "ka", + "hy", + "tr", + "pl", + "vi", + "latin", + "te", + "si", + "bo", + "km", + "my", + "am", + "emoji", + "math" + ], + "type": "string" + }, + "maxItems": 25, + "minItems": 1, + "type": "array" + }, + { + "description": "Comma-separated list of supported codes.", + "maxLength": 80, + "minLength": 2, + "type": "string" + } +] - removed
Input schema / properties / lang / oneOfRemoved value: -[ - { - "enum": [ - "ar", - "he", - "th", - "ja", - "zh", - "ko", - "el", - "hi", - "bn", - "ta", - "ru", - "ka", - "hy", - "tr", - "pl", - "vi", - "latin", - "te", - "si", - "bo", - "km", - "my", - "am", - "emoji", - "math" - ], - "type": "string" - }, - { - "items": { - "enum": [ - "ar", - "he", - "th", - "ja", - "zh", - "ko", - "el", - "hi", - "bn", - "ta", - "ru", - "ka", - "hy", - "tr", - "pl", - "vi", - "latin", - "te", - "si", - "bo", - "km", - "my", - "am", - "emoji", - "math" - ], - "type": "string" - }, - "maxItems": 25, - "minItems": 1, - "type": "array" - }, - { - "description": "Comma-separated list of supported codes.", - "maxLength": 80, - "minLength": 2, - "type": "string" - } -] - added
Input schema / properties / marginsAdded value: +{ + "additionalProperties": false, + "description": "Margins in points, all four required (0–200). Default 45 / 36 / 35 / 36.", + "properties": { + "bottom": { + "maximum": 200, + "minimum": 0, + "type": "number" + }, + "left": { + "maximum": 200, + "minimum": 0, + "type": "number" + }, + "right": { + "maximum": 200, + "minimum": 0, + "type": "number" + }, + "top": { + "maximum": 200, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "top", + "right", + "bottom", + "left" + ], + "type": "object" +} - added
Input schema / properties / metadataAdded value: +{ + "additionalProperties": false, + "description": "/Info (+ XMP under PDF/A): author, subject, keywords, /Trapped.", + "properties": { + "author": { + "maxLength": 500, + "type": "string" + }, + "keywords": { + "maxLength": 1000, + "type": "string" + }, + "subject": { + "maxLength": 1000, + "type": "string" + }, + "trapped": { + "description": "/Trapped print flag.", + "enum": [ + "True", + "False", + "Unknown" + ], + "type": "string" + } + }, + "type": "object" +} - changed
Input schema / properties / normalize / descriptionPrevious value: -"Unicode normalization form applied before shaping. Defaults to 'NFC' (recommended for international scripts: composes decomposed sequences for the widest glyph coverage). Override with 'NFD'/'NFKC'/'NFKD' only for specialised needs."New value: +"Unicode normalization before shaping. Default 'NFC' (widest glyph coverage); NFD/NFKC/NFKD or false for special needs." - added
Input schema / properties / outputIntentAdded value: +{ + "additionalProperties": false, + "description": "Custom PDF/A OutputIntent: an RGB ICC profile + condition strings replacing the built-in sRGB intent (CMYK rejected).", + "properties": { + "iccProfileBase64": { + "description": "ICC profile bytes, base64 (RGB, ≤ 8 MiB).", + "maxLength": 11000000, + "minLength": 1, + "type": "string" + }, + "info": { + "maxLength": 500, + "type": "string" + }, + "outputCondition": { + "maxLength": 200, + "type": "string" + }, + "outputConditionIdentifier": { + "description": "e.g. \"sRGB IEC61966-2.1\".", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "registryName": { + "description": "Default \"http://www.color.org\".", + "maxLength": 200, + "type": "string" + } + }, + "required": [ + "iccProfileBase64", + "outputConditionIdentifier" + ], + "type": "object" +} - added
Input schema / properties / outputMode / descriptionAdded value: +"'base64' (default) returns the PDF inline; 'file' writes it inside the PDFNATIVE_MCP_OUTPUT_DIR sandbox (SECURITY_VIOLATION when the sandbox is not configured)." - added
Input schema / properties / outputPath / descriptionAdded value: +"Required when outputMode='file'. Relative path inside the sandbox; must end with .pdf (no absolute paths, no '..')." - added
Input schema / properties / pageSizeAdded value: +{ + "description": "Portrait page preset (points): A4 595.28×841.89 (default), Letter 612×792, Legal 612×1008, A3 841.89×1190.55, Tabloid 792×1224. print.* boxes must fit it.", + "enum": [ + "A4", + "Letter", + "Legal", + "A3", + "Tabloid" + ], + "type": "string" +} - changed
Input schema / properties / pdfA / descriptionPrevious value: -"Optional PDF/A conformance level. When set, Tagged PDF + sRGB OutputIntent + XMP metadata are emitted; the 'latin' Noto Sans fallback is auto-registered for non-WinAnsi Latin (ISO 19005-1 §6.3.4). See docs/guides/PDFA.md for the full authoring guide."New value: +"PDF/A level (Tagged PDF + sRGB OutputIntent + XMP). Fonts are embedded here, so the claim is valid as-is. See docs/guides/PDFA.md." - added
Input schema / properties / printAdded value: +{ + "additionalProperties": false, + "description": "Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b). See docs/guides/PRINT.md.", + "properties": { + "artBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "bleed": { + "description": "Bleed in points (8.5 = 3 mm); sets TrimBox = MediaBox inset. Exclusive with trimBox.", + "exclusiveMinimum": 0, + "maximum": 200, + "type": "number" + }, + "bleedBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "cropBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "marks": { + "description": "Printer's marks (needs bleed or trimBox): true for defaults, or an object.", + "oneOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "crop": { + "description": "Corner crop (trim) marks. Default true.", + "type": "boolean" + }, + "length": { + "description": "Mark length in points. Default 14.", + "maximum": 100, + "minimum": 1, + "type": "number" + }, + "offset": { + "description": "Gap between TrimBox and marks in points. Default 5.", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "registration": { + "description": "Edge-midpoint registration targets. Default true.", + "type": "boolean" + }, + "weight": { + "description": "Stroke width in points. Default 0.25.", + "maximum": 5, + "minimum": 0.05, + "type": "number" + } + }, + "type": "object" + } + ] + }, + "trimBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "userUnit": { + "description": "/UserUnit (multiples of 1/72 in) for pages over 14400 pt. Rejected under pdfa1b.", + "maximum": 75000, + "minimum": 1, + "type": "number" + } + }, + "type": "object" +} - added
Input schema / properties / strictAdded value: +{ + "default": false, + "description": "Fail with PDF_A_COMPLIANCE_VIOLATION instead of producing a non-conformant PDF/A file (e.g. PDFA_NO_FONT_ENTRIES without embedFonts). Pair with embedFonts=true.", + "type": "boolean" +} - added
Input schema / properties / viewerPreferences / properties / duplexAdded value: +{ + "description": "Print-dialog paper handling default (/Duplex): single-sided or double-sided flipping on the short/long edge.", + "enum": [ + "simplex", + "duplexFlipShortEdge", + "duplexFlipLongEdge" + ], + "type": "string" +} - added
Input schema / properties / viewerPreferences / properties / numCopiesAdded value: +{ + "description": "Default number of copies for the Print dialog (/NumCopies; viewers honour 2-5 per ISO 32000 Table 150).", + "maximum": 1000, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / viewerPreferences / properties / pickTrayByPDFSizeAdded value: +{ + "description": "Ask the printer to pick the input tray from the PDF page size (/PickTrayByPDFSize).", + "type": "boolean" +} - added
Input schema / properties / viewerPreferences / properties / printPageRangeAdded value: +{ + "description": "Default page ranges for the Print dialog (/PrintPageRange) as inclusive 1-based [first, last] pairs, e.g. [[1, 4], [7, 7]].", + "items": { + "items": { + "minimum": 1, + "type": "integer" + }, + "maxItems": 2, + "minItems": 2, + "type": "array" + }, + "maxItems": 100, + "type": "array" +} - changed
Output schema / descriptionPrevious value: -"Structured result of a PDF-producing tool. In base64 mode the PDF bytes are delivered out-of-band as an embedded `resource` content block (data: URI), NOT duplicated here, to keep responses token-frugal. In file mode `filePath` is the sandboxed absolute path."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`." - added
Output schema / properties / diagnosticsAdded value: +{ + "description": "PDF/A diagnostics (when includeDiagnostics=true).", + "items": { + "additionalProperties": false, + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "severity": { + "enum": [ + "warning" + ], + "type": "string" + } + }, + "required": [ + "code", + "message", + "severity" + ], + "type": "object" + }, + "type": "array" +} - changed
Output schema / properties / filePath / descriptionPrevious value: -"Absolute sandboxed file path (when mode='file')."New value: +"Sandboxed absolute path (file mode)." - added
Output schema / properties / summaryAdded value: +{ + "additionalProperties": true, + "description": "Tool-specific summary, when produced.", + "type": "object" +}
- Added
add_ltv - Changed
add_table42 fields changed- changed
Input schema / properties / autoFitColumns / descriptionPrevious value: -"When true, column widths auto-fit content (pdfnative v1.1). Switches the backend to buildDocumentPDFBytes; byte output differs from the default path."New value: +"Auto-fit column widths to content. Output bytes then depend on text metrics (not byte-deterministic across content changes)." - changed
Input schema / properties / caption / descriptionPrevious value: -"Caption rendered above the table (and emitted as /Caption structure element in tagged/PDF/A mode). pdfnative v1.2."New value: +"Caption rendered above the table (tagged as /Caption under PDF/A)." - changed
Input schema / properties / cellBorders / descriptionPrevious value: -"Per-cell vector borders (pdfnative v1.4). Switches the backend to buildDocumentPDFBytes. Choose individual sides or `all`."New value: +"Per-cell vector borders (pure strokes, PDF/A-safe). Choose individual sides or `all`." - changed
Input schema / properties / cellPadding / descriptionPrevious value: -"Horizontal cell padding in points applied to both insets (default 3). pdfnative v1.2."New value: +"Horizontal cell padding in points (default 3)." - changed
Input schema / properties / cellVAlign / descriptionPrevious value: -"Vertical alignment of cell content (pdfnative v1.4). Switches the backend to buildDocumentPDFBytes."New value: +"Vertical alignment of cell content." - changed
Input schema / properties / clipCells / descriptionPrevious value: -"When true, cell contents are clipped to column bounds via PDF clip-path operators (pdfnative v1.1). Recommended for PDF/A and visual safety. Switches the backend to buildDocumentPDFBytes."New value: +"Clip cell contents to the column bounds (PDF clip operators). Recommended for PDF/A and visual safety." - added
Input schema / properties / compressAdded value: +{ + "description": "FlateDecode the streams (smaller file, different bytes; PDF/A unaffected, XMP stays plain). Default false.", + "type": "boolean" +} - added
Input schema / properties / creationDateAdded value: +{ + "description": "ISO-8601 instant for /CreationDate (+ XMP). Pin it for byte-identical output across calls (same host TZ); omitted = wall clock, so every call differs.", + "format": "date-time", + "type": "string" +} - added
Input schema / properties / debugAdded value: +{ + "description": "Draw margin / block / cell guide rectangles (unmarked content — not for PDF/UA output). Geometry unchanged. Default false.", + "type": "boolean" +} - added
Input schema / properties / embedFontsAdded value: +{ + "default": false, + "description": "Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A claim (ISO 19005 §6.2.11.4.1) and for strict=true; adds ~0.3 MiB.", + "type": "boolean" +} - added
Input schema / properties / encryptAdded value: +{ + "additionalProperties": false, + "description": "Encrypt at build time (AES-128 default / AES-256) and KEEP the AcroForm — unlike encrypt_pdf, which rebuilds the page tree. Exclusive with pdfA. Randomised output, never cached.", + "properties": { + "algorithm": { + "default": "aes128", + "description": "aes128 (V4/R4, widest compatibility) or aes256 (V5/R6).", + "enum": [ + "aes128", + "aes256" + ], + "type": "string" + }, + "ownerPassword": { + "description": "Owner password (full access).", + "maxLength": 4096, + "minLength": 1, + "type": "string" + }, + "permissions": { + "additionalProperties": false, + "description": "Permission flags; each defaults to allowed.", + "properties": { + "copy": { + "type": "boolean" + }, + "extractText": { + "type": "boolean" + }, + "modify": { + "type": "boolean" + }, + "print": { + "type": "boolean" + } + }, + "type": "object" + }, + "userPassword": { + "description": "Open password; omitted/empty = opens without a prompt.", + "maxLength": 4096, + "type": "string" + } + }, + "required": [ + "ownerPassword" + ], + "type": "object" +} - added
Input schema / properties / footerTemplateAdded value: +{ + "additionalProperties": false, + "description": "Running footer on every page. Replaces the default footer: footerText is then ignored and page numbers appear only via {page}/{pages}.", + "properties": { + "center": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "color": { + "description": "Hex colour.", + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + "fontSize": { + "description": "Default 7.", + "maximum": 14, + "minimum": 6, + "type": "number" + }, + "left": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "right": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / headerTemplateAdded value: +{ + "additionalProperties": false, + "description": "Running header on every page (left / center / right zones); reserves 15 pt.", + "properties": { + "center": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "color": { + "description": "Hex colour.", + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + "fontSize": { + "description": "Default 7.", + "maximum": 14, + "minimum": 6, + "type": "number" + }, + "left": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "right": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / includeDiagnosticsAdded value: +{ + "default": false, + "description": "Return the PDF/A diagnostics raised while building as `diagnostics[]` (possibly empty).", + "type": "boolean" +} - added
Input schema / properties / marginsAdded value: +{ + "additionalProperties": false, + "description": "Margins in points, all four required (0–200). Default 45 / 36 / 35 / 36.", + "properties": { + "bottom": { + "maximum": 200, + "minimum": 0, + "type": "number" + }, + "left": { + "maximum": 200, + "minimum": 0, + "type": "number" + }, + "right": { + "maximum": 200, + "minimum": 0, + "type": "number" + }, + "top": { + "maximum": 200, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "top", + "right", + "bottom", + "left" + ], + "type": "object" +} - added
Input schema / properties / metadataAdded value: +{ + "additionalProperties": false, + "description": "/Info (+ XMP under PDF/A): author, subject, keywords, /Trapped.", + "properties": { + "author": { + "maxLength": 500, + "type": "string" + }, + "keywords": { + "maxLength": 1000, + "type": "string" + }, + "subject": { + "maxLength": 1000, + "type": "string" + }, + "trapped": { + "description": "/Trapped print flag.", + "enum": [ + "True", + "False", + "Unknown" + ], + "type": "string" + } + }, + "type": "object" +} - changed
Input schema / properties / minRowHeight / descriptionPrevious value: -"Minimum row height in points (default 12). pdfnative v1.2."New value: +"Minimum row height in points (default 12)." - added
Input schema / properties / outputIntentAdded value: +{ + "additionalProperties": false, + "description": "Custom PDF/A OutputIntent: an RGB ICC profile + condition strings replacing the built-in sRGB intent (CMYK rejected).", + "properties": { + "iccProfileBase64": { + "description": "ICC profile bytes, base64 (RGB, ≤ 8 MiB).", + "maxLength": 11000000, + "minLength": 1, + "type": "string" + }, + "info": { + "maxLength": 500, + "type": "string" + }, + "outputCondition": { + "maxLength": 200, + "type": "string" + }, + "outputConditionIdentifier": { + "description": "e.g. \"sRGB IEC61966-2.1\".", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "registryName": { + "description": "Default \"http://www.color.org\".", + "maxLength": 200, + "type": "string" + } + }, + "required": [ + "iccProfileBase64", + "outputConditionIdentifier" + ], + "type": "object" +} - added
Input schema / properties / pageSizeAdded value: +{ + "description": "Portrait page preset (points): A4 595.28×841.89 (default), Letter 612×792, Legal 612×1008, A3 841.89×1190.55, Tabloid 792×1224. print.* boxes must fit it.", + "enum": [ + "A4", + "Letter", + "Legal", + "A3", + "Tabloid" + ], + "type": "string" +} - changed
Input schema / properties / pdfA / descriptionPrevious value: -"Optional PDF/A conformance level (powered by pdfnative v1.2). Use 'pdfa1b' for archival of simple text+images, 'pdfa2b'/'pdfa2u' for richer content (2u guarantees Unicode mapping), 'pdfa3b' when embedding source attachments (Factur-X / ZUGFeRD). Mutually exclusive with PDF encryption. See docs/guides/PDFA.md."New value: +"PDF/A level: pdfa1b (simple text+images), pdfa2b/pdfa2u (richer; 2u = Unicode mapping), pdfa3b (attachments / Factur-X). Pair with embedFonts=true for a valid claim. Exclusive with encryption. See docs/guides/PDFA.md." - added
Input schema / properties / printAdded value: +{ + "additionalProperties": false, + "description": "Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b). See docs/guides/PRINT.md.", + "properties": { + "artBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "bleed": { + "description": "Bleed in points (8.5 = 3 mm); sets TrimBox = MediaBox inset. Exclusive with trimBox.", + "exclusiveMinimum": 0, + "maximum": 200, + "type": "number" + }, + "bleedBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "cropBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "marks": { + "description": "Printer's marks (needs bleed or trimBox): true for defaults, or an object.", + "oneOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "crop": { + "description": "Corner crop (trim) marks. Default true.", + "type": "boolean" + }, + "length": { + "description": "Mark length in points. Default 14.", + "maximum": 100, + "minimum": 1, + "type": "number" + }, + "offset": { + "description": "Gap between TrimBox and marks in points. Default 5.", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "registration": { + "description": "Edge-midpoint registration targets. Default true.", + "type": "boolean" + }, + "weight": { + "description": "Stroke width in points. Default 0.25.", + "maximum": 5, + "minimum": 0.05, + "type": "number" + } + }, + "type": "object" + } + ] + }, + "trimBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "userUnit": { + "description": "/UserUnit (multiples of 1/72 in) for pages over 14400 pt. Rejected under pdfa1b.", + "maximum": 75000, + "minimum": 1, + "type": "number" + } + }, + "type": "object" +} - changed
Input schema / properties / repeatHeader / descriptionPrevious value: -"Repeat the header row on every continuation page (pdfnative v1.2). Default true."New value: +"Repeat the header row on every continuation page (default true)." - added
Input schema / properties / strictAdded value: +{ + "default": false, + "description": "Fail with PDF_A_COMPLIANCE_VIOLATION instead of producing a non-conformant PDF/A file (e.g. PDFA_NO_FONT_ENTRIES without embedFonts). Pair with embedFonts=true.", + "type": "boolean" +} - added
Input schema / properties / viewerPreferences / properties / duplexAdded value: +{ + "description": "Print-dialog paper handling default (/Duplex): single-sided or double-sided flipping on the short/long edge.", + "enum": [ + "simplex", + "duplexFlipShortEdge", + "duplexFlipLongEdge" + ], + "type": "string" +} - added
Input schema / properties / viewerPreferences / properties / numCopiesAdded value: +{ + "description": "Default number of copies for the Print dialog (/NumCopies; viewers honour 2-5 per ISO 32000 Table 150).", + "maximum": 1000, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / viewerPreferences / properties / pickTrayByPDFSizeAdded value: +{ + "description": "Ask the printer to pick the input tray from the PDF page size (/PickTrayByPDFSize).", + "type": "boolean" +} - added
Input schema / properties / viewerPreferences / properties / printPageRangeAdded value: +{ + "description": "Default page ranges for the Print dialog (/PrintPageRange) as inclusive 1-based [first, last] pairs, e.g. [[1, 4], [7, 7]].", + "items": { + "items": { + "minimum": 1, + "type": "integer" + }, + "maxItems": 2, + "minItems": 2, + "type": "array" + }, + "maxItems": 100, + "type": "array" +} - changed
Input schema / properties / watermark / descriptionPrevious value: -"Optional semi-transparent text watermark rendered on every page (e.g. 'DRAFT', 'CONFIDENTIAL'). Text only in this version. opacity < 1.0 is rejected under pdfA='pdfa1b' (ISO 19005-1 forbids transparency)."New value: +"Optional semi-transparent watermark rendered centred on every page: `text` (e.g. 'DRAFT'), `image` (JPEG/PNG), or both combined. At least one of text / image is required. opacity < 1.0 (text or image, including the defaults) is rejected under pdfA='pdfa1b' (ISO 19005-1 forbids transparency)." - changed
Input schema / properties / watermark / properties / angle / descriptionPrevious value: -"Rotation in degrees (counterclockwise). Default -45."New value: +"Text rotation in degrees (counterclockwise). Default -45." - changed
Input schema / properties / watermark / properties / color / descriptionPrevious value: -"RGB colour as a [r, g, b] triple in the 0.0–1.0 range. Default light gray [0.75, 0.75, 0.75]."New value: +"Text RGB colour as a [r, g, b] triple in the 0.0–1.0 range. Default light gray [0.75, 0.75, 0.75]." - changed
Input schema / properties / watermark / properties / fontSize / descriptionPrevious value: -"Font size in points. Default 60, auto-fit to the page."New value: +"Text font size in points. Default 60, auto-fit to the page." - added
Input schema / properties / watermark / properties / imageAdded value: +{ + "additionalProperties": false, + "description": "Image watermark (JPEG or PNG) centred on every page, optionally combined with `text`. Bytes are validated against the JPEG/PNG magic numbers; mimeType must match.", + "properties": { + "height": { + "description": "Display height in points (default: from the image pixel size).", + "exclusiveMinimum": 0, + "maximum": 14400, + "type": "number" + }, + "imageBase64": { + "description": "Base64-encoded JPEG or 8-bit opaque PNG bytes (max 8 MiB decoded; alpha-channel, palette and interlaced PNGs are rejected with a remedy). Plain base64, no data: URI prefix.", + "maxLength": 12000000, + "minLength": 4, + "type": "string" + }, + "mimeType": { + "description": "'image/jpeg' or 'image/png' — must match the actual bytes.", + "enum": [ + "image/jpeg", + "image/png" + ], + "type": "string" + }, + "opacity": { + "description": "Image opacity 0.0–1.0. Default 0.10.", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "width": { + "description": "Display width in points (default: from the image pixel size).", + "exclusiveMinimum": 0, + "maximum": 14400, + "type": "number" + } + }, + "required": [ + "imageBase64", + "mimeType" + ], + "type": "object" +} - changed
Input schema / properties / watermark / properties / opacity / descriptionPrevious value: -"Opacity 0.0–1.0. Default 0.15."New value: +"Text opacity 0.0–1.0. Default 0.15. (Image opacity is image.opacity.)" - changed
Input schema / properties / watermark / properties / position / descriptionPrevious value: -"'background' (behind page content, default) or 'foreground' (above it)."New value: +"'background' (behind page content, default) or 'foreground' (above it). Applies to text and image alike." - changed
Input schema / properties / watermark / properties / text / descriptionPrevious value: -"Watermark text."New value: +"Watermark text. Optional when `image` is given." - removed
Input schema / properties / watermark / requiredRemoved value: -[ - "text" -] - changed
Input schema / properties / wrap / descriptionPrevious value: -"Cell wrap policy (pdfnative v1.2). 'auto' (default) wraps only when a cell overflows; 'always' wraps every cell; 'never' uses v1.1 character truncation."New value: +"Cell wrap policy: 'auto' (default) wraps only overflowing cells; 'always' wraps every cell; 'never' truncates." - changed
Input schema / properties / zebra / descriptionPrevious value: -"Enable zebra striping (alternate-row light tint, PDF/A-1b safe). pdfnative v1.2."New value: +"Alternate-row light tint (static fill, PDF/A-1b safe)." - changed
Output schema / descriptionPrevious value: -"Structured result of a PDF-producing tool. In base64 mode the PDF bytes are delivered out-of-band as an embedded `resource` content block (data: URI), NOT duplicated here, to keep responses token-frugal. In file mode `filePath` is the sandboxed absolute path."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`." - added
Output schema / properties / diagnosticsAdded value: +{ + "description": "PDF/A diagnostics (when includeDiagnostics=true).", + "items": { + "additionalProperties": false, + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "severity": { + "enum": [ + "warning" + ], + "type": "string" + } + }, + "required": [ + "code", + "message", + "severity" + ], + "type": "object" + }, + "type": "array" +} - changed
Output schema / properties / filePath / descriptionPrevious value: -"Absolute sandboxed file path (when mode='file')."New value: +"Sandboxed absolute path (file mode)." - added
Output schema / properties / summaryAdded value: +{ + "additionalProperties": true, + "description": "Tool-specific summary, when produced.", + "type": "object" +}
- Changed
annotate_pdf6 fields changed- added
Input schema / properties / outputMode / descriptionAdded value: +"'base64' (default) returns the PDF inline; 'file' writes it inside the PDFNATIVE_MCP_OUTPUT_DIR sandbox (SECURITY_VIOLATION when the sandbox is not configured)." - added
Input schema / properties / outputPath / descriptionAdded value: +"Required when outputMode='file'. Relative path inside the sandbox; must end with .pdf (no absolute paths, no '..')." - changed
Output schema / descriptionPrevious value: -"Structured result of a PDF-producing tool. In base64 mode the PDF bytes are delivered out-of-band as an embedded `resource` content block (data: URI), NOT duplicated here, to keep responses token-frugal. In file mode `filePath` is the sandboxed absolute path."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`." - added
Output schema / properties / diagnosticsAdded value: +{ + "description": "PDF/A diagnostics (when includeDiagnostics=true).", + "items": { + "additionalProperties": false, + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "severity": { + "enum": [ + "warning" + ], + "type": "string" + } + }, + "required": [ + "code", + "message", + "severity" + ], + "type": "object" + }, + "type": "array" +} - changed
Output schema / properties / filePath / descriptionPrevious value: -"Absolute sandboxed file path (when mode='file')."New value: +"Sandboxed absolute path (file mode)." - added
Output schema / properties / summaryAdded value: +{ + "additionalProperties": true, + "description": "Tool-specific summary, when produced.", + "type": "object" +}
- Changed
decrypt_pdf5 fields changed- added
Input schema / properties / outputMode / descriptionAdded value: +"'base64' (default) returns the PDF inline; 'file' writes it inside the PDFNATIVE_MCP_OUTPUT_DIR sandbox (SECURITY_VIOLATION when the sandbox is not configured)." - changed
Output schema / descriptionPrevious value: -"Structured result of a PDF-producing tool. In base64 mode the PDF bytes are delivered out-of-band as an embedded `resource` content block (data: URI), NOT duplicated here, to keep responses token-frugal. In file mode `filePath` is the sandboxed absolute path."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`." - added
Output schema / properties / diagnosticsAdded value: +{ + "description": "PDF/A diagnostics (when includeDiagnostics=true).", + "items": { + "additionalProperties": false, + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "severity": { + "enum": [ + "warning" + ], + "type": "string" + } + }, + "required": [ + "code", + "message", + "severity" + ], + "type": "object" + }, + "type": "array" +} - changed
Output schema / properties / filePath / descriptionPrevious value: -"Absolute sandboxed file path (when mode='file')."New value: +"Sandboxed absolute path (file mode)." - added
Output schema / properties / summaryAdded value: +{ + "additionalProperties": true, + "description": "Tool-specific summary, when produced.", + "type": "object" +}
- Changed
embed_image23 fields changed- added
Input schema / properties / alignAdded value: +{ + "default": "left", + "description": "Horizontal placement of the image inside the content width.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" +} - added
Input schema / properties / altAdded value: +{ + "description": "Accessible description of the image (tagged /Figure /Alt). Provide it for non-decorative images under PDF/A or PDF/UA.", + "maxLength": 500, + "type": "string" +} - added
Input schema / properties / compressAdded value: +{ + "description": "FlateDecode the streams (smaller file, different bytes; PDF/A unaffected, XMP stays plain). Default false.", + "type": "boolean" +} - added
Input schema / properties / creationDateAdded value: +{ + "description": "ISO-8601 instant for /CreationDate (+ XMP). Pin it for byte-identical output across calls (same host TZ); omitted = wall clock, so every call differs.", + "format": "date-time", + "type": "string" +} - added
Input schema / properties / debugAdded value: +{ + "description": "Draw margin / block / cell guide rectangles (unmarked content — not for PDF/UA output). Geometry unchanged. Default false.", + "type": "boolean" +} - added
Input schema / properties / embedFontsAdded value: +{ + "default": false, + "description": "Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A claim (ISO 19005 §6.2.11.4.1) and for strict=true; adds ~0.3 MiB.", + "type": "boolean" +} - added
Input schema / properties / encryptAdded value: +{ + "additionalProperties": false, + "description": "Encrypt at build time (AES-128 default / AES-256) and KEEP the AcroForm — unlike encrypt_pdf, which rebuilds the page tree. Exclusive with pdfA. Randomised output, never cached.", + "properties": { + "algorithm": { + "default": "aes128", + "description": "aes128 (V4/R4, widest compatibility) or aes256 (V5/R6).", + "enum": [ + "aes128", + "aes256" + ], + "type": "string" + }, + "ownerPassword": { + "description": "Owner password (full access).", + "maxLength": 4096, + "minLength": 1, + "type": "string" + }, + "permissions": { + "additionalProperties": false, + "description": "Permission flags; each defaults to allowed.", + "properties": { + "copy": { + "type": "boolean" + }, + "extractText": { + "type": "boolean" + }, + "modify": { + "type": "boolean" + }, + "print": { + "type": "boolean" + } + }, + "type": "object" + }, + "userPassword": { + "description": "Open password; omitted/empty = opens without a prompt.", + "maxLength": 4096, + "type": "string" + } + }, + "required": [ + "ownerPassword" + ], + "type": "object" +} - added
Input schema / properties / footerTemplateAdded value: +{ + "additionalProperties": false, + "description": "Running footer on every page. Replaces the default footer: footerText is then ignored and page numbers appear only via {page}/{pages}.", + "properties": { + "center": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "color": { + "description": "Hex colour.", + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + "fontSize": { + "description": "Default 7.", + "maximum": 14, + "minimum": 6, + "type": "number" + }, + "left": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "right": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / headerTemplateAdded value: +{ + "additionalProperties": false, + "description": "Running header on every page (left / center / right zones); reserves 15 pt.", + "properties": { + "center": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "color": { + "description": "Hex colour.", + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + "fontSize": { + "description": "Default 7.", + "maximum": 14, + "minimum": 6, + "type": "number" + }, + "left": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "right": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + } + }, + "type": "object" +} - changed
Input schema / properties / imageBase64 / descriptionPrevious value: -"Base64-encoded image bytes. Supports JPEG and PNG formats."New value: +"Base64 image bytes. JPEG (baseline; 1, 3 or 4 components — CMYK raises PDFA_DEVICE_CMYK_IMAGE under PDF/A) or PNG (8-bit greyscale/RGB, non-interlaced; alpha-channel and palette PNGs are rejected with a remedy). No data: URI." - added
Input schema / properties / includeDiagnosticsAdded value: +{ + "default": false, + "description": "Return the PDF/A diagnostics raised while building as `diagnostics[]` (possibly empty).", + "type": "boolean" +} - added
Input schema / properties / marginsAdded value: +{ + "additionalProperties": false, + "description": "Margins in points, all four required (0–200). Default 45 / 36 / 35 / 36.", + "properties": { + "bottom": { + "maximum": 200, + "minimum": 0, + "type": "number" + }, + "left": { + "maximum": 200, + "minimum": 0, + "type": "number" + }, + "right": { + "maximum": 200, + "minimum": 0, + "type": "number" + }, + "top": { + "maximum": 200, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "top", + "right", + "bottom", + "left" + ], + "type": "object" +} - added
Input schema / properties / metadataAdded value: +{ + "additionalProperties": false, + "description": "/Info (+ XMP under PDF/A): author, subject, keywords, /Trapped.", + "properties": { + "author": { + "maxLength": 500, + "type": "string" + }, + "keywords": { + "maxLength": 1000, + "type": "string" + }, + "subject": { + "maxLength": 1000, + "type": "string" + }, + "trapped": { + "description": "/Trapped print flag.", + "enum": [ + "True", + "False", + "Unknown" + ], + "type": "string" + } + }, + "type": "object" +} - changed
Input schema / properties / mimeType / descriptionPrevious value: -"MIME type of the image. Must match the actual encoding of imageBase64."New value: +"MIME type of the image. Must match the actual encoding of imageBase64 (magic bytes are checked)." - added
Input schema / properties / outputIntentAdded value: +{ + "additionalProperties": false, + "description": "Custom PDF/A OutputIntent: an RGB ICC profile + condition strings replacing the built-in sRGB intent (CMYK rejected).", + "properties": { + "iccProfileBase64": { + "description": "ICC profile bytes, base64 (RGB, ≤ 8 MiB).", + "maxLength": 11000000, + "minLength": 1, + "type": "string" + }, + "info": { + "maxLength": 500, + "type": "string" + }, + "outputCondition": { + "maxLength": 200, + "type": "string" + }, + "outputConditionIdentifier": { + "description": "e.g. \"sRGB IEC61966-2.1\".", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "registryName": { + "description": "Default \"http://www.color.org\".", + "maxLength": 200, + "type": "string" + } + }, + "required": [ + "iccProfileBase64", + "outputConditionIdentifier" + ], + "type": "object" +} - added
Input schema / properties / pageSizeAdded value: +{ + "description": "Portrait page preset (points): A4 595.28×841.89 (default), Letter 612×792, Legal 612×1008, A3 841.89×1190.55, Tabloid 792×1224. print.* boxes must fit it.", + "enum": [ + "A4", + "Letter", + "Legal", + "A3", + "Tabloid" + ], + "type": "string" +} - changed
Input schema / properties / pdfA / descriptionPrevious value: -"Optional PDF/A conformance level (powered by pdfnative v1.2). Use 'pdfa1b' for archival of simple text+images, 'pdfa2b'/'pdfa2u' for richer content (2u guarantees Unicode mapping), 'pdfa3b' when embedding source attachments (Factur-X / ZUGFeRD). Mutually exclusive with PDF encryption. See docs/guides/PDFA.md."New value: +"PDF/A level: pdfa1b (simple text+images), pdfa2b/pdfa2u (richer; 2u = Unicode mapping), pdfa3b (attachments / Factur-X). Pair with embedFonts=true for a valid claim. Exclusive with encryption. See docs/guides/PDFA.md." - added
Input schema / properties / printAdded value: +{ + "additionalProperties": false, + "description": "Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b). See docs/guides/PRINT.md.", + "properties": { + "artBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "bleed": { + "description": "Bleed in points (8.5 = 3 mm); sets TrimBox = MediaBox inset. Exclusive with trimBox.", + "exclusiveMinimum": 0, + "maximum": 200, + "type": "number" + }, + "bleedBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "cropBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "marks": { + "description": "Printer's marks (needs bleed or trimBox): true for defaults, or an object.", + "oneOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "crop": { + "description": "Corner crop (trim) marks. Default true.", + "type": "boolean" + }, + "length": { + "description": "Mark length in points. Default 14.", + "maximum": 100, + "minimum": 1, + "type": "number" + }, + "offset": { + "description": "Gap between TrimBox and marks in points. Default 5.", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "registration": { + "description": "Edge-midpoint registration targets. Default true.", + "type": "boolean" + }, + "weight": { + "description": "Stroke width in points. Default 0.25.", + "maximum": 5, + "minimum": 0.05, + "type": "number" + } + }, + "type": "object" + } + ] + }, + "trimBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "userUnit": { + "description": "/UserUnit (multiples of 1/72 in) for pages over 14400 pt. Rejected under pdfa1b.", + "maximum": 75000, + "minimum": 1, + "type": "number" + } + }, + "type": "object" +} - added
Input schema / properties / strictAdded value: +{ + "default": false, + "description": "Fail with PDF_A_COMPLIANCE_VIOLATION instead of producing a non-conformant PDF/A file (e.g. PDFA_NO_FONT_ENTRIES without embedFonts). Pair with embedFonts=true.", + "type": "boolean" +} - changed
Output schema / descriptionPrevious value: -"Structured result of a PDF-producing tool. In base64 mode the PDF bytes are delivered out-of-band as an embedded `resource` content block (data: URI), NOT duplicated here, to keep responses token-frugal. In file mode `filePath` is the sandboxed absolute path."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`." - added
Output schema / properties / diagnosticsAdded value: +{ + "description": "PDF/A diagnostics (when includeDiagnostics=true).", + "items": { + "additionalProperties": false, + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "severity": { + "enum": [ + "warning" + ], + "type": "string" + } + }, + "required": [ + "code", + "message", + "severity" + ], + "type": "object" + }, + "type": "array" +} - changed
Output schema / properties / filePath / descriptionPrevious value: -"Absolute sandboxed file path (when mode='file')."New value: +"Sandboxed absolute path (file mode)." - added
Output schema / properties / summaryAdded value: +{ + "additionalProperties": true, + "description": "Tool-specific summary, when produced.", + "type": "object" +}
- Changed
encrypt_pdf9 fields changed- changed
Input schema / properties / algorithm / descriptionPrevious value: -"Content cipher: aes128 (V4/R4, widest compatibility) or aes256 (V5/R6, strongest)."New value: +"aes128 (V4/R4, widest compatibility) or aes256 (V5/R6)." - added
Input schema / properties / outputMode / descriptionAdded value: +"'base64' (default) returns the PDF inline; 'file' writes it inside the PDFNATIVE_MCP_OUTPUT_DIR sandbox (SECURITY_VIOLATION when the sandbox is not configured)." - changed
Input schema / properties / ownerPassword / descriptionPrevious value: -"Owner password (required, non-empty). Controls permissions and full access."New value: +"Owner password (full access)." - changed
Input schema / properties / permissions / descriptionPrevious value: -"Access permission flags (enforced by conforming readers). Each defaults to allowed when omitted."New value: +"Permission flags; each defaults to allowed." - changed
Input schema / properties / userPassword / descriptionPrevious value: -"User (open) password. Omitted or empty string means the document opens without a password prompt."New value: +"Open password; omitted/empty = opens without a prompt." - changed
Output schema / descriptionPrevious value: -"Structured result of a PDF-producing tool. In base64 mode the PDF bytes are delivered out-of-band as an embedded `resource` content block (data: URI), NOT duplicated here, to keep responses token-frugal. In file mode `filePath` is the sandboxed absolute path."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`." - added
Output schema / properties / diagnosticsAdded value: +{ + "description": "PDF/A diagnostics (when includeDiagnostics=true).", + "items": { + "additionalProperties": false, + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "severity": { + "enum": [ + "warning" + ], + "type": "string" + } + }, + "required": [ + "code", + "message", + "severity" + ], + "type": "object" + }, + "type": "array" +} - changed
Output schema / properties / filePath / descriptionPrevious value: -"Absolute sandboxed file path (when mode='file')."New value: +"Sandboxed absolute path (file mode)." - added
Output schema / properties / summaryAdded value: +{ + "additionalProperties": true, + "description": "Tool-specific summary, when produced.", + "type": "object" +}
- Added
extract_attachments - Added
extract_pages - Changed
extract_text7 fields changed- changed
Input schema / properties / password / descriptionPrevious value: -"Password to open an encrypted source PDF (user or owner — both are tried). Omit for unencrypted documents. Never logged or echoed back."New value: +"Password (user or owner) of an encrypted source. Never logged or echoed." - added
Output schema / descriptionAdded value: +"Structured text-extraction result. Every property is optional because the result can be projected: verbosity:'summary' returns only the scalar summary fields, fields:[...] keeps a dot-path subset. Defaults return the full shape." - added
Output schema / properties / charCountAdded value: +{ + "description": "summary only: length of fullText.", + "minimum": 0, + "type": "integer" +} - changed
Output schema / properties / extractableReason / descriptionPrevious value: -"Human-readable explanation when extractable=false. Absent when extractable=true."New value: +"Present when extractable is false: why no text could be decoded." - removed
Output schema / properties / pages / items / properties / runs / items / requiredRemoved value: -[ - "text", - "x", - "y", - "fontSize", - "fontName" -] - removed
Output schema / properties / pages / items / requiredRemoved value: -[ - "index", - "text" -] - removed
Output schema / requiredRemoved value: -[ - "pageCount", - "extractedPageCount", - "extractable", - "pages", - "fullText" -]
- Added
fill_form - Changed
generate_basic_pdf34 fields changed- changed
Input schema / properties / blocks / items / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "level": { - "enum": [ - 1, - 2, - 3 - ], - "type": "integer" - }, - "text": { - "maxLength": 500, - "minLength": 1, - "type": "string" - }, - "type": { - "const": "heading" - } - }, - "required": [ - "type", - "text", - "level" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "text": { - "description": "Paragraph text. Embedded newlines ('\\n') are automatically split into separate paragraphs — no need to pre-split; never emit a literal newline expecting a soft line break.", - "maxLength": 50000, - "minLength": 1, - "type": "string" - }, - "type": { - "const": "paragraph" - } - }, - "required": [ - "type", - "text" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "description": "List items. A string is a leaf; an object { text, items } nests a sub-list (bullets/numbers indent; numbered sub-lists restart at 1).", - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "style": { - "default": "bullet", - "enum": [ - "bullet", - "numbered" - ], - "type": "string" - }, - "type": { - "const": "list" - } - }, - "required": [ - "type", - "items" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "type": { - "const": "pageBreak" - } - }, - "required": [ - "type" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "height": { - "maximum": 500, - "minimum": 1, - "type": "number" - }, - "type": { - "const": "spacer" - } - }, - "required": [ - "type", - "height" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "Native vector chart (pdfnative v1.6.0) — bar / horizontal-bar / line / pie / donut, rendered as pure PDF path operators.", - "properties": { - "align": { - "description": "Horizontal alignment within the content width. Default 'left'.", - "enum": [ - "left", - "center", - "right" - ], - "type": "string" - }, - "altText": { - "description": "Alt text for the tagged-PDF /Figure /Alt. Auto-generated when omitted.", - "maxLength": 500, - "type": "string" - }, - "axis": { - "additionalProperties": false, - "description": "Value-axis options (bar/line only).", - "properties": { - "grid": { - "description": "Draw horizontal gridlines.", - "type": "boolean" - }, - "ticks": { - "description": "Target tick count (nice 1/2/5×10ⁿ steps).", - "maximum": 20, - "minimum": 2, - "type": "integer" - }, - "yMax": { - "description": "Force the axis maximum (values are clamped to the plot band).", - "type": "number" - }, - "yMin": { - "description": "Force the axis minimum (values are clamped to the plot band).", - "type": "number" - } - }, - "type": "object" - }, - "categories": { - "description": "Category / slice labels (x-axis). Defaults to 1-based indices when omitted.", - "items": { - "maxLength": 200, - "type": "string" - }, - "maxItems": 1000, - "type": "array" - }, - "chartType": { - "description": "Chart kind. 'pie'/'donut' use exactly one series; 'bar'/'barH'/'line' support multiple series.", - "enum": [ - "bar", - "barH", - "line", - "pie", - "donut" - ], - "type": "string" - }, - "colors": { - "description": "Palette override (per-series for bar/line, per-slice for pie/donut).", - "items": { - "description": "CSS-style hex colour, e.g. \"#3366cc\".", - "pattern": "^#?[0-9a-fA-F]{6}$", - "type": "string" - }, - "maxItems": 50, - "type": "array" - }, - "height": { - "description": "Plot-area height in points. Default 240.", - "maximum": 2000, - "minimum": 50, - "type": "number" - }, - "legend": { - "description": "Legend placement. Defaults to 'bottom' for multi-series/pie, else 'none'.", - "enum": [ - "bottom", - "none" - ], - "type": "string" - }, - "markers": { - "description": "Draw point markers on line series. Default false.", - "type": "boolean" - }, - "series": { - "description": "Data series. Pie/donut charts use exactly one series (each value becomes a slice).", - "items": { - "additionalProperties": false, - "properties": { - "color": { - "description": "CSS-style hex colour, e.g. \"#3366cc\".", - "pattern": "^#?[0-9a-fA-F]{6}$", - "type": "string" - }, - "label": { - "description": "Series label (shown in the legend).", - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "values": { - "description": "Numeric values, one per category. Negative values are supported for bar/line.", - "items": { - "type": "number" - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - } - }, - "required": [ - "label", - "values" - ], - "type": "object" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" - }, - "title": { - "description": "Chart title rendered above the plot.", - "maxLength": 200, - "type": "string" - }, - "type": { - "const": "chart" - }, - "width": { - "description": "Plot width in points (clamped to content width). Default 460.", - "maximum": 2000, - "minimum": 50, - "type": "number" - } - }, - "required": [ - "type", - "chartType", - "series" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "level": { + "enum": [ + 1, + 2, + 3 + ], + "type": "integer" + }, + "text": { + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "heading" + } + }, + "required": [ + "type", + "text", + "level" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "text": { + "description": "Paragraph text. Embedded newlines ('\\n') are automatically split into separate paragraphs — no need to pre-split; never emit a literal newline expecting a soft line break.", + "maxLength": 50000, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "paragraph" + } + }, + "required": [ + "type", + "text" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "description": "List items. A string is a leaf; an object { text, items } nests a sub-list (bullets/numbers indent; numbered sub-lists restart at 1).", + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "style": { + "default": "bullet", + "enum": [ + "bullet", + "numbered" + ], + "type": "string" + }, + "type": { + "const": "list" + } + }, + "required": [ + "type", + "items" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "type": { + "const": "pageBreak" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "height": { + "maximum": 500, + "minimum": 1, + "type": "number" + }, + "type": { + "const": "spacer" + } + }, + "required": [ + "type", + "height" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Native vector chart rendered as pure PDF path operators — bar / horizontal-bar / stacked-bar / line / area / scatter / pie / donut (pdfnative 1.7 charts v2: time and log axes, data labels, secondary axis, legends). Same body as add_chart.", + "properties": { + "align": { + "description": "Horizontal alignment within the content width. Default 'left'.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + }, + "altText": { + "description": "Alt text for the tagged-PDF /Figure /Alt. Auto-generated when omitted.", + "maxLength": 500, + "type": "string" + }, + "axis": { + "additionalProperties": false, + "description": "Value-axis options (bar/line only).", + "properties": { + "grid": { + "description": "Draw horizontal gridlines.", + "type": "boolean" + }, + "scale": { + "description": "Value-axis scale. 'log' requires strictly positive values and is not available for stacked charts.", + "enum": [ + "linear", + "log" + ], + "type": "string" + }, + "ticks": { + "description": "Target tick count (nice 1/2/5×10ⁿ steps).", + "maximum": 20, + "minimum": 2, + "type": "integer" + }, + "yMax": { + "description": "Force the axis maximum (values are clamped to the plot band).", + "type": "number" + }, + "yMin": { + "description": "Force the axis minimum (values are clamped to the plot band).", + "type": "number" + } + }, + "type": "object" + }, + "axis2": { + "additionalProperties": false, + "description": "Secondary RIGHT value axis (drawn only when a series sets yAxis:'right').", + "properties": { + "scale": { + "enum": [ + "linear", + "log" + ], + "type": "string" + }, + "ticks": { + "maximum": 20, + "minimum": 2, + "type": "integer" + }, + "yMax": { + "type": "number" + }, + "yMin": { + "type": "number" + } + }, + "type": "object" + }, + "categories": { + "description": "Category / slice labels (x-axis). Defaults to 1-based indices when omitted.", + "items": { + "maxLength": 200, + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "chartType": { + "description": "Chart kind. 'pie'/'donut' use exactly one series; 'bar'/'barH'/'stackedBar'/'stackedBarH'/'line'/'area'/'scatter' support multiple series. 'scatter' requires xValues on every series and a positional xAxis.type ('linear' or 'time').", + "enum": [ + "bar", + "barH", + "stackedBar", + "stackedBarH", + "line", + "area", + "scatter", + "pie", + "donut" + ], + "type": "string" + }, + "colors": { + "description": "Palette override (per-series for bar/line, per-slice for pie/donut).", + "items": { + "description": "CSS-style hex colour, e.g. \"#3366cc\".", + "pattern": "^#?[0-9a-fA-F]{6}$", + "type": "string" + }, + "maxItems": 50, + "type": "array" + }, + "dataLabels": { + "description": "Per-point value labels: true for defaults, or an object to format them.", + "oneOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "decimals": { + "maximum": 6, + "minimum": 0, + "type": "integer" + }, + "prefix": { + "maxLength": 16, + "type": "string" + }, + "suffix": { + "maxLength": 16, + "type": "string" + } + }, + "type": "object" + } + ] + }, + "height": { + "description": "Plot-area height in points. Default 240.", + "maximum": 2000, + "minimum": 50, + "type": "number" + }, + "labelRotation": { + "description": "Rotate category labels counter-clockwise by this many degrees (disables the automatic stride).", + "maximum": 90, + "minimum": 0, + "type": "number" + }, + "labelStride": { + "description": "Draw every Nth category label. Default: automatic (measured non-overlap); 1 draws every label.", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "legend": { + "description": "Legend placement. Defaults to 'bottom' for multi-series/pie, else 'none'.", + "enum": [ + "bottom", + "none" + ], + "type": "string" + }, + "markers": { + "description": "Draw point markers on line series. Default false.", + "type": "boolean" + }, + "series": { + "description": "Data series. Pie/donut charts use exactly one series (each value becomes a slice).", + "items": { + "additionalProperties": false, + "properties": { + "color": { + "description": "CSS-style hex colour, e.g. \"#3366cc\".", + "pattern": "^#?[0-9a-fA-F]{6}$", + "type": "string" + }, + "label": { + "description": "Series label (shown in the legend).", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "values": { + "description": "Numeric values, one per category. Negative values are supported for bar/line.", + "items": { + "type": "number" + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "xValues": { + "description": "Per-point x positions (same length as values) for scatter charts and for line/area charts with xAxis.type 'linear' or 'time'.", + "items": { + "description": "Positional x value: a number (linear axis) or an ISO-8601 date / epoch milliseconds (time axis).", + "maxLength": 64, + "type": [ + "number", + "string" + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "yAxis": { + "description": "Bind the series to the left (default) or the secondary right value axis (cartesian charts only; configure its range with 'axis2').", + "enum": [ + "left", + "right" + ], + "type": "string" + } + }, + "required": [ + "label", + "values" + ], + "type": "object" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "title": { + "description": "Chart title rendered above the plot.", + "maxLength": 200, + "type": "string" + }, + "type": { + "const": "chart" + }, + "width": { + "description": "Plot width in points (clamped to content width). Default 460.", + "maximum": 2000, + "minimum": 50, + "type": "number" + }, + "xAxis": { + "additionalProperties": false, + "description": "Horizontal axis. 'category' (default) positions points by index; 'linear' / 'time' position them by series xValues (line/area/scatter only). Time ticks are UTC-deterministic.", + "properties": { + "grid": { + "description": "Draw vertical gridlines.", + "type": "boolean" + }, + "max": { + "description": "Axis maximum (number, or ISO-8601 / epoch ms for time axes).", + "maxLength": 64, + "type": [ + "number", + "string" + ] + }, + "min": { + "description": "Axis minimum (number, or ISO-8601 / epoch ms for time axes).", + "maxLength": 64, + "type": [ + "number", + "string" + ] + }, + "ticks": { + "maximum": 20, + "minimum": 2, + "type": "integer" + }, + "type": { + "enum": [ + "category", + "linear", + "time" + ], + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "type", + "chartType", + "series" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Inline smart table — same body as add_table (every row must have exactly as many cells as headers).", + "properties": { + "autoFitColumns": { + "description": "Auto-fit column widths to content. Output bytes then depend on text metrics (not byte-deterministic across content changes).", + "type": "boolean" + }, + "caption": { + "description": "Caption rendered above the table (tagged as /Caption under PDF/A).", + "maxLength": 200, + "type": "string" + }, + "cellBorders": { + "additionalProperties": false, + "description": "Per-cell vector borders (pure strokes, PDF/A-safe). Choose individual sides or `all`.", + "properties": { + "all": { + "description": "Draw all four edges (overrides the individual side flags).", + "type": "boolean" + }, + "bottom": { + "type": "boolean" + }, + "color": { + "description": "Stroke colour as a PDF operator string ('0.8 0.8 0.8') or hex. Default light grey.", + "type": "string" + }, + "left": { + "type": "boolean" + }, + "right": { + "type": "boolean" + }, + "style": { + "description": "Stroke style (default 'solid').", + "enum": [ + "solid", + "dashed", + "dotted" + ], + "type": "string" + }, + "top": { + "type": "boolean" + }, + "width": { + "description": "Stroke width in points (default 0.5).", + "maximum": 10, + "minimum": 0, + "type": "number" + } + }, + "type": "object" + }, + "cellPadding": { + "description": "Horizontal cell padding in points (default 3).", + "maximum": 50, + "minimum": 0, + "type": "number" + }, + "cellVAlign": { + "description": "Vertical alignment of cell content.", + "enum": [ + "top", + "middle", + "bottom" + ], + "type": "string" + }, + "clipCells": { + "description": "Clip cell contents to the column bounds (PDF clip operators). Recommended for PDF/A and visual safety.", + "type": "boolean" + }, + "headers": { + "description": "Column header labels. Must have the same length as each row in `rows`.", + "items": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "minRowHeight": { + "description": "Minimum row height in points (default 12).", + "maximum": 200, + "minimum": 1, + "type": "number" + }, + "repeatHeader": { + "description": "Repeat the header row on every continuation page (default true).", + "type": "boolean" + }, + "rows": { + "description": "Data rows. Each row is an array of cell strings with the same length as `headers`.", + "items": { + "items": { + "maxLength": 500, + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "maxItems": 5000, + "minItems": 1, + "type": "array" + }, + "type": { + "const": "table" + }, + "wrap": { + "description": "Cell wrap policy: 'auto' (default) wraps only overflowing cells; 'always' wraps every cell; 'never' truncates.", + "enum": [ + "auto", + "always", + "never" + ], + "type": "string" + }, + "zebra": { + "description": "Alternate-row light tint (static fill, PDF/A-1b safe).", + "type": "boolean" + } + }, + "required": [ + "type", + "headers", + "rows" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Inline JPEG/PNG image. Without width/height the pixel size is used as points and clamped to the content width; with one dimension the aspect ratio is kept. The decoded bytes of all image blocks in one call are capped at 24 MiB (a watermark image has its own 8 MiB cap).", + "properties": { + "align": { + "default": "left", + "description": "Horizontal placement inside the content width.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + }, + "alt": { + "description": "Accessible description (tagged /Figure /Alt). Always provide it for non-decorative content under PDF/A or PDF/UA.", + "maxLength": 500, + "type": "string" + }, + "height": { + "description": "Render height in points.", + "maximum": 1000, + "minimum": 10, + "type": "number" + }, + "imageBase64": { + "description": "Base64 image bytes. JPEG (baseline; 1, 3 or 4 components — CMYK raises PDFA_DEVICE_CMYK_IMAGE under PDF/A) or PNG (8-bit greyscale/RGB, non-interlaced; alpha-channel and palette PNGs are rejected with a remedy). No data: URI.", + "maxLength": 12000000, + "minLength": 4, + "type": "string" + }, + "mimeType": { + "description": "MIME type of the image. Must match the actual encoding of imageBase64 (magic bytes are checked).", + "enum": [ + "image/jpeg", + "image/png" + ], + "type": "string" + }, + "type": { + "const": "image" + }, + "width": { + "description": "Render width in points.", + "maximum": 800, + "minimum": 10, + "type": "number" + } + }, + "required": [ + "type", + "imageBase64", + "mimeType" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Clickable external link (/URI action). Only http:, https: and mailto: URLs are accepted.", + "properties": { + "color": { + "description": "Hex colour (#RGB or #RRGGBB).", + "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$", + "type": "string" + }, + "fontSize": { + "description": "Default 10.", + "maximum": 48, + "minimum": 6, + "type": "number" + }, + "text": { + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "link" + }, + "url": { + "description": "http(s):// or mailto: URL.", + "maxLength": 2048, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "type", + "text", + "url" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Printed table of contents generated from the document's heading blocks (internal /GoTo links with dot leaders). Pairs with outline:'auto' for the bookmark pane.", + "properties": { + "fontSize": { + "description": "Default 10.", + "maximum": 24, + "minimum": 6, + "type": "number" + }, + "indent": { + "description": "Points of indent per heading level (default 15).", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "maxLevel": { + "description": "Deepest heading level listed (default 3).", + "enum": [ + 1, + 2, + 3 + ], + "type": "integer" + }, + "title": { + "description": "Default 'Table of Contents'.", + "maxLength": 200, + "type": "string" + }, + "type": { + "const": "toc" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Inline barcode — same body as add_barcode (pure vector, no /Alt available in the engine).", + "properties": { + "align": { + "default": "left", + "description": "Horizontal placement inside the content width.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + }, + "data": { + "description": "Raw payload to encode — do NOT URL-encode. For QR/URL pass e.g. \"https://example.com\" verbatim. EAN-13 must be 12 or 13 digits (13th is auto-computed). Code 128 accepts ASCII alphanumerics.", + "maxLength": 4296, + "minLength": 1, + "type": "string" + }, + "ecLevel": { + "default": "M", + "description": "QR ONLY. Error correction level (L=7%, M=15%, Q=25%, H=30%). Ignored for code128/ean13/datamatrix/pdf417. Use H for printed media that may get smudged or partially covered (e.g. logo overlay).", + "enum": [ + "L", + "M", + "Q", + "H" + ], + "type": "string" + }, + "format": { + "description": "Barcode symbology to render.", + "enum": [ + "qr", + "code128", + "ean13", + "datamatrix", + "pdf417" + ], + "type": "string" + }, + "height": { + "default": 200, + "description": "Barcode height in PDF points (ignored for square symbologies like QR/Data Matrix).", + "maximum": 500, + "minimum": 30, + "type": "number" + }, + "type": { + "const": "barcode" + }, + "width": { + "default": 200, + "description": "Barcode width in PDF points.", + "maximum": 500, + "minimum": 30, + "type": "number" + } + }, + "required": [ + "type", + "format", + "data" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Vector drawing from an SVG path `d` string or SVG markup. Supported: <path> <rect> (rx/ry) <circle> <ellipse> <line> <polyline> <polygon> and <text>/<tspan> (x, y, font-size, fill, text-anchor, dx/dy); fill / stroke / stroke-width attributes; double-quoted attributes only. NOT supported (silently ignored): transform, <g>, <use>, <image>, <defs>/<clipPath>, gradients, opacity, CSS/style, dash patterns, text word-wrap. No external reference is ever fetched (no XML parser: entities other than & < > " ' &#n; are dropped). Pure path operators — PDF/A-safe at every level.", + "properties": { + "align": { + "default": "left", + "description": "Horizontal placement inside the content width.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + }, + "alt": { + "description": "Accessible description (tagged /Figure /Alt). Always provide it for non-decorative content under PDF/A or PDF/UA.", + "maxLength": 500, + "type": "string" + }, + "data": { + "description": "Path `d` string or SVG markup (≤ 100 000 characters).", + "maxLength": 100000, + "minLength": 1, + "type": "string" + }, + "fill": { + "description": "Hex colour or 'none' (default black).", + "pattern": "^(?:none|#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}))$", + "type": "string" + }, + "height": { + "description": "Render height in points (default 200).", + "maximum": 1000, + "minimum": 10, + "type": "number" + }, + "stroke": { + "description": "Hex colour or 'none' (default none).", + "pattern": "^(?:none|#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}))$", + "type": "string" + }, + "strokeWidth": { + "description": "Stroke width in SVG user units (default 1).", + "maximum": 50, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "svg" + }, + "viewBox": { + "description": "[minX, minY, width, height] — overrides the viewBox of the markup; required for a bare path string that is not 0-based.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "width": { + "description": "Render width in points (default 200).", + "maximum": 800, + "minimum": 10, + "type": "number" + } + }, + "required": [ + "type", + "data" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Inline AcroForm field — same body as an add_form field. Under a PDF/A claim the widget appearance font is not embedded (PDFA_UNEMBEDDED_FORM_FONT; strict:true fails the call).", + "properties": { + "checked": { + "description": "Initial checked state for checkbox / radio fields.", + "type": "boolean" + }, + "fieldType": { + "description": "Type of form control to render. Radio fields sharing a name form one radio group.", + "enum": [ + "text", + "textarea", + "checkbox", + "radio", + "dropdown", + "listbox" + ], + "type": "string" + }, + "fontSize": { + "description": "Font size for text rendering inside the field.", + "maximum": 48, + "minimum": 6, + "type": "number" + }, + "height": { + "description": "Field height in points (default depends on the type).", + "maximum": 300, + "minimum": 10, + "type": "number" + }, + "label": { + "description": "Human-readable label shown above the field.", + "maxLength": 200, + "type": "string" + }, + "maxLength": { + "description": "Maximum character length for text/textarea fields.", + "maximum": 32767, + "minimum": 1, + "type": "integer" + }, + "name": { + "description": "Unique field name used as the PDF annotation identifier (/T).", + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "options": { + "description": "Choices for dropdown, listbox or radio fields.", + "items": { + "maxLength": 200, + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "placeholder": { + "description": "Hint text shown while the field is empty.", + "maxLength": 200, + "type": "string" + }, + "readOnly": { + "description": "Prevent editing of this field.", + "type": "boolean" + }, + "required": { + "description": "Mark field as required.", + "type": "boolean" + }, + "type": { + "const": "formField" + }, + "value": { + "description": "Default value pre-filled in the field.", + "maxLength": 2000, + "type": "string" + }, + "width": { + "description": "Field width in points (default: full content width).", + "maximum": 500, + "minimum": 10, + "type": "number" + } + }, + "required": [ + "type", + "fieldType", + "name" + ], + "type": "object" + } +] - added
Input schema / properties / compressAdded value: +{ + "description": "FlateDecode the streams (smaller file, different bytes; PDF/A unaffected, XMP stays plain). Default false.", + "type": "boolean" +} - added
Input schema / properties / creationDateAdded value: +{ + "description": "ISO-8601 instant for /CreationDate (+ XMP). Pin it for byte-identical output across calls (same host TZ); omitted = wall clock, so every call differs.", + "format": "date-time", + "type": "string" +} - added
Input schema / properties / debugAdded value: +{ + "description": "Draw margin / block / cell guide rectangles (unmarked content — not for PDF/UA output). Geometry unchanged. Default false.", + "type": "boolean" +} - added
Input schema / properties / embedFontsAdded value: +{ + "default": false, + "description": "Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A claim (ISO 19005 §6.2.11.4.1) and for strict=true; adds ~0.3 MiB.", + "type": "boolean" +} - added
Input schema / properties / encryptAdded value: +{ + "additionalProperties": false, + "description": "Encrypt at build time (AES-128 default / AES-256) and KEEP the AcroForm — unlike encrypt_pdf, which rebuilds the page tree. Exclusive with pdfA. Randomised output, never cached.", + "properties": { + "algorithm": { + "default": "aes128", + "description": "aes128 (V4/R4, widest compatibility) or aes256 (V5/R6).", + "enum": [ + "aes128", + "aes256" + ], + "type": "string" + }, + "ownerPassword": { + "description": "Owner password (full access).", + "maxLength": 4096, + "minLength": 1, + "type": "string" + }, + "permissions": { + "additionalProperties": false, + "description": "Permission flags; each defaults to allowed.", + "properties": { + "copy": { + "type": "boolean" + }, + "extractText": { + "type": "boolean" + }, + "modify": { + "type": "boolean" + }, + "print": { + "type": "boolean" + } + }, + "type": "object" + }, + "userPassword": { + "description": "Open password; omitted/empty = opens without a prompt.", + "maxLength": 4096, + "type": "string" + } + }, + "required": [ + "ownerPassword" + ], + "type": "object" +} - added
Input schema / properties / footerTemplateAdded value: +{ + "additionalProperties": false, + "description": "Running footer on every page. Replaces the default footer: footerText is then ignored and page numbers appear only via {page}/{pages}.", + "properties": { + "center": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "color": { + "description": "Hex colour.", + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + "fontSize": { + "description": "Default 7.", + "maximum": 14, + "minimum": 6, + "type": "number" + }, + "left": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "right": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / headerTemplateAdded value: +{ + "additionalProperties": false, + "description": "Running header on every page (left / center / right zones); reserves 15 pt.", + "properties": { + "center": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "color": { + "description": "Hex colour.", + "pattern": "^#[0-9a-fA-F]{6}$", + "type": "string" + }, + "fontSize": { + "description": "Default 7.", + "maximum": 14, + "minimum": 6, + "type": "number" + }, + "left": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + }, + "right": { + "description": "Placeholders: {page} {pages} {title} {date} (build-day wall clock, not creationDate).", + "maxLength": 200, + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / includeDiagnosticsAdded value: +{ + "default": false, + "description": "Return the PDF/A diagnostics raised while building as `diagnostics[]` (possibly empty).", + "type": "boolean" +} - added
Input schema / properties / marginsAdded value: +{ + "additionalProperties": false, + "description": "Margins in points, all four required (0–200). Default 45 / 36 / 35 / 36.", + "properties": { + "bottom": { + "maximum": 200, + "minimum": 0, + "type": "number" + }, + "left": { + "maximum": 200, + "minimum": 0, + "type": "number" + }, + "right": { + "maximum": 200, + "minimum": 0, + "type": "number" + }, + "top": { + "maximum": 200, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "top", + "right", + "bottom", + "left" + ], + "type": "object" +} - added
Input schema / properties / metadataAdded value: +{ + "additionalProperties": false, + "description": "/Info (+ XMP under PDF/A): author, subject, keywords, /Trapped.", + "properties": { + "author": { + "maxLength": 500, + "type": "string" + }, + "keywords": { + "maxLength": 1000, + "type": "string" + }, + "subject": { + "maxLength": 1000, + "type": "string" + }, + "trapped": { + "description": "/Trapped print flag.", + "enum": [ + "True", + "False", + "Unknown" + ], + "type": "string" + } + }, + "type": "object" +} - changed
Input schema / properties / normalize / descriptionPrevious value: -"Optional Unicode normalization applied to all rendered text before shaping. 'NFC' (recommended) composes base + combining marks into precomposed code points for better glyph coverage; 'NFD'/'NFKC'/'NFKD' are also accepted. Omit for byte-stable output (no normalization)."New value: +"Unicode normalization before shaping ('NFC' recommended for glyph coverage; NFD/NFKC/NFKD accepted). Omit = none." - added
Input schema / properties / outputIntentAdded value: +{ + "additionalProperties": false, + "description": "Custom PDF/A OutputIntent: an RGB ICC profile + condition strings replacing the built-in sRGB intent (CMYK rejected).", + "properties": { + "iccProfileBase64": { + "description": "ICC profile bytes, base64 (RGB, ≤ 8 MiB).", + "maxLength": 11000000, + "minLength": 1, + "type": "string" + }, + "info": { + "maxLength": 500, + "type": "string" + }, + "outputCondition": { + "maxLength": 200, + "type": "string" + }, + "outputConditionIdentifier": { + "description": "e.g. \"sRGB IEC61966-2.1\".", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "registryName": { + "description": "Default \"http://www.color.org\".", + "maxLength": 200, + "type": "string" + } + }, + "required": [ + "iccProfileBase64", + "outputConditionIdentifier" + ], + "type": "object" +} - added
Input schema / properties / pageSizeAdded value: +{ + "description": "Portrait page preset (points): A4 595.28×841.89 (default), Letter 612×792, Legal 612×1008, A3 841.89×1190.55, Tabloid 792×1224. print.* boxes must fit it.", + "enum": [ + "A4", + "Letter", + "Legal", + "A3", + "Tabloid" + ], + "type": "string" +} - changed
Input schema / properties / pdfA / descriptionPrevious value: -"Optional PDF/A conformance level (powered by pdfnative v1.2). Use 'pdfa1b' for archival of simple text+images, 'pdfa2b'/'pdfa2u' for richer content (2u guarantees Unicode mapping), 'pdfa3b' when embedding source attachments (Factur-X / ZUGFeRD). Mutually exclusive with PDF encryption. See docs/guides/PDFA.md."New value: +"PDF/A level: pdfa1b (simple text+images), pdfa2b/pdfa2u (richer; 2u = Unicode mapping), pdfa3b (attachments / Factur-X). Pair with embedFonts=true for a valid claim. Exclusive with encryption. See docs/guides/PDFA.md." - added
Input schema / properties / printAdded value: +{ + "additionalProperties": false, + "description": "Print production (ISO 32000-1 §14.11): page boxes, `bleed` shorthand (TrimBox = MediaBox inset), crop/registration marks outside the TrimBox, /UserUnit for large formats (PDF 1.7; not under pdfa1b). See docs/guides/PRINT.md.", + "properties": { + "artBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "bleed": { + "description": "Bleed in points (8.5 = 3 mm); sets TrimBox = MediaBox inset. Exclusive with trimBox.", + "exclusiveMinimum": 0, + "maximum": 200, + "type": "number" + }, + "bleedBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "cropBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "marks": { + "description": "Printer's marks (needs bleed or trimBox): true for defaults, or an object.", + "oneOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "crop": { + "description": "Corner crop (trim) marks. Default true.", + "type": "boolean" + }, + "length": { + "description": "Mark length in points. Default 14.", + "maximum": 100, + "minimum": 1, + "type": "number" + }, + "offset": { + "description": "Gap between TrimBox and marks in points. Default 5.", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "registration": { + "description": "Edge-midpoint registration targets. Default true.", + "type": "boolean" + }, + "weight": { + "description": "Stroke width in points. Default 0.25.", + "maximum": 5, + "minimum": 0.05, + "type": "number" + } + }, + "type": "object" + } + ] + }, + "trimBox": { + "description": "[x0, y0, x1, y1] in points, origin bottom-left, inside the MediaBox.", + "items": { + "type": "number" + }, + "maxItems": 4, + "minItems": 4, + "type": "array" + }, + "userUnit": { + "description": "/UserUnit (multiples of 1/72 in) for pages over 14400 pt. Rejected under pdfa1b.", + "maximum": 75000, + "minimum": 1, + "type": "number" + } + }, + "type": "object" +} - added
Input schema / properties / strictAdded value: +{ + "default": false, + "description": "Fail with PDF_A_COMPLIANCE_VIOLATION instead of producing a non-conformant PDF/A file (e.g. PDFA_NO_FONT_ENTRIES without embedFonts). Pair with embedFonts=true.", + "type": "boolean" +} - added
Input schema / properties / viewerPreferences / properties / duplexAdded value: +{ + "description": "Print-dialog paper handling default (/Duplex): single-sided or double-sided flipping on the short/long edge.", + "enum": [ + "simplex", + "duplexFlipShortEdge", + "duplexFlipLongEdge" + ], + "type": "string" +} - added
Input schema / properties / viewerPreferences / properties / numCopiesAdded value: +{ + "description": "Default number of copies for the Print dialog (/NumCopies; viewers honour 2-5 per ISO 32000 Table 150).", + "maximum": 1000, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / viewerPreferences / properties / pickTrayByPDFSizeAdded value: +{ + "description": "Ask the printer to pick the input tray from the PDF page size (/PickTrayByPDFSize).", + "type": "boolean" +} - added
Input schema / properties / viewerPreferences / properties / printPageRangeAdded value: +{ + "description": "Default page ranges for the Print dialog (/PrintPageRange) as inclusive 1-based [first, last] pairs, e.g. [[1, 4], [7, 7]].", + "items": { + "items": { + "minimum": 1, + "type": "integer" + }, + "maxItems": 2, + "minItems": 2, + "type": "array" + }, + "maxItems": 100, + "type": "array" +} - changed
Input schema / properties / watermark / descriptionPrevious value: -"Optional semi-transparent text watermark rendered on every page (e.g. 'DRAFT', 'CONFIDENTIAL'). Text only in this version. opacity < 1.0 is rejected under pdfA='pdfa1b' (ISO 19005-1 forbids transparency)."New value: +"Optional semi-transparent watermark rendered centred on every page: `text` (e.g. 'DRAFT'), `image` (JPEG/PNG), or both combined. At least one of text / image is required. opacity < 1.0 (text or image, including the defaults) is rejected under pdfA='pdfa1b' (ISO 19005-1 forbids transparency)." - changed
Input schema / properties / watermark / properties / angle / descriptionPrevious value: -"Rotation in degrees (counterclockwise). Default -45."New value: +"Text rotation in degrees (counterclockwise). Default -45." - changed
Input schema / properties / watermark / properties / color / descriptionPrevious value: -"RGB colour as a [r, g, b] triple in the 0.0–1.0 range. Default light gray [0.75, 0.75, 0.75]."New value: +"Text RGB colour as a [r, g, b] triple in the 0.0–1.0 range. Default light gray [0.75, 0.75, 0.75]." - changed
Input schema / properties / watermark / properties / fontSize / descriptionPrevious value: -"Font size in points. Default 60, auto-fit to the page."New value: +"Text font size in points. Default 60, auto-fit to the page." - added
Input schema / properties / watermark / properties / imageAdded value: +{ + "additionalProperties": false, + "description": "Image watermark (JPEG or PNG) centred on every page, optionally combined with `text`. Bytes are validated against the JPEG/PNG magic numbers; mimeType must match.", + "properties": { + "height": { + "description": "Display height in points (default: from the image pixel size).", + "exclusiveMinimum": 0, + "maximum": 14400, + "type": "number" + }, + "imageBase64": { + "description": "Base64-encoded JPEG or 8-bit opaque PNG bytes (max 8 MiB decoded; alpha-channel, palette and interlaced PNGs are rejected with a remedy). Plain base64, no data: URI prefix.", + "maxLength": 12000000, + "minLength": 4, + "type": "string" + }, + "mimeType": { + "description": "'image/jpeg' or 'image/png' — must match the actual bytes.", + "enum": [ + "image/jpeg", + "image/png" + ], + "type": "string" + }, + "opacity": { + "description": "Image opacity 0.0–1.0. Default 0.10.", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "width": { + "description": "Display width in points (default: from the image pixel size).", + "exclusiveMinimum": 0, + "maximum": 14400, + "type": "number" + } + }, + "required": [ + "imageBase64", + "mimeType" + ], + "type": "object" +} - changed
Input schema / properties / watermark / properties / opacity / descriptionPrevious value: -"Opacity 0.0–1.0. Default 0.15."New value: +"Text opacity 0.0–1.0. Default 0.15. (Image opacity is image.opacity.)" - changed
Input schema / properties / watermark / properties / position / descriptionPrevious value: -"'background' (behind page content, default) or 'foreground' (above it)."New value: +"'background' (behind page content, default) or 'foreground' (above it). Applies to text and image alike." - changed
Input schema / properties / watermark / properties / text / descriptionPrevious value: -"Watermark text."New value: +"Watermark text. Optional when `image` is given." - removed
Input schema / properties / watermark / requiredRemoved value: -[ - "text" -] - changed
Output schema / descriptionPrevious value: -"Structured result of a PDF-producing tool. In base64 mode the PDF bytes are delivered out-of-band as an embedded `resource` content block (data: URI), NOT duplicated here, to keep responses token-frugal. In file mode `filePath` is the sandboxed absolute path."New value: +"Result of a PDF-producing tool. base64 mode: the PDF arrives as an embedded `resource` content block (not duplicated here); file mode: `filePath`." - added
Output schema / properties / diagnosticsAdded value: +{ + "description": "PDF/A diagnostics (when includeDiagnostics=true).", + "items": { + "additionalProperties": false, + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "severity": { + "enum": [ + "warning" + ], + "type": "string" + } + }, + "required": [ + "code", + "message", + "severity" + ], + "type": "object" + }, + "type": "array" +} - changed
Output schema / properties / filePath / descriptionPrevious value: -"Absolute sandboxed file path (when mode='file')."New value: +"Sandboxed absolute path (file mode)." - added
Output schema / properties / summaryAdded value: +{ + "additionalProperties": true, + "description": "Tool-specific summary, when produced.", + "type": "object" +}
- Added
inspect_layout - Added
inspect_pdf - Added
merge_pdfs - Added
prepare_signature_placeholder - Added
read_form_fields - Added
sign_pdf - Changed
split_pdf8 fields changed- changed
Input schema / properties / encrypt / descriptionPrevious value: -"Re-encrypt the produced PDF with the PDF Standard Security Handler (AES-128 V4/R4 default, or AES-256 V5/R6). RC4 is never emitted. Requires a Web Crypto CSPRNG. Applied to every produced range."New value: +"Re-encrypt the output (Standard Security Handler; AES-128 default or AES-256; RC4 never emitted). Applied to every produced range." - changed
Input schema / properties / encrypt / properties / algorithm / descriptionPrevious value: -"Content cipher: aes128 (V4/R4, widest compatibility) or aes256 (V5/R6, strongest)."New value: +"aes128 (V4/R4, widest compatibility) or aes256 (V5/R6)." - changed
Input schema / properties / encrypt / properties / ownerPassword / descriptionPrevious value: -"Owner password (required, non-empty). Controls permissions and full access."New value: +"Owner password (full access)." - changed
Input schema / properties / encrypt / properties / permissions / descriptionPrevious value: -"Access permission flags (enforced by conforming readers). Each defaults to allowed when omitted."New value: +"Permission flags; each defaults to allowed." - changed
Input schema / properties / encrypt / properties / userPassword / descriptionPrevious value: -"User (open) password. Omitted or empty string means the document opens without a password prompt."New value: +"Open password; omitted/empty = opens without a prompt." - added
Input schema / properties / outputMode / descriptionAdded value: +"'base64' (default) returns the PDF inline; 'file' writes it inside the PDFNATIVE_MCP_OUTPUT_DIR sandbox (SECURITY_VIOLATION when the sandbox is not configured)." - changed
Input schema / properties / password / descriptionPrevious value: -"Password to open an encrypted source PDF (user or owner — both are tried). Omit for unencrypted documents. Never logged or echoed back."New value: +"Password (user or owner) of an encrypted source. Never logged or echoed." - changed
Output schema / properties / parts / items / properties / filePath / descriptionPrevious value: -"Absolute sandboxed file path (when mode='file')."New value: +"Sandboxed absolute path (file mode)."
- Added
timestamp_pdf - Added
update_metadata - Added
validate_pdf - Added
verify_pdf
14 tool updates
v1.6.0- Added
add_chart - Added
decrypt_pdf - Added
encrypt_pdf - Removed
extract_attachments - Removed
extract_pages - Changed
extract_text5 fields changed- added
Input schema / properties / includeRunsAdded value: +{ + "default": false, + "description": "When true, each page also carries `runs[]` — positioned text-showing operations `{ text, x, y, fontSize, fontName }` in device space (content-stream order). Useful for layout-aware extraction; larger responses.", + "type": "boolean" +} - added
Input schema / properties / maxTextLengthAdded value: +{ + "description": "Hard cap on total extracted characters across all pages (memory bound for adversarial input). Default 16000000. Exceeding it fails with OUTPUT_TOO_LARGE.", + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / passwordAdded value: +{ + "description": "Password to open an encrypted source PDF (user or owner — both are tried). Omit for unencrypted documents. Never logged or echoed back.", + "maxLength": 4096, + "minLength": 1, + "type": "string" +} - changed
Output schema / properties / extractable / descriptionPrevious value: -"False when one or more requested pages had a non-empty content stream but yielded no extractable text (likely subset fonts without /ToUnicode)."New value: +"False when one or more requested pages produced text that is entirely U+FFFD replacement characters — a font with no usable /ToUnicode CMap or base encoding. Blank pages are still considered extractable." - added
Output schema / properties / pages / items / properties / runsAdded value: +{ + "description": "Positioned text runs (present only when includeRuns is true).", + "items": { + "additionalProperties": false, + "properties": { + "fontName": { + "type": "string" + }, + "fontSize": { + "type": "number" + }, + "text": { + "type": "string" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": [ + "text", + "x", + "y", + "fontSize", + "fontName" + ], + "type": "object" + }, + "type": "array" +}
- Changed
generate_basic_pdf1 field changed- changed
Input schema / properties / blocks / items / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "level": { - "enum": [ - 1, - 2, - 3 - ], - "type": "integer" - }, - "text": { - "maxLength": 500, - "minLength": 1, - "type": "string" - }, - "type": { - "const": "heading" - } - }, - "required": [ - "type", - "text", - "level" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "text": { - "description": "Paragraph text. Embedded newlines ('\\n') are automatically split into separate paragraphs — no need to pre-split; never emit a literal newline expecting a soft line break.", - "maxLength": 50000, - "minLength": 1, - "type": "string" - }, - "type": { - "const": "paragraph" - } - }, - "required": [ - "type", - "text" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "description": "List items. A string is a leaf; an object { text, items } nests a sub-list (bullets/numbers indent; numbered sub-lists restart at 1).", - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "oneOf": [ - { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - { - "additionalProperties": false, - "properties": { - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "text": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - } - ] - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "style": { - "default": "bullet", - "enum": [ - "bullet", - "numbered" - ], - "type": "string" - }, - "type": { - "const": "list" - } - }, - "required": [ - "type", - "items" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "type": { - "const": "pageBreak" - } - }, - "required": [ - "type" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "height": { - "maximum": 500, - "minimum": 1, - "type": "number" - }, - "type": { - "const": "spacer" - } - }, - "required": [ - "type", - "height" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "level": { + "enum": [ + 1, + 2, + 3 + ], + "type": "integer" + }, + "text": { + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "heading" + } + }, + "required": [ + "type", + "text", + "level" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "text": { + "description": "Paragraph text. Embedded newlines ('\\n') are automatically split into separate paragraphs — no need to pre-split; never emit a literal newline expecting a soft line break.", + "maxLength": 50000, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "paragraph" + } + }, + "required": [ + "type", + "text" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "description": "List items. A string is a leaf; an object { text, items } nests a sub-list (bullets/numbers indent; numbered sub-lists restart at 1).", + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "style": { + "default": "bullet", + "enum": [ + "bullet", + "numbered" + ], + "type": "string" + }, + "type": { + "const": "list" + } + }, + "required": [ + "type", + "items" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "type": { + "const": "pageBreak" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "height": { + "maximum": 500, + "minimum": 1, + "type": "number" + }, + "type": { + "const": "spacer" + } + }, + "required": [ + "type", + "height" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Native vector chart (pdfnative v1.6.0) — bar / horizontal-bar / line / pie / donut, rendered as pure PDF path operators.", + "properties": { + "align": { + "description": "Horizontal alignment within the content width. Default 'left'.", + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + }, + "altText": { + "description": "Alt text for the tagged-PDF /Figure /Alt. Auto-generated when omitted.", + "maxLength": 500, + "type": "string" + }, + "axis": { + "additionalProperties": false, + "description": "Value-axis options (bar/line only).", + "properties": { + "grid": { + "description": "Draw horizontal gridlines.", + "type": "boolean" + }, + "ticks": { + "description": "Target tick count (nice 1/2/5×10ⁿ steps).", + "maximum": 20, + "minimum": 2, + "type": "integer" + }, + "yMax": { + "description": "Force the axis maximum (values are clamped to the plot band).", + "type": "number" + }, + "yMin": { + "description": "Force the axis minimum (values are clamped to the plot band).", + "type": "number" + } + }, + "type": "object" + }, + "categories": { + "description": "Category / slice labels (x-axis). Defaults to 1-based indices when omitted.", + "items": { + "maxLength": 200, + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "chartType": { + "description": "Chart kind. 'pie'/'donut' use exactly one series; 'bar'/'barH'/'line' support multiple series.", + "enum": [ + "bar", + "barH", + "line", + "pie", + "donut" + ], + "type": "string" + }, + "colors": { + "description": "Palette override (per-series for bar/line, per-slice for pie/donut).", + "items": { + "description": "CSS-style hex colour, e.g. \"#3366cc\".", + "pattern": "^#?[0-9a-fA-F]{6}$", + "type": "string" + }, + "maxItems": 50, + "type": "array" + }, + "height": { + "description": "Plot-area height in points. Default 240.", + "maximum": 2000, + "minimum": 50, + "type": "number" + }, + "legend": { + "description": "Legend placement. Defaults to 'bottom' for multi-series/pie, else 'none'.", + "enum": [ + "bottom", + "none" + ], + "type": "string" + }, + "markers": { + "description": "Draw point markers on line series. Default false.", + "type": "boolean" + }, + "series": { + "description": "Data series. Pie/donut charts use exactly one series (each value becomes a slice).", + "items": { + "additionalProperties": false, + "properties": { + "color": { + "description": "CSS-style hex colour, e.g. \"#3366cc\".", + "pattern": "^#?[0-9a-fA-F]{6}$", + "type": "string" + }, + "label": { + "description": "Series label (shown in the legend).", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "values": { + "description": "Numeric values, one per category. Negative values are supported for bar/line.", + "items": { + "type": "number" + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "label", + "values" + ], + "type": "object" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + }, + "title": { + "description": "Chart title rendered above the plot.", + "maxLength": 200, + "type": "string" + }, + "type": { + "const": "chart" + }, + "width": { + "description": "Plot width in points (clamped to content width). Default 460.", + "maximum": 2000, + "minimum": 50, + "type": "number" + } + }, + "required": [ + "type", + "chartType", + "series" + ], + "type": "object" + } +]
- Removed
inspect_pdf - Removed
merge_pdfs - Removed
prepare_signature_placeholder - Removed
sign_pdf - Changed
split_pdf3 fields changed- added
Input schema / properties / encryptAdded value: +{ + "additionalProperties": false, + "description": "Re-encrypt the produced PDF with the PDF Standard Security Handler (AES-128 V4/R4 default, or AES-256 V5/R6). RC4 is never emitted. Requires a Web Crypto CSPRNG. Applied to every produced range.", + "properties": { + "algorithm": { + "default": "aes128", + "description": "Content cipher: aes128 (V4/R4, widest compatibility) or aes256 (V5/R6, strongest).", + "enum": [ + "aes128", + "aes256" + ], + "type": "string" + }, + "ownerPassword": { + "description": "Owner password (required, non-empty). Controls permissions and full access.", + "maxLength": 4096, + "minLength": 1, + "type": "string" + }, + "permissions": { + "additionalProperties": false, + "description": "Access permission flags (enforced by conforming readers). Each defaults to allowed when omitted.", + "properties": { + "copy": { + "type": "boolean" + }, + "extractText": { + "type": "boolean" + }, + "modify": { + "type": "boolean" + }, + "print": { + "type": "boolean" + } + }, + "type": "object" + }, + "userPassword": { + "description": "User (open) password. Omitted or empty string means the document opens without a password prompt.", + "maxLength": 4096, + "type": "string" + } + }, + "required": [ + "ownerPassword" + ], + "type": "object" +} - added
Input schema / properties / passwordAdded value: +{ + "description": "Password to open an encrypted source PDF (user or owner — both are tried). Omit for unencrypted documents. Never logged or echoed back.", + "maxLength": 4096, + "minLength": 1, + "type": "string" +} - changed
Input schema / properties / pdfBase64 / descriptionPrevious value: -"Base64-encoded source PDF. Must not be encrypted."New value: +"Base64-encoded source PDF. Pass `password` for an encrypted source."
- Removed
validate_pdf - Removed
verify_pdf
4 tool updates
v1.4.0- Changed
add_international_text1 field changed- changed
Input schema / properties / lang / oneOfPrevious value: -[ - { - "enum": [ - "ar", - "he", - "th", - "ja", - "zh", - "ko", - "el", - "hi", - "bn", - "ta", - "ru", - "ka", - "hy", - "tr", - "pl", - "vi", - "latin", - "te", - "si", - "bo", - "km", - "my", - "am", - "emoji" - ], - "type": "string" - }, - { - "items": { - "enum": [ - "ar", - "he", - "th", - "ja", - "zh", - "ko", - "el", - "hi", - "bn", - "ta", - "ru", - "ka", - "hy", - "tr", - "pl", - "vi", - "latin", - "te", - "si", - "bo", - "km", - "my", - "am", - "emoji" - ], - "type": "string" - }, - "maxItems": 24, - "minItems": 1, - "type": "array" - }, - { - "description": "Comma-separated list of supported codes.", - "maxLength": 80, - "minLength": 2, - "type": "string" - } -]New value: +[ + { + "enum": [ + "ar", + "he", + "th", + "ja", + "zh", + "ko", + "el", + "hi", + "bn", + "ta", + "ru", + "ka", + "hy", + "tr", + "pl", + "vi", + "latin", + "te", + "si", + "bo", + "km", + "my", + "am", + "emoji", + "math" + ], + "type": "string" + }, + { + "items": { + "enum": [ + "ar", + "he", + "th", + "ja", + "zh", + "ko", + "el", + "hi", + "bn", + "ta", + "ru", + "ka", + "hy", + "tr", + "pl", + "vi", + "latin", + "te", + "si", + "bo", + "km", + "my", + "am", + "emoji", + "math" + ], + "type": "string" + }, + "maxItems": 25, + "minItems": 1, + "type": "array" + }, + { + "description": "Comma-separated list of supported codes.", + "maxLength": 80, + "minLength": 2, + "type": "string" + } +]
- Added
annotate_pdf - Added
draft_governance_issue - Changed
inspect_pdf1 field changed- added
Output schema / properties / pageLabelsAdded value: +{ + "description": "Logical page-numbering ranges from the /PageLabels number tree (ISO 32000-1 §12.4.2), or absent when the document has none. Each range gives the 0-based first page, numbering style, optional prefix and start value.", + "items": { + "additionalProperties": false, + "properties": { + "prefix": { + "type": "string" + }, + "start": { + "type": "integer" + }, + "startPage": { + "minimum": 0, + "type": "integer" + }, + "style": { + "enum": [ + "decimal", + "roman", + "Roman", + "alpha", + "Alpha", + "none" + ], + "type": "string" + } + }, + "required": [ + "startPage" + ], + "type": "object" + }, + "type": "array" +}
6 tool updates
v1.2.2- Changed
add_international_text1 field changed- added
Input schema / properties / viewerPreferencesAdded value: +{ + "additionalProperties": false, + "description": "Reader presentation hints (catalog /PageLayout, /PageMode, /ViewerPreferences). PDF/A-safe; all optional.", + "properties": { + "centerWindow": { + "type": "boolean" + }, + "direction": { + "enum": [ + "l2r", + "r2l" + ], + "type": "string" + }, + "displayDocTitle": { + "type": "boolean" + }, + "fitWindow": { + "type": "boolean" + }, + "hideMenubar": { + "type": "boolean" + }, + "hideToolbar": { + "type": "boolean" + }, + "hideWindowUI": { + "type": "boolean" + }, + "nonFullScreenPageMode": { + "enum": [ + "useNone", + "useOutlines", + "useThumbs", + "useOC" + ], + "type": "string" + }, + "pageLayout": { + "enum": [ + "singlePage", + "oneColumn", + "twoColumnLeft", + "twoColumnRight", + "twoPageLeft", + "twoPageRight" + ], + "type": "string" + }, + "pageMode": { + "enum": [ + "useNone", + "useOutlines", + "useThumbs", + "fullScreen", + "useOC", + "useAttachments" + ], + "type": "string" + }, + "printScaling": { + "enum": [ + "none", + "appDefault" + ], + "type": "string" + } + }, + "type": "object" +}
- Changed
add_table3 fields changed- added
Input schema / properties / cellBordersAdded value: +{ + "additionalProperties": false, + "description": "Per-cell vector borders (pdfnative v1.4). Switches the backend to buildDocumentPDFBytes. Choose individual sides or `all`.", + "properties": { + "all": { + "description": "Draw all four edges (overrides the individual side flags).", + "type": "boolean" + }, + "bottom": { + "type": "boolean" + }, + "color": { + "description": "Stroke colour as a PDF operator string ('0.8 0.8 0.8') or hex. Default light grey.", + "type": "string" + }, + "left": { + "type": "boolean" + }, + "right": { + "type": "boolean" + }, + "style": { + "description": "Stroke style (default 'solid').", + "enum": [ + "solid", + "dashed", + "dotted" + ], + "type": "string" + }, + "top": { + "type": "boolean" + }, + "width": { + "description": "Stroke width in points (default 0.5).", + "maximum": 10, + "minimum": 0, + "type": "number" + } + }, + "type": "object" +} - added
Input schema / properties / cellVAlignAdded value: +{ + "description": "Vertical alignment of cell content (pdfnative v1.4). Switches the backend to buildDocumentPDFBytes.", + "enum": [ + "top", + "middle", + "bottom" + ], + "type": "string" +} - added
Input schema / properties / viewerPreferencesAdded value: +{ + "additionalProperties": false, + "description": "Reader presentation hints (catalog /PageLayout, /PageMode, /ViewerPreferences). PDF/A-safe; all optional.", + "properties": { + "centerWindow": { + "type": "boolean" + }, + "direction": { + "enum": [ + "l2r", + "r2l" + ], + "type": "string" + }, + "displayDocTitle": { + "type": "boolean" + }, + "fitWindow": { + "type": "boolean" + }, + "hideMenubar": { + "type": "boolean" + }, + "hideToolbar": { + "type": "boolean" + }, + "hideWindowUI": { + "type": "boolean" + }, + "nonFullScreenPageMode": { + "enum": [ + "useNone", + "useOutlines", + "useThumbs", + "useOC" + ], + "type": "string" + }, + "pageLayout": { + "enum": [ + "singlePage", + "oneColumn", + "twoColumnLeft", + "twoColumnRight", + "twoPageLeft", + "twoPageRight" + ], + "type": "string" + }, + "pageMode": { + "enum": [ + "useNone", + "useOutlines", + "useThumbs", + "fullScreen", + "useOC", + "useAttachments" + ], + "type": "string" + }, + "printScaling": { + "enum": [ + "none", + "appDefault" + ], + "type": "string" + } + }, + "type": "object" +}
- Added
extract_pages - Changed
generate_basic_pdf4 fields changed- changed
Input schema / properties / blocks / items / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "level": { - "enum": [ - 1, - 2, - 3 - ], - "type": "integer" - }, - "text": { - "maxLength": 500, - "minLength": 1, - "type": "string" - }, - "type": { - "const": "heading" - } - }, - "required": [ - "type", - "text", - "level" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "text": { - "description": "Paragraph text. Embedded newlines ('\\n') are automatically split into separate paragraphs — no need to pre-split; never emit a literal newline expecting a soft line break.", - "maxLength": 50000, - "minLength": 1, - "type": "string" - }, - "type": { - "const": "paragraph" - } - }, - "required": [ - "type", - "text" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "items": { - "items": { - "maxLength": 1000, - "minLength": 1, - "type": "string" - }, - "maxItems": 1000, - "minItems": 1, - "type": "array" - }, - "style": { - "default": "bullet", - "enum": [ - "bullet", - "numbered" - ], - "type": "string" - }, - "type": { - "const": "list" - } - }, - "required": [ - "type", - "items" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "type": { - "const": "pageBreak" - } - }, - "required": [ - "type" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "height": { - "maximum": 500, - "minimum": 1, - "type": "number" - }, - "type": { - "const": "spacer" - } - }, - "required": [ - "type", - "height" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "level": { + "enum": [ + 1, + 2, + 3 + ], + "type": "integer" + }, + "text": { + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "heading" + } + }, + "required": [ + "type", + "text", + "level" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "text": { + "description": "Paragraph text. Embedded newlines ('\\n') are automatically split into separate paragraphs — no need to pre-split; never emit a literal newline expecting a soft line break.", + "maxLength": 50000, + "minLength": 1, + "type": "string" + }, + "type": { + "const": "paragraph" + } + }, + "required": [ + "type", + "text" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "description": "List items. A string is a leaf; an object { text, items } nests a sub-list (bullets/numbers indent; numbered sub-lists restart at 1).", + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "oneOf": [ + { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "text": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "style": { + "default": "bullet", + "enum": [ + "bullet", + "numbered" + ], + "type": "string" + }, + "type": { + "const": "list" + } + }, + "required": [ + "type", + "items" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "type": { + "const": "pageBreak" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "height": { + "maximum": 500, + "minimum": 1, + "type": "number" + }, + "type": { + "const": "spacer" + } + }, + "required": [ + "type", + "height" + ], + "type": "object" + } +] - added
Input schema / properties / outlineAdded value: +{ + "description": "Document outline (bookmarks panel). Either 'auto' (derive a flat outline from heading blocks) or an explicit nested bookmark tree.", + "oneOf": [ + { + "enum": [ + "auto" + ], + "type": "string" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "bold": { + "type": "boolean" + }, + "children": { + "items": { + "additionalProperties": false, + "properties": { + "bold": { + "type": "boolean" + }, + "children": { + "items": { + "additionalProperties": false, + "properties": { + "bold": { + "type": "boolean" + }, + "children": { + "items": { + "additionalProperties": false, + "properties": { + "bold": { + "type": "boolean" + }, + "children": { + "items": { + "additionalProperties": false, + "properties": { + "bold": { + "type": "boolean" + }, + "children": { + "items": { + "additionalProperties": false, + "properties": { + "bold": { + "type": "boolean" + }, + "color": { + "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1').", + "type": "string" + }, + "italic": { + "type": "boolean" + }, + "open": { + "description": "Initial expansion state (default true). false renders the branch collapsed.", + "type": "boolean" + }, + "pageIndex": { + "description": "0-based destination page index.", + "minimum": 0, + "type": "integer" + }, + "title": { + "description": "Bookmark label.", + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "y": { + "description": "Destination Y coordinate in points (default: top of page).", + "type": "number" + } + }, + "required": [ + "title", + "pageIndex" + ], + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "color": { + "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1').", + "type": "string" + }, + "italic": { + "type": "boolean" + }, + "open": { + "description": "Initial expansion state (default true). false renders the branch collapsed.", + "type": "boolean" + }, + "pageIndex": { + "description": "0-based destination page index.", + "minimum": 0, + "type": "integer" + }, + "title": { + "description": "Bookmark label.", + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "y": { + "description": "Destination Y coordinate in points (default: top of page).", + "type": "number" + } + }, + "required": [ + "title", + "pageIndex" + ], + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "color": { + "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1').", + "type": "string" + }, + "italic": { + "type": "boolean" + }, + "open": { + "description": "Initial expansion state (default true). false renders the branch collapsed.", + "type": "boolean" + }, + "pageIndex": { + "description": "0-based destination page index.", + "minimum": 0, + "type": "integer" + }, + "title": { + "description": "Bookmark label.", + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "y": { + "description": "Destination Y coordinate in points (default: top of page).", + "type": "number" + } + }, + "required": [ + "title", + "pageIndex" + ], + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "color": { + "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1').", + "type": "string" + }, + "italic": { + "type": "boolean" + }, + "open": { + "description": "Initial expansion state (default true). false renders the branch collapsed.", + "type": "boolean" + }, + "pageIndex": { + "description": "0-based destination page index.", + "minimum": 0, + "type": "integer" + }, + "title": { + "description": "Bookmark label.", + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "y": { + "description": "Destination Y coordinate in points (default: top of page).", + "type": "number" + } + }, + "required": [ + "title", + "pageIndex" + ], + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "color": { + "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1').", + "type": "string" + }, + "italic": { + "type": "boolean" + }, + "open": { + "description": "Initial expansion state (default true). false renders the branch collapsed.", + "type": "boolean" + }, + "pageIndex": { + "description": "0-based destination page index.", + "minimum": 0, + "type": "integer" + }, + "title": { + "description": "Bookmark label.", + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "y": { + "description": "Destination Y coordinate in points (default: top of page).", + "type": "number" + } + }, + "required": [ + "title", + "pageIndex" + ], + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "color": { + "description": "Label colour as a hex string ('#1a73e8') or PDF operator string ('0 0 1').", + "type": "string" + }, + "italic": { + "type": "boolean" + }, + "open": { + "description": "Initial expansion state (default true). false renders the branch collapsed.", + "type": "boolean" + }, + "pageIndex": { + "description": "0-based destination page index.", + "minimum": 0, + "type": "integer" + }, + "title": { + "description": "Bookmark label.", + "maxLength": 500, + "minLength": 1, + "type": "string" + }, + "y": { + "description": "Destination Y coordinate in points (default: top of page).", + "type": "number" + } + }, + "required": [ + "title", + "pageIndex" + ], + "type": "object" + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + } + ] +} - added
Input schema / properties / pageLabelsAdded value: +{ + "description": "Page-label ranges (the visible page numbers in the viewer, e.g. roman front-matter then decimal body). startPage values must be unique and strictly increasing.", + "items": { + "additionalProperties": false, + "properties": { + "prefix": { + "description": "Optional label prefix (e.g. 'A-').", + "maxLength": 64, + "type": "string" + }, + "start": { + "description": "First numeric value in the range (default 1).", + "minimum": 1, + "type": "integer" + }, + "startPage": { + "description": "0-based index of the first page in this range.", + "minimum": 0, + "type": "integer" + }, + "style": { + "description": "Numbering style. 'none' (or omitted with a prefix) yields prefix-only labels.", + "enum": [ + "decimal", + "roman", + "Roman", + "alpha", + "Alpha", + "none" + ], + "type": "string" + } + }, + "required": [ + "startPage" + ], + "type": "object" + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" +} - added
Input schema / properties / viewerPreferencesAdded value: +{ + "additionalProperties": false, + "description": "Reader presentation hints (catalog /PageLayout, /PageMode, /ViewerPreferences). PDF/A-safe; all optional.", + "properties": { + "centerWindow": { + "type": "boolean" + }, + "direction": { + "enum": [ + "l2r", + "r2l" + ], + "type": "string" + }, + "displayDocTitle": { + "type": "boolean" + }, + "fitWindow": { + "type": "boolean" + }, + "hideMenubar": { + "type": "boolean" + }, + "hideToolbar": { + "type": "boolean" + }, + "hideWindowUI": { + "type": "boolean" + }, + "nonFullScreenPageMode": { + "enum": [ + "useNone", + "useOutlines", + "useThumbs", + "useOC" + ], + "type": "string" + }, + "pageLayout": { + "enum": [ + "singlePage", + "oneColumn", + "twoColumnLeft", + "twoColumnRight", + "twoPageLeft", + "twoPageRight" + ], + "type": "string" + }, + "pageMode": { + "enum": [ + "useNone", + "useOutlines", + "useThumbs", + "fullScreen", + "useOC", + "useAttachments" + ], + "type": "string" + }, + "printScaling": { + "enum": [ + "none", + "appDefault" + ], + "type": "string" + } + }, + "type": "object" +}
- Added
merge_pdfs - Added
split_pdf
14 tool updates
v1.2.0- Changed
add_attachment2 fields changed- added
Output schema / descriptionAdded value: +"Structured result of a PDF-producing tool. In base64 mode the PDF bytes are delivered out-of-band as an embedded `resource` content block (data: URI), NOT duplicated here, to keep responses token-frugal. In file mode `filePath` is the sandboxed absolute path." - removed
Output schema / properties / base64Removed value: -{ - "description": "Base64-encoded PDF bytes (when mode='base64').", - "type": "string" -}
- Changed
add_barcode2 fields changed- added
Output schema / descriptionAdded value: +"Structured result of a PDF-producing tool. In base64 mode the PDF bytes are delivered out-of-band as an embedded `resource` content block (data: URI), NOT duplicated here, to keep responses token-frugal. In file mode `filePath` is the sandboxed absolute path." - removed
Output schema / properties / base64Removed value: -{ - "description": "Base64-encoded PDF bytes (when mode='base64').", - "type": "string" -}
- Changed
add_form2 fields changed- added
Output schema / descriptionAdded value: +"Structured result of a PDF-producing tool. In base64 mode the PDF bytes are delivered out-of-band as an embedded `resource` content block (data: URI), NOT duplicated here, to keep responses token-frugal. In file mode `filePath` is the sandboxed absolute path." - removed
Output schema / properties / base64Removed value: -{ - "description": "Base64-encoded PDF bytes (when mode='base64').", - "type": "string" -}
- Changed
add_international_text3 fields changed- added
Input schema / properties / normalizeAdded value: +{ + "description": "Unicode normalization form applied before shaping. Defaults to 'NFC' (recommended for international scripts: composes decomposed sequences for the widest glyph coverage). Override with 'NFD'/'NFKC'/'NFKD' only for specialised needs.", + "enum": [ + "NFC", + "NFD", + "NFKC", + "NFKD" + ], + "type": "string" +} - added
Output schema / descriptionAdded value: +"Structured result of a PDF-producing tool. In base64 mode the PDF bytes are delivered out-of-band as an embedded `resource` content block (data: URI), NOT duplicated here, to keep responses token-frugal. In file mode `filePath` is the sandboxed absolute path." - removed
Output schema / properties / base64Removed value: -{ - "description": "Base64-encoded PDF bytes (when mode='base64').", - "type": "string" -}
- Changed
add_table3 fields changed- added
Input schema / properties / watermarkAdded value: +{ + "additionalProperties": false, + "description": "Optional semi-transparent text watermark rendered on every page (e.g. 'DRAFT', 'CONFIDENTIAL'). Text only in this version. opacity < 1.0 is rejected under pdfA='pdfa1b' (ISO 19005-1 forbids transparency).", + "properties": { + "angle": { + "description": "Rotation in degrees (counterclockwise). Default -45.", + "maximum": 360, + "minimum": -360, + "type": "number" + }, + "color": { + "description": "RGB colour as a [r, g, b] triple in the 0.0–1.0 range. Default light gray [0.75, 0.75, 0.75].", + "items": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" + }, + "fontSize": { + "description": "Font size in points. Default 60, auto-fit to the page.", + "maximum": 300, + "minimum": 6, + "type": "number" + }, + "opacity": { + "description": "Opacity 0.0–1.0. Default 0.15.", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "position": { + "default": "background", + "description": "'background' (behind page content, default) or 'foreground' (above it).", + "enum": [ + "background", + "foreground" + ], + "type": "string" + }, + "text": { + "description": "Watermark text.", + "maxLength": 100, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" +} - added
Output schema / descriptionAdded value: +"Structured result of a PDF-producing tool. In base64 mode the PDF bytes are delivered out-of-band as an embedded `resource` content block (data: URI), NOT duplicated here, to keep responses token-frugal. In file mode `filePath` is the sandboxed absolute path." - removed
Output schema / properties / base64Removed value: -{ - "description": "Base64-encoded PDF bytes (when mode='base64').", - "type": "string" -}
- Changed
embed_image2 fields changed- added
Output schema / descriptionAdded value: +"Structured result of a PDF-producing tool. In base64 mode the PDF bytes are delivered out-of-band as an embedded `resource` content block (data: URI), NOT duplicated here, to keep responses token-frugal. In file mode `filePath` is the sandboxed absolute path." - removed
Output schema / properties / base64Removed value: -{ - "description": "Base64-encoded PDF bytes (when mode='base64').", - "type": "string" -}
- Added
extract_attachments - Changed
extract_text2 fields changed- added
Input schema / properties / fieldsAdded value: +{ + "description": "Optional dot-path projection applied to the structured result (e.g. ['fullText'] or ['extractable']). Composes after verbosity. Unknown paths are omitted.", + "items": { + "minLength": 1, + "type": "string" + }, + "maxItems": 16, + "type": "array" +} - added
Input schema / properties / verbosityAdded value: +{ + "default": "full", + "description": "Response verbosity. 'full' (default) returns the per-page pages[] array and fullText; 'summary' returns a token-frugal { pageCount, extractedPageCount, extractable, charCount } and drops the text payloads.", + "enum": [ + "summary", + "full" + ], + "type": "string" +}
- Changed
generate_basic_pdf4 fields changed- added
Input schema / properties / normalizeAdded value: +{ + "description": "Optional Unicode normalization applied to all rendered text before shaping. 'NFC' (recommended) composes base + combining marks into precomposed code points for better glyph coverage; 'NFD'/'NFKC'/'NFKD' are also accepted. Omit for byte-stable output (no normalization).", + "enum": [ + "NFC", + "NFD", + "NFKC", + "NFKD" + ], + "type": "string" +} - added
Input schema / properties / watermarkAdded value: +{ + "additionalProperties": false, + "description": "Optional semi-transparent text watermark rendered on every page (e.g. 'DRAFT', 'CONFIDENTIAL'). Text only in this version. opacity < 1.0 is rejected under pdfA='pdfa1b' (ISO 19005-1 forbids transparency).", + "properties": { + "angle": { + "description": "Rotation in degrees (counterclockwise). Default -45.", + "maximum": 360, + "minimum": -360, + "type": "number" + }, + "color": { + "description": "RGB colour as a [r, g, b] triple in the 0.0–1.0 range. Default light gray [0.75, 0.75, 0.75].", + "items": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" + }, + "fontSize": { + "description": "Font size in points. Default 60, auto-fit to the page.", + "maximum": 300, + "minimum": 6, + "type": "number" + }, + "opacity": { + "description": "Opacity 0.0–1.0. Default 0.15.", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "position": { + "default": "background", + "description": "'background' (behind page content, default) or 'foreground' (above it).", + "enum": [ + "background", + "foreground" + ], + "type": "string" + }, + "text": { + "description": "Watermark text.", + "maxLength": 100, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" +} - added
Output schema / descriptionAdded value: +"Structured result of a PDF-producing tool. In base64 mode the PDF bytes are delivered out-of-band as an embedded `resource` content block (data: URI), NOT duplicated here, to keep responses token-frugal. In file mode `filePath` is the sandboxed absolute path." - removed
Output schema / properties / base64Removed value: -{ - "description": "Base64-encoded PDF bytes (when mode='base64').", - "type": "string" -}
- Changed
inspect_pdf2 fields changed- added
Input schema / properties / fieldsAdded value: +{ + "description": "Optional dot-path projection applied to the structured result (e.g. ['pageCount','signatureCount']). Composes after verbosity. Unknown paths are omitted.", + "items": { + "minLength": 1, + "type": "string" + }, + "maxItems": 16, + "type": "array" +} - added
Input schema / properties / verbosityAdded value: +{ + "default": "full", + "description": "Response verbosity. 'full' (default) returns every field; 'summary' returns a token-frugal scalar subset (version, pageCount, encryption, pdfA, signatureCount, hasSignaturePlaceholder, attachmentCount) — drops the attachments[], info and perPage arrays.", + "enum": [ + "summary", + "full" + ], + "type": "string" +}
- Changed
prepare_signature_placeholder2 fields changed- added
Output schema / descriptionAdded value: +"Structured result of a PDF-producing tool. In base64 mode the PDF bytes are delivered out-of-band as an embedded `resource` content block (data: URI), NOT duplicated here, to keep responses token-frugal. In file mode `filePath` is the sandboxed absolute path." - removed
Output schema / properties / base64Removed value: -{ - "description": "Base64-encoded PDF bytes (when mode='base64').", - "type": "string" -}
- Changed
sign_pdf2 fields changed- added
Output schema / descriptionAdded value: +"Structured result of a PDF-producing tool. In base64 mode the PDF bytes are delivered out-of-band as an embedded `resource` content block (data: URI), NOT duplicated here, to keep responses token-frugal. In file mode `filePath` is the sandboxed absolute path." - removed
Output schema / properties / base64Removed value: -{ - "description": "Base64-encoded PDF bytes (when mode='base64').", - "type": "string" -}
- Changed
validate_pdf2 fields changed- added
Input schema / properties / fieldsAdded value: +{ + "description": "Optional dot-path projection applied to the structured result (e.g. ['valid']). Composes after verbosity. Unknown paths are omitted.", + "items": { + "minLength": 1, + "type": "string" + }, + "maxItems": 16, + "type": "array" +} - added
Input schema / properties / verbosityAdded value: +{ + "default": "full", + "description": "Response verbosity. 'full' (default) returns errors[] and warnings[]; 'summary' returns a token-frugal verdict { standard, valid, errorCount, warningCount, summary } and drops the message arrays.", + "enum": [ + "summary", + "full" + ], + "type": "string" +}
- Changed
verify_pdf2 fields changed- added
Input schema / properties / fieldsAdded value: +{ + "description": "Optional dot-path projection applied to the structured result (e.g. ['allValid'] or ['signatures.valid']). Composes after verbosity. Unknown paths are omitted.", + "items": { + "minLength": 1, + "type": "string" + }, + "maxItems": 16, + "type": "array" +} - added
Input schema / properties / verbosityAdded value: +{ + "default": "full", + "description": "Response verbosity. 'full' (default) returns the per-signature signatures[] array; 'summary' returns a token-frugal verdict { signatureCount, allValid, invalid, summary } and drops signatures[].", + "enum": [ + "summary", + "full" + ], + "type": "string" +}
13 tool updates
v1.1.0- First observed
add_attachment - First observed
add_barcode - First observed
add_form - First observed
add_international_text - First observed
add_table - First observed
embed_image - First observed
extract_text - First observed
generate_basic_pdf - First observed
inspect_pdf - First observed
prepare_signature_placeholder - First observed
sign_pdf - First observed
validate_pdf - First observed
verify_pdf
TDQS
Scored across 28 tools
Most tools have sharply distinct purposes, and the descriptions actively resolve the obvious overlaps: generate_basic_pdf is declared the default while add_table/add_chart/embed_image/add_barcode are scoped to standalone artefacts, split_pdf vs extract_pages is cross-referenced, and add_form vs read_form_fields vs fill_form are clearly separated. The only soft spot is the cluster of read-only inspectors (inspect_pdf, inspect_layout, validate_pdf, verify_pdf), whose names alone would be confusable, though their descriptions disambiguate well.
All names are snake_case with a leading verb (generate_basic_pdf, extract_text, merge_pdfs, sign_pdf, validate_pdf, verify_pdf), which is predictable. The main deviation is the create-family split between generate_/embed_ and the add_* prefix (add_table, add_form, add_chart, add_barcode, add_attachment, add_ltv), plus a few oddities like timestamp_pdf and prepare_signature_placeholder.
At 28 tools this is on the heavy side, well beyond the comfortable 3–15 band. The PDF domain is genuinely broad (generation, extraction, page ops, forms, signatures, LTV, validation), so each tool does have a distinct job, but the surface is large enough that agents must scan a long list to find the right entry point.
Coverage is unusually thorough: creation from blocks, standalone artefact builders, extraction, merge/split/subset, annotation, encrypt/decrypt, form read/fill, signing with placeholder, DSS/LTV, document timestamps, structural validation and signature verification form a coherent lifecycle. Remaining gaps are true redaction (explicitly called out as out of scope for annotate_pdf) and page-level editing like rotation/reordering in place.
Maintenance
Related MCP Connectors
Deterministic PDF tools for AI agents: inspect fields, fill forms, merge PDFs, invoices.
PDF tools for AI agents: validate, extract, merge, split, compress, OCR, sign and redact.
Generate and read PDFs for AI agents: a generate_pdf and a read_pdf tool, priced per document.
Send PDFs for e-signature from AI agents, with a public hash-chained evidence log anyone can verify
Related MCP Servers
- AlicenseAqualityCmaintenanceGenerate professional PDFs from Claude, Cursor, and other AI tools. Create invoices, contracts, reports, and certificates from templates or inline HTML markup.721 npm1MIT
- FlicenseNot gradedqualityAmaintenanceEnables AI agents to perform comprehensive PDF operations locally, including compression, text extraction, PII redaction, page organization, splitting, merging, watermarking, creation, and form filling, all without cloud uploads.7 npm-
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to create and process office documents locally, including generating branded PDF, Word, Excel, and editable PowerPoint files from templates and themes, plus reading, OCR, form-filling, manipulation, and conversion of PDFs.1MIT
- AlicenseBqualityAmaintenanceEnables AI agents to perform local-first PDF processing entirely on-device, including OCR write-back to make scans searchable, unlocking and re-encrypting PDFs, splitting/merging/rotating pages, and compressing files, with no cloud calls or file uploads.2527 PyPI1MIT