Skip to main content
Glama

Add international text

add_international_text
Idempotent

Render PDF text in 32 scripts, including Arabic, Hebrew, CJK, Devanagari and Thai, with automatic BiDi, complex-script shaping and embedded fonts.

Instructions

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.

Input Schema

NameRequiredDescriptionDefault
fontNoOperator-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.
langYesLanguage / 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.
pdfANoPDF/A level (Tagged PDF + sRGB OutputIntent + XMP). Fonts are embedded here, so the claim is valid as-is. See docs/guides/PDFA.md.
pdfxNoPDF/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.
debugNoDraw margin / block / cell guide rectangles (unmarked content — not for PDF/UA output). Geometry unchanged. Default false.
printNoPrint 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.
titleYesPDF title (rendered as page heading and stored as document metadata).
strictNoFail 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.
encryptNoEncrypt 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.
marginsNoMargins in points, all four required (0–200). Default 45 / 36 / 35 / 36.
compressNoFlateDecode the streams (smaller file, different bytes; PDF/A unaffected, XMP stays plain). Default false.
metadataNo/Info (+ XMP under PDF/A): author, subject, keywords, /Trapped.
pageSizeNoPortrait 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.
directionNoBase 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).
normalizeNoUnicode normalization before shaping. Default 'NFC' (widest glyph coverage); NFD/NFKC/NFKD or false for special needs.
actualTextNoUntagged 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.
outputModeNo'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
outputPathNoRequired when outputMode='file'. Relative path inside the sandbox; must end with .pdf (no absolute paths, no '..').
paragraphsYesOrdered list of paragraphs to render in the chosen script.
typographyNoFine 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.
creationDateNoISO-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.
outputIntentNoCustom 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.
footerTemplateNoRunning footer on every page. Replaces the default footer: footerText is then ignored and page numbers appear only via {page}/{pages}.
headerTemplateNoRunning header on every page (left / center / right zones); reserves 15 pt.
viewerPreferencesNoReader presentation hints (catalog /PageLayout, /PageMode, /ViewerPreferences). PDF/A-safe; all optional.
includeDiagnosticsNoReturn the diagnostics raised while building (PDFA_*, PDFX_*, TYPOGRAPHY_*, TEXT_GLYPH_NOT_COVERED) as `diagnostics[]` (possibly empty).

Output Schema

NameRequiredDescriptionDefault
urlNoPublic URL of the file (file mode, only when PDFNATIVE_MCP_OUTPUT_BASE_URL is set): base URL + sandbox-relative path, percent-encoded.
modeYes
summaryNoTool-specific summary, when produced.
filePathNoSandboxed absolute path (file mode).
sizeBytesYes
diagnosticsNoEngine diagnostics (when includeDiagnostics=true).

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed16 schema fields changedv1.8.0
    • addedInput schema / properties / actualText
      Added 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"
      +}
    • addedInput schema / properties / direction
      Added 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"
      +}
    • addedInput schema / properties / font
      Added 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"
      +}
    • changedInput schema / properties / footerTemplate / properties / color / anyOf
      Previous 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"
      +  }
      +]
    • changedInput schema / properties / headerTemplate / properties / color / anyOf
      Previous 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"
      +  }
      +]
    • changedInput schema / properties / includeDiagnostics / description
      Previous 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)."
    • changedInput schema / properties / lang / anyOf
      Previous 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"
      +  }
      +]
    • changedInput schema / properties / lang / description
      Previous 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."
    • changedInput schema / properties / pdfx / description
      Previous 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."
    • changedInput schema / properties / print / description
      Previous 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."
    • addedInput schema / properties / print / properties / spotColours
      Added 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"
      +}
    • changedInput schema / properties / strict / description
      Previous 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."
    • changedInput schema / properties / typography / description
      Previous 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."
    • changedInput schema / properties / typography / properties / punctuationSpacing / anyOf
      Previous 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"
      +  }
      +]
    • changedOutput schema / description
      Previous 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)."
    • addedOutput schema / properties / url
      Added 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"
      +}
  2. Changed25 schema fields changedv1.6.2
    • changedInput schema / properties / creationDate / description
      Previous 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."
    • changedInput schema / properties / footerTemplate / properties / center / description
      Previous 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)."
    • addedInput schema / properties / footerTemplate / properties / color / anyOf
      Added 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"
      +  }
      +]
    • changedInput schema / properties / footerTemplate / properties / color / description
      Previous value: -"Hex colour."New value: +"Hex colour (#RRGGBB)."
    • removedInput schema / properties / footerTemplate / properties / color / pattern
      Removed value: -"^#[0-9a-fA-F]{6}$"
    • removedInput schema / properties / footerTemplate / properties / color / type
      Removed value: -"string"
    • changedInput schema / properties / footerTemplate / properties / left / description
      Previous 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)."
    • changedInput schema / properties / footerTemplate / properties / right / description
      Previous 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)."
    • changedInput schema / properties / headerTemplate / properties / center / description
      Previous 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)."
    • addedInput schema / properties / headerTemplate / properties / color / anyOf
      Added 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"
      +  }
      +]
    • changedInput schema / properties / headerTemplate / properties / color / description
      Previous value: -"Hex colour."New value: +"Hex colour (#RRGGBB)."
    • removedInput schema / properties / headerTemplate / properties / color / pattern
      Removed value: -"^#[0-9a-fA-F]{6}$"
    • removedInput schema / properties / headerTemplate / properties / color / type
      Removed value: -"string"
    • changedInput schema / properties / headerTemplate / properties / left / description
      Previous 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)."
    • changedInput schema / properties / headerTemplate / properties / right / description
      Previous 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)."
    • changedInput schema / properties / includeDiagnostics / description
      Previous 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)."
    • changedInput schema / properties / lang / anyOf
      Previous 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"
      +  }
      +]
    • changedInput schema / properties / lang / description
      Previous 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."
    • changedInput schema / properties / outputIntent / description
      Previous 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."
    • changedInput schema / properties / outputIntent / properties / iccProfileBase64 / description
      Previous value: -"ICC profile bytes, base64 (RGB, ≤ 8 MiB)."New value: +"ICC profile bytes, base64 (RGB, CMYK or Gray; ≤ 8 MiB)."
    • addedInput schema / properties / pdfx
      Added 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"
      +}
    • changedInput schema / properties / print / properties / marks / oneOf
      Previous 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"
      +  }
      +]
    • changedInput schema / properties / strict / description
      Previous 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."
    • addedInput schema / properties / typography
      Added 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"
      +}
    • changedOutput schema / properties / diagnostics / description
      Previous value: -"PDF/A diagnostics (when includeDiagnostics=true)."New value: +"Engine diagnostics (when includeDiagnostics=true)."
  3. Changed27 schema fields changed
    • addedInput schema / properties / compress
      Added value: +{
      +  "description": "FlateDecode the streams (smaller file, different bytes; PDF/A unaffected, XMP stays plain). Default false.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / creationDate
      Added 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"
      +}
    • addedInput schema / properties / debug
      Added value: +{
      +  "description": "Draw margin / block / cell guide rectangles (unmarked content — not for PDF/UA output). Geometry unchanged. Default false.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / encrypt
      Added 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"
      +}
    • addedInput schema / properties / footerTemplate
      Added 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"
      +}
    • addedInput schema / properties / headerTemplate
      Added 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"
      +}
    • addedInput schema / properties / includeDiagnostics
      Added value: +{
      +  "default": false,
      +  "description": "Return the PDF/A diagnostics raised while building as `diagnostics[]` (possibly empty).",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / lang / anyOf
      Added 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"
      +  }
      +]
    • removedInput schema / properties / lang / oneOf
      Removed 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"
      -  }
      -]
    • addedInput schema / properties / margins
      Added 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"
      +}
    • addedInput schema / properties / metadata
      Added 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"
      +}
    • changedInput schema / properties / normalize / description
      Previous 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."
    • addedInput schema / properties / outputIntent
      Added 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"
      +}
    • addedInput schema / properties / outputMode / description
      Added 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)."
    • addedInput schema / properties / outputPath / description
      Added value: +"Required when outputMode='file'. Relative path inside the sandbox; must end with .pdf (no absolute paths, no '..')."
    • addedInput schema / properties / pageSize
      Added 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"
      +}
    • changedInput schema / properties / pdfA / description
      Previous 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."
    • addedInput schema / properties / print
      Added 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"
      +}
    • addedInput schema / properties / strict
      Added 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"
      +}
    • addedInput schema / properties / viewerPreferences / properties / duplex
      Added 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"
      +}
    • addedInput schema / properties / viewerPreferences / properties / numCopies
      Added 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"
      +}
    • addedInput schema / properties / viewerPreferences / properties / pickTrayByPDFSize
      Added value: +{
      +  "description": "Ask the printer to pick the input tray from the PDF page size (/PickTrayByPDFSize).",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / viewerPreferences / properties / printPageRange
      Added 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"
      +}
    • changedOutput schema / description
      Previous 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`."
    • addedOutput schema / properties / diagnostics
      Added 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"
      +}
    • changedOutput schema / properties / filePath / description
      Previous value: -"Absolute sandboxed file path (when mode='file')."New value: +"Sandboxed absolute path (file mode)."
    • addedOutput schema / properties / summary
      Added value: +{
      +  "additionalProperties": true,
      +  "description": "Tool-specific summary, when produced.",
      +  "type": "object"
      +}
  4. Changed1 schema field changedv1.4.0
    • changedInput schema / properties / lang / oneOf
      Previous 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"
      +  }
      +]
  5. Changed1 schema field changedv1.2.2
    • addedInput schema / properties / viewerPreferences
      Added 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"
      +}
  6. Changed3 schema fields changedv1.2.0
    • addedInput schema / properties / normalize
      Added 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"
      +}
    • addedOutput schema / description
      Added 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."
    • removedOutput schema / properties / base64
      Removed value: -{
      -  "description": "Base64-encoded PDF bytes (when mode='base64').",
      -  "type": "string"
      -}
  7. First observedv1.1.0

TDQS

A3.6/5.0
Behavior4/5

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.

Conciseness3/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.