Skip to main content
Glama

Add native vector chart

add_chart
Idempotent

Generate a single-page PDF with a native vector chart (bar, line, area, scatter, pie, donut) from multi-series data, including legends, axes and label controls.

Instructions

Single-page PDF with a native vector chart (pure path operators, no raster): bar, barH, stackedBar, stackedBarH, line (markers), area, scatter, pie, donut. Multi-series, legends, 'nice' ticks, gridlines, negatives; per-series xValues with xAxis.type 'linear' | 'time' (ISO-8601), secondary right axis (axis2 + yAxis:'right'), axis.scale 'log', dataLabels, labelStride / labelRotation. Pie/donut take exactly one series. Colours are hex ('#3366cc'). Tagged /Figure + /Alt (auto when altText is omitted). Engine cross-field rules surface as CHART_ERROR with the remedy. Inside a longer document use a 'chart' block in generate_basic_pdf. PDF/A (pdfA + embedFonts:true), print, metadata and creationDate as on every document tool.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
axisNoValue-axis options (bar/line only).
pdfANoPDF/A level: pdfa1b (simple text+images), pdfa2b/pdfa2u (richer; 2u = Unicode mapping), pdfa3b (attachments / Factur-X). Pair with embedFonts=true for a valid claim. Exclusive with encryption. See docs/guides/PDFA.md.
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). 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.
alignNoHorizontal alignment within the content width. Default 'left'.
axis2NoSecondary RIGHT value axis (drawn only when a series sets yAxis:'right').
debugNoDraw margin / block / cell guide rectangles (unmarked content — not for PDF/UA output). Geometry unchanged. Default false.
introNoOptional introductory paragraph rendered above the chart. The chart `title` (if any) is also used as the PDF metadata title.
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.
titleNoChart title rendered above the plot.
widthNoPlot width in points (clamped to content width). Default 460.
xAxisNoHorizontal axis. 'category' (default) positions points by index; 'linear' / 'time' position them by series xValues (line/area/scatter only). Time ticks are UTC-deterministic.
colorsNoPalette override (per-series for bar/line, per-slice for pie/donut).
heightNoPlot-area height in points. Default 240.
legendNoLegend placement. Defaults to 'bottom' for multi-series/pie, else 'none'.
seriesYesData series. Pie/donut charts use exactly one series (each value becomes a slice).
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 → DIAGNOSTIC_ESCALATED. Pair with embedFonts=true.
altTextNoAlt text for the tagged-PDF /Figure /Alt. Auto-generated when omitted.
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.
markersNoDraw point markers on line series. Default false.
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.
chartTypeYesChart kind. 'pie'/'donut' use exactly one series; 'bar'/'barH'/'stackedBar'/'stackedBarH'/'line'/'area'/'scatter' support multiple series. 'scatter' requires xValues on every series and a positional xAxis.type ('linear' or 'time').
categoriesNoCategory / slice labels (x-axis). Defaults to 1-based indices when omitted.
dataLabelsNoPer-point value labels: true for defaults, or an object to format them.
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.
outputModeNoEither 'base64' (returns the PDF inline) or 'file' (writes into the PDFNATIVE_MCP_OUTPUT_DIR sandbox).base64
outputPathNoRequired when outputMode='file'. Relative path inside the sandbox; must end with .pdf.
typographyNoFine 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.
labelStrideNoDraw every Nth category label. Default: automatic (measured non-overlap); 1 draws every label.
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.
labelRotationNoRotate category labels counter-clockwise by this many degrees (disables the automatic stride).
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_*) as `diagnostics[]` (possibly empty).

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
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. Changed30 schema fields changedv1.6.2
    • addedInput schema / properties / colors / items / 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"
      +  }
      +]
    • removedInput schema / properties / colors / items / pattern
      Removed value: -"^#?[0-9a-fA-F]{6}$"
    • removedInput schema / properties / colors / items / type
      Removed value: -"string"
    • 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)."
    • 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"
      +  }
      +]
    • addedInput schema / properties / series / items / 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"
      +  }
      +]
    • removedInput schema / properties / series / items / properties / color / pattern
      Removed value: -"^#?[0-9a-fA-F]{6}$"
    • removedInput schema / properties / series / items / properties / color / type
      Removed value: -"string"
    • 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)."
  2. Changed29 schema fields changed
    • addedInput schema / properties / axis / properties / scale
      Added value: +{
      +  "description": "Value-axis scale. 'log' requires strictly positive values and is not available for stacked charts.",
      +  "enum": [
      +    "linear",
      +    "log"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / axis2
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Secondary RIGHT value axis (drawn only when a series sets yAxis:'right').",
      +  "properties": {
      +    "scale": {
      +      "enum": [
      +        "linear",
      +        "log"
      +      ],
      +      "type": "string"
      +    },
      +    "ticks": {
      +      "maximum": 20,
      +      "minimum": 2,
      +      "type": "integer"
      +    },
      +    "yMax": {
      +      "type": "number"
      +    },
      +    "yMin": {
      +      "type": "number"
      +    }
      +  },
      +  "type": "object"
      +}
    • changedInput schema / properties / chartType / description
      Previous value: -"Chart kind. 'pie'/'donut' use exactly one series; 'bar'/'barH'/'line' support multiple series."New value: +"Chart kind. 'pie'/'donut' use exactly one series; 'bar'/'barH'/'stackedBar'/'stackedBarH'/'line'/'area'/'scatter' support multiple series. 'scatter' requires xValues on every series and a positional xAxis.type ('linear' or 'time')."
    • changedInput schema / properties / chartType / enum
      Previous value: -[
      -  "bar",
      -  "barH",
      -  "line",
      -  "pie",
      -  "donut"
      -]New value: +[
      +  "bar",
      +  "barH",
      +  "stackedBar",
      +  "stackedBarH",
      +  "line",
      +  "area",
      +  "scatter",
      +  "pie",
      +  "donut"
      +]
    • 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 / dataLabels
      Added value: +{
      +  "description": "Per-point value labels: true for defaults, or an object to format them.",
      +  "oneOf": [
      +    {
      +      "type": "boolean"
      +    },
      +    {
      +      "additionalProperties": false,
      +      "properties": {
      +        "decimals": {
      +          "maximum": 6,
      +          "minimum": 0,
      +          "type": "integer"
      +        },
      +        "prefix": {
      +          "maxLength": 16,
      +          "type": "string"
      +        },
      +        "suffix": {
      +          "maxLength": 16,
      +          "type": "string"
      +        }
      +      },
      +      "type": "object"
      +    }
      +  ]
      +}
    • 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 / 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 / labelRotation
      Added value: +{
      +  "description": "Rotate category labels counter-clockwise by this many degrees (disables the automatic stride).",
      +  "maximum": 90,
      +  "minimum": 0,
      +  "type": "number"
      +}
    • addedInput schema / properties / labelStride
      Added value: +{
      +  "description": "Draw every Nth category label. Default: automatic (measured non-overlap); 1 draws every label.",
      +  "maximum": 1000,
      +  "minimum": 1,
      +  "type": "integer"
      +}
    • 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 / 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 (powered by pdfnative v1.2). Use 'pdfa1b' for archival of simple text+images, 'pdfa2b'/'pdfa2u' for richer content (2u guarantees Unicode mapping), 'pdfa3b' when embedding source attachments (Factur-X / ZUGFeRD). Mutually exclusive with PDF encryption. See docs/guides/PDFA.md."New value: +"PDF/A level: pdfa1b (simple text+images), pdfa2b/pdfa2u (richer; 2u = Unicode mapping), pdfa3b (attachments / Factur-X). Pair with embedFonts=true for a valid claim. Exclusive with encryption. See docs/guides/PDFA.md."
    • 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 / series / items / properties / xValues
      Added value: +{
      +  "description": "Per-point x positions (same length as values) for scatter charts and for line/area charts with xAxis.type 'linear' or 'time'.",
      +  "items": {
      +    "description": "Positional x value: a number (linear axis) or an ISO-8601 date / epoch milliseconds (time axis).",
      +    "maxLength": 64,
      +    "type": [
      +      "number",
      +      "string"
      +    ]
      +  },
      +  "maxItems": 1000,
      +  "minItems": 1,
      +  "type": "array"
      +}
    • addedInput schema / properties / series / items / properties / yAxis
      Added value: +{
      +  "description": "Bind the series to the left (default) or the secondary right value axis (cartesian charts only; configure its range with 'axis2').",
      +  "enum": [
      +    "left",
      +    "right"
      +  ],
      +  "type": "string"
      +}
    • 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 / xAxis
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Horizontal axis. 'category' (default) positions points by index; 'linear' / 'time' position them by series xValues (line/area/scatter only). Time ticks are UTC-deterministic.",
      +  "properties": {
      +    "grid": {
      +      "description": "Draw vertical gridlines.",
      +      "type": "boolean"
      +    },
      +    "max": {
      +      "description": "Axis maximum (number, or ISO-8601 / epoch ms for time axes).",
      +      "maxLength": 64,
      +      "type": [
      +        "number",
      +        "string"
      +      ]
      +    },
      +    "min": {
      +      "description": "Axis minimum (number, or ISO-8601 / epoch ms for time axes).",
      +      "maxLength": 64,
      +      "type": [
      +        "number",
      +        "string"
      +      ]
      +    },
      +    "ticks": {
      +      "maximum": 20,
      +      "minimum": 2,
      +      "type": "integer"
      +    },
      +    "type": {
      +      "enum": [
      +        "category",
      +        "linear",
      +        "time"
      +      ],
      +      "type": "string"
      +    }
      +  },
      +  "type": "object"
      +}
    • 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"
      +}
  3. Addedv1.6.0

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=false, idempotentHint=true and destructiveHint=false, but the description adds substantive behavior beyond them: alt text is auto-generated when omitted, /Figure tagging, cross-field engine rules surfacing as CHART_ERROR with the remedy, and the PDF/A requirement (pdfA + embedFonts:true, plus print/metadata/creationDate notes). That is real operational context an agent needs before calling a 37-parameter generator.

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?

Purpose and chart types are front-loaded and almost every clause carries information, so there is little waste. However, the whole description is a single run-on paragraph that mixes chart-feature semantics with PDF/A, print and metadata concerns, producing a dense wall of semicolon clauses that is hard to scan before a call.

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?

With an output schema present, return values need no explanation, and the 100%-covered schema carries the per-field detail. The description covers the headline capabilities and the composition/PDF-A constraints, which is sufficient for a tool of this complexity, though it does not mention pagination/sandbox expectations for outputMode beyond what the schema says.

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 description coverage is 100%, so the baseline is 3. The description earns the extra point by explaining cross-parameter coupling that the flat schema only states locally: per-series xValues must pair with xAxis.type 'linear'|'time', the secondary axis is engaged only via axis2 + series yAxis:'right', and pie/donut accept exactly one series. Those are integration-level semantics rather than restatements.

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?

Specific verb+resource ('Add native vector chart') immediately qualified by what it produces ('Single-page PDF with a native vector chart ... pure path operators, no raster') and an enumerated chart-type list that an agent can match against a request. It also routes the agent to the sibling case ('Inside a longer document use a 'chart' block in generate_basic_pdf'), so add_chart is clearly distinguishable from generate_basic_pdf.

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 an explicit alternative and the condition that selects it: standalone one-chart PDFs here, embedded charts via generate_basic_pdf's 'chart' block in longer documents. It also states form constraints (pie/donut take exactly one series). It does not spell out when the tool should not be used at all (e.g. raster image charts), so it stops short of full when/when-not coverage.

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