Skip to main content
Glama
Nizoka

pdfnative-mcp

Add international text

add_international_text
Idempotent

Generate a PDF with correctly rendered text in Arabic, Hebrew, Thai, CJK, Devanagari, Bengali, and Greek. Handles right-to-left BiDi, Arabic joining, complex scripts, and math symbols automatically.

Instructions

PDF rendering text in 24 scripts (Arabic, Hebrew, Thai, CJK, Devanagari, Bengali, Tamil, Telugu, Sinhala, Tibetan, Khmer, Myanmar, Ethiopic, Cyrillic, Greek, Georgian, Armenian, Vietnamese, …), 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

TableJSON Schema
NameRequiredDescriptionDefault
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).
pdfANoPDF/A level (Tagged PDF + sRGB OutputIntent + XMP). Fonts are embedded here, so the claim is valid as-is. See docs/guides/PDFA.md.
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). See docs/guides/PRINT.md.
titleYesPDF title (rendered as page heading and stored as document metadata).
strictNoFail 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.
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.
normalizeNoUnicode normalization before shaping. Default 'NFC' (widest glyph coverage); NFD/NFKC/NFKD or false for special needs.
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.
creationDateNoISO-8601 instant for /CreationDate (+ XMP). Pin it for byte-identical output across calls (same host TZ); omitted = wall clock, so every call differs.
outputIntentNoCustom PDF/A OutputIntent: an RGB ICC profile + condition strings replacing the built-in sRGB intent (CMYK rejected).
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 PDF/A diagnostics raised while building as `diagnostics[]` (possibly empty).

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
modeYes
summaryNoTool-specific summary, when produced.
filePathNoSandboxed absolute path (file mode).
sizeBytesYes
diagnosticsNoPDF/A diagnostics (when includeDiagnostics=true).

Schema Changelog

Changes observed during successful MCP inspections.

  1. 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"
      +}
  2. 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"
      +  }
      +]
  3. 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"
      +}
  4. 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"
      -}
  5. First observedv1.1.0

TDQS

A4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, the description discloses important behavioral facts: BiDi, Arabic joining, complex-script shaping, NFC normalization, newlines become paragraphs, and fonts are always embedded so embedFonts does not exist. This is exactly the kind of behavior an agent cannot infer from the schema alone, and it contradicts no annotation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three-to-five dense sentences deliver a lot of ground without filler. The heavy script list is pruned with ellipsis, behavioral facts are front-loaded, and shared document options are collapsed into one phrase. It could trim a little, but it commits no wasted words.

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 complex tool with 21 parameters, an output schema, and nested objects, this description covers the critical behavioral and parameter concerns. It could still be improved by naming the typical alternative for plain-Latin text, but it is nearly complete as it stands for selecting and calling the tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so a baseline of 3 applies, but the description adds real semantics: lang can be either a single code or an array for mixed runs, newlines split paragraphs, and Unicode normalization behavior is explicitly described. This is genuinely useful beyond the schema, though not exhaustive.

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?

The description clearly identifies the tool as rendering PDF text in 24 scripts plus emoji and math, which distinguishes it from siblings like add_table, add_barcode, and add_chart. It does not explicitly state that it creates a new PDF document or position itself against generate_basic_pdf, so it stops just 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.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a strong capability profile: international scripts, automatic shaping, always-embedded fonts, and no embedFonts option. However, it never explicitly says when to use this tool instead of a sibling such as generate_basic_pdf or add_table, so the when-to-use guidance 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.