Skip to main content
Glama

Add embedded file attachment (PDF/A-3, Factur-X)

add_attachment
Idempotent

Create PDF/A-3b documents with embedded files to generate Factur-X or ZUGFeRD e-invoices and attach machine-readable side files.

Instructions

PDF/A-3b document with embedded files — the tool for Factur-X / ZUGFeRD e-invoices (one XML attachment, relationship 'Source', mimeType application/xml) or any PDF carrying machine-readable side-files (≤ 8 MiB each). Body via blocks (same schema as generate_basic_pdf). Pair with embedFonts:true for a valid PDF/A-3 claim (strict:true fails otherwise). Read them back with extract_attachments. Print, metadata and creationDate options as on every document tool.

Input Schema

NameRequiredDescriptionDefault
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.
titleYesDocument title (also written to the /Info dictionary).
blocksNoOptional human-readable document body (same block schema as generate_basic_pdf). When omitted, a minimal cover paragraph is emitted so the PDF is not empty.
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.
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).
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.
embedFontsNoEmbed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A or PDF/X claim (every font embedded) and for strict=true; adds ~0.3 MiB.
footerTextNoOptional footer text rendered on every page.
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 '..').
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.
attachmentsYesOne or more files to embed. Auto-enables PDF/A-3 (ISO 19005-3). Factur-X invoices use a single attachment with relationship=Source and mimeType=application/xml.
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.
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. Changed12 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"
      +}
    • 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 / 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. Changed23 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 / embedFonts / description
      Previous value: -"Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A claim (ISO 19005 §6.2.11.4.1) and for strict=true; adds ~0.3 MiB."New value: +"Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A or PDF/X claim (every font embedded) and for strict=true; adds ~0.3 MiB."
    • 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 / 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)."
    • 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. Changed19 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 / embedFonts
      Added value: +{
      +  "default": false,
      +  "description": "Embed Noto Sans Latin instead of the viewer base-14 Helvetica. REQUIRED for a valid PDF/A claim (ISO 19005 §6.2.11.4.1) and for strict=true; adds ~0.3 MiB.",
      +  "type": "boolean"
      +}
    • 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 / 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"
      +}
    • 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"
      +}
    • 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"
      +}
    • 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. Changed2 schema fields changedv1.2.0
    • 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.2/5.0
Behavior4/5

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

Annotations already cover safety (readOnlyHint false, idempotent true, destructive false), so this is a non-destructive idempotent create. The description adds real behavioral facts beyond them: the ≤8 MiB per-attachment limit, that embedFonts:true is required for a valid PDF/A-3 claim, and that strict:true will fail otherwise. It does not mention that attachments auto-enable PDF/A-3 (that lives only in the schema) or what happens on soft failures.

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

Conciseness4/5

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

Four tight clauses, front-loaded with the artifact and the primary use case before secondary constraints. Dense but every sentence carries information; only the trailing 'creationDate options as on every document tool' is filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 22-parameter tool with an output schema, the description correctly focuses on what the schema cannot tell the agent: the compliance envelope (embedFonts/strict interlock), the attachment size cap, and reuse of the sibling's block schema. Return values are covered by the output schema, so nothing essential is missing.

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

Parameters3/5

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

Schema coverage is 100%, so every parameter is already documented in schema, and the baseline is 3. The description adds modest cross-reference value — blocks shares generate_basic_pdf's schema and print/metadata/creationDate behave as on other document tools — but supplies no semantics for the attachment-specific fields (filename, relationship, dataBase64) that justify the tool.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb and artifact: a PDF/A-3b document with embedded files, and pins the flagship use case (Factur-X / ZUGFeRD with one XML attachment, relationship 'Source', mimeType application/xml). It also distinguishes itself from siblings by delegating page content to generate_basic_pdf's block schema and pointing to extract_attachments for the inverse operation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

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

Gives a clear when-to-use signal: e-invoices or any PDF carrying machine-readable side-files, with a per-file size cap. It routes to extract_attachments for readback and to generate_basic_pdf for the block schema, but never states the obvious exclusion (use generate_basic_pdf if you have no attachment to embed), leaving that to the required-parameter schema.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.