Skip to main content
Glama

Change a sheet

change_sheet
Destructive

Change a sheet, in order: design {design} lays an empty sheet out as a template is (heading, tables with totals, formats, dropdown and checkbox columns, fields, notes, charts; in a look and an accent, widths fitted, header frozen), set {at, rows} writes rows of values from a cell (text read as typed in en-GB, a leading = a formula), clear {range}, format {range, format}, border {range, sides}, merge {range}, unmerge {range}, resize {cols or rows, px or fit}, insert_rows {at, count}, insert_cols {at, count}, delete_rows {rows}, delete_cols {cols}, rename {title}, sort {by, range}, freeze {rows, cols}, filter {range}, validate {range, rule} (dropdowns, checkboxes, number, date and text rules), conditional_format {range, when or scale, style}, chart {type, range} (a chart over the cells, read live), clear_charts {range}. Cells by A1, rows by number, columns by letter. A formula that cannot be read is refused, naming the cell. Everyone with the document open sees each change at once.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
sheetYesThe sheet, by its title ("Budget") or id. list_sheets lists them.
changesYesApplied in order; each sees the sheet as the ones before it left it (an inserted row moves the rows below it). A refused change stops the rest.
documentIdYesThe document (from find_documents).

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
revYesThe sheet revision after them; null when nothing was written.
urlYesLink that opens the document in the livediagram editor.
titleYesIts title now.
appliedYesOne line per change, in order.
sheetIdYesThe sheet id.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / changes / items / oneOf
      Previous value: -[
      -  {
      -    "properties": {
      -      "at": {
      -        "description": "The top-left cell, in A1 form (\"A1\").",
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "set",
      -        "description": "Write rows of values from a cell.",
      -        "type": "string"
      -      },
      -      "rows": {
      -        "description": "Rows of values, top to bottom; the sheet grows to fit, up to 10,000 rows and 200 columns.",
      -        "items": {
      -          "description": "One row, left to right.",
      -          "items": {
      -            "description": "A value: text is read as typed in en-GB (a leading = is a formula, \"12%\" a percent, \"03/04/2026\" the 3rd of April), a JSON number or boolean is kept as it is, null clears the cell.",
      -            "type": [
      -              "string",
      -              "number",
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "maxItems": 200,
      -          "type": "array"
      -        },
      -        "maxItems": 10000,
      -        "type": "array"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "at",
      -      "rows"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "op": {
      -        "const": "clear",
      -        "description": "Clear a range.",
      -        "type": "string"
      -      },
      -      "range": {
      -        "description": "A cell or range in A1 form: \"B4\", \"A1:D20\".",
      -        "type": "string"
      -      },
      -      "what": {
      -        "description": "What to clear: inputs, formats, or all (the default).",
      -        "enum": [
      -          "inputs",
      -          "formats",
      -          "all"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "range"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "format": {
      -        "description": "The parts of the format to set; parts left out are kept.",
      -        "properties": {
      -          "align": {
      -            "anyOf": [
      -              {
      -                "enum": [
      -                  "left",
      -                  "center",
      -                  "right"
      -                ],
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "Horizontal alignment; null for automatic (numbers right, text left)."
      -          },
      -          "background": {
      -            "description": "Fill colour, #rrggbb; null for none.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "bold": {
      -            "description": "Bold on (true) or off (false).",
      -            "type": "boolean"
      -          },
      -          "color": {
      -            "description": "Text colour, #rrggbb; null for the default.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "currency": {
      -            "description": "The currency symbol: R$ CHF zł kr £ $ € ¥ ₹ ₩ ₽ ₺ ₪ ₫; null for the default.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "decimals": {
      -            "anyOf": [
      -              {
      -                "maximum": 10,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "Decimal places, 0 to 10; null for the format’s own."
      -          },
      -          "fontSize": {
      -            "description": "Font size in points, a whole number from 6 to 96; null for the default.",
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "italic": {
      -            "description": "Italic on or off.",
      -            "type": "boolean"
      -          },
      -          "numberFormat": {
      -            "description": "How numbers show: auto, number, percent, currency, accounting, scientific, date, time, datetime, duration, text, custom; null for auto.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "strikethrough": {
      -            "description": "Strikethrough on or off.",
      -            "type": "boolean"
      -          },
      -          "underline": {
      -            "description": "Underline on or off.",
      -            "type": "boolean"
      -          },
      -          "verticalAlign": {
      -            "anyOf": [
      -              {
      -                "enum": [
      -                  "top",
      -                  "middle",
      -                  "bottom"
      -                ],
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "Vertical alignment; null for the default (bottom)."
      -          },
      -          "wrap": {
      -            "anyOf": [
      -              {
      -                "enum": [
      -                  "overflow",
      -                  "wrap",
      -                  "clip"
      -                ],
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "Long text runs over empty neighbours, wraps, or is clipped; null for overflow."
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "op": {
      -        "const": "format",
      -        "description": "Format a range.",
      -        "type": "string"
      -      },
      -      "range": {
      -        "description": "A cell or range in A1 form: \"B4\", \"A1:D20\".",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "range",
      -      "format"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "at": {
      -        "description": "The row number they go beside (1 is the first row).",
      -        "maximum": 9007199254740991,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "count": {
      -        "description": "How many (default 1).",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "op": {
      -        "const": "insert_rows",
      -        "description": "Insert rows.",
      -        "type": "string"
      -      },
      -      "side": {
      -        "description": "Before (the default) or after it.",
      -        "enum": [
      -          "before",
      -          "after"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "at"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "at": {
      -        "description": "The column letter they go beside (\"C\").",
      -        "type": "string"
      -      },
      -      "count": {
      -        "description": "How many (default 1).",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "op": {
      -        "const": "insert_cols",
      -        "description": "Insert columns.",
      -        "type": "string"
      -      },
      -      "side": {
      -        "description": "Before (the default) or after it.",
      -        "enum": [
      -          "before",
      -          "after"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "at"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "op": {
      -        "const": "delete_rows",
      -        "description": "Delete rows, and their cells.",
      -        "type": "string"
      -      },
      -      "rows": {
      -        "description": "A row number or a span: \"3\", \"3:5\".",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "rows"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "cols": {
      -        "description": "A column letter or a span: \"C\", \"C:E\".",
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "delete_cols",
      -        "description": "Delete columns, and their cells.",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "cols"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "op": {
      -        "const": "rename",
      -        "description": "Rename the sheet.",
      -        "type": "string"
      -      },
      -      "title": {
      -        "description": "The new title, 1 to 60 characters, unique on its tab.",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "title"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "by": {
      -        "description": "The column to sort by, by letter (\"B\").",
      -        "type": "string"
      -      },
      -      "descending": {
      -        "description": "Z to A, largest first (default A to Z).",
      -        "type": "boolean"
      -      },
      -      "header": {
      -        "description": "The range’s first row is a header and stays put.",
      -        "type": "boolean"
      -      },
      -      "op": {
      -        "const": "sort",
      -        "description": "Sort rows by a column.",
      -        "type": "string"
      -      },
      -      "range": {
      -        "description": "Only this range’s cells move. Left out, the whole sheet’s rows are reordered (frozen rows stay).",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "by"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "cols": {
      -        "description": "Columns to freeze; 0 unfreezes.",
      -        "maximum": 26,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "op": {
      -        "const": "freeze",
      -        "description": "Freeze rows and columns at the top and left.",
      -        "type": "string"
      -      },
      -      "rows": {
      -        "description": "Rows to freeze; 0 unfreezes.",
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "integer"
      -      }
      -    },
      -    "required": [
      -      "op"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "help": {
      -        "description": "Said when a value is refused.",
      -        "maxLength": 255,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "validate",
      -        "description": "Set what a range may hold (a dropdown, a checkbox, a number, date or text rule); it replaces the rules the range covered.",
      -        "type": "string"
      -      },
      -      "range": {
      -        "description": "A cell or range in A1 form: \"B4\", \"A1:D20\".",
      -        "type": "string"
      -      },
      -      "reject": {
      -        "description": "Refuse a value it does not allow (default true); false keeps it and marks it.",
      -        "type": "boolean"
      -      },
      -      "rule": {
      -        "description": "The rule.",
      -        "oneOf": [
      -          {
      -            "properties": {
      -              "colors": {
      -                "description": "A colour per option, #rrggbb, or null.",
      -                "items": {
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "type": "array"
      -              },
      -              "display": {
      -                "description": "How it shows (default chip).",
      -                "enum": [
      -                  "chip",
      -                  "arrow",
      -                  "plain"
      -                ],
      -                "type": "string"
      -              },
      -              "options": {
      -                "description": "The values offered, in order.",
      -                "items": {
      -                  "type": "string"
      -                },
      -                "maxItems": 500,
      -                "minItems": 1,
      -                "type": "array"
      -              },
      -              "type": {
      -                "const": "dropdown",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "options"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "properties": {
      -              "display": {
      -                "enum": [
      -                  "chip",
      -                  "arrow",
      -                  "plain"
      -                ],
      -                "type": "string"
      -              },
      -              "source": {
      -                "description": "The cells (on this sheet) whose values are offered, \"A2:A20\".",
      -                "type": "string"
      -              },
      -              "type": {
      -                "const": "dropdown_range",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "source"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "properties": {
      -              "type": {
      -                "const": "checkbox",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "properties": {
      -              "condition": {
      -                "description": "number: between, not_between, greater_than, greater_than_or_equal, less_than, less_than_or_equal, equal, not_equal. date: valid, before, on_or_before, after, on_or_after, on, between, not_between. text: contains, not_contains, exactly, email, url.",
      -                "type": "string"
      -              },
      -              "type": {
      -                "enum": [
      -                  "number",
      -                  "date",
      -                  "text"
      -                ],
      -                "type": "string"
      -              },
      -              "value": {
      -                "description": "A number, a date (YYYY-MM-DD) or text.",
      -                "type": [
      -                  "number",
      -                  "string"
      -                ]
      -              },
      -              "value2": {
      -                "description": "The second value of between.",
      -                "type": [
      -                  "number",
      -                  "string"
      -                ]
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "condition"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "range",
      -      "rule"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "op": {
      -        "const": "clear_validation",
      -        "description": "Take a range out of every validation rule.",
      -        "type": "string"
      -      },
      -      "range": {
      -        "description": "A cell or range in A1 form: \"B4\", \"A1:D20\".",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "range"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "op": {
      -        "const": "conditional_format",
      -        "description": "Add a format rule (last in the list): a condition and a style, or a colour scale.",
      -        "type": "string"
      -      },
      -      "range": {
      -        "description": "A cell or range in A1 form: \"B4\", \"A1:D20\".",
      -        "type": "string"
      -      },
      -      "scale": {
      -        "description": "A colour scale instead of when: each number shaded between the points.",
      -        "properties": {
      -          "max": {
      -            "properties": {
      -              "color": {
      -                "description": "#rrggbb",
      -                "type": "string"
      -              },
      -              "type": {
      -                "enum": [
      -                  "min",
      -                  "max",
      -                  "number",
      -                  "percent",
      -                  "percentile"
      -                ],
      -                "type": "string"
      -              },
      -              "value": {
      -                "description": "For number, percent and percentile.",
      -                "type": "number"
      -              }
      -            },
      -            "required": [
      -              "color",
      -              "type"
      -            ],
      -            "type": "object"
      -          },
      -          "mid": {
      -            "properties": {
      -              "color": {
      -                "description": "#rrggbb",
      -                "type": "string"
      -              },
      -              "type": {
      -                "enum": [
      -                  "min",
      -                  "max",
      -                  "number",
      -                  "percent",
      -                  "percentile"
      -                ],
      -                "type": "string"
      -              },
      -              "value": {
      -                "description": "For number, percent and percentile.",
      -                "type": "number"
      -              }
      -            },
      -            "required": [
      -              "color",
      -              "type"
      -            ],
      -            "type": "object"
      -          },
      -          "min": {
      -            "properties": {
      -              "color": {
      -                "description": "#rrggbb",
      -                "type": "string"
      -              },
      -              "type": {
      -                "enum": [
      -                  "min",
      -                  "max",
      -                  "number",
      -                  "percent",
      -                  "percentile"
      -                ],
      -                "type": "string"
      -              },
      -              "value": {
      -                "description": "For number, percent and percentile.",
      -                "type": "number"
      -              }
      -            },
      -            "required": [
      -              "color",
      -              "type"
      -            ],
      -            "type": "object"
      -          }
      -        },
      -        "required": [
      -          "min",
      -          "max"
      -        ],
      -        "type": "object"
      -      },
      -      "style": {
      -        "description": "when's style.",
      -        "properties": {
      -          "background": {
      -            "description": "#rrggbb",
      -            "type": "string"
      -          },
      -          "bold": {
      -            "type": "boolean"
      -          },
      -          "color": {
      -            "description": "#rrggbb",
      -            "type": "string"
      -          },
      -          "italic": {
      -            "type": "boolean"
      -          },
      -          "strikethrough": {
      -            "type": "boolean"
      -          },
      -          "underline": {
      -            "type": "boolean"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "when": {
      -        "properties": {
      -          "condition": {
      -            "description": "empty, not_empty, contains, not_contains, starts_with, ends_with, exactly, date_before, date_after, date_on, greater_than, greater_than_or_equal, less_than, less_than_or_equal, between, equal, not_equal, or formula.",
      -            "type": "string"
      -          },
      -          "formula": {
      -            "description": "formula's: written for the range's top-left cell, like =$C2>100.",
      -            "type": "string"
      -          },
      -          "value": {
      -            "type": [
      -              "string",
      -              "number"
      -            ]
      -          },
      -          "value2": {
      -            "description": "The second value of between.",
      -            "type": [
      -              "string",
      -              "number"
      -            ]
      -          }
      -        },
      -        "required": [
      -          "condition"
      -        ],
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "range"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "op": {
      -        "const": "clear_conditional_formats",
      -        "description": "Remove the format rules touching a range, or every one.",
      -        "type": "string"
      -      },
      -      "range": {
      -        "description": "A cell or range in A1 form: \"B4\", \"A1:D20\".",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "properties": {
      +      "at": {
      +        "description": "The top-left cell, in A1 form (\"A1\").",
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "set",
      +        "description": "Write rows of values from a cell.",
      +        "type": "string"
      +      },
      +      "rows": {
      +        "description": "Rows of values, top to bottom; the sheet grows to fit, up to 10,000 rows and 200 columns.",
      +        "items": {
      +          "description": "One row, left to right.",
      +          "items": {
      +            "description": "A value: text is read as typed in en-GB (a leading = is a formula, \"12%\" a percent, \"03/04/2026\" the 3rd of April), a JSON number or boolean is kept as it is, null clears the cell.",
      +            "type": [
      +              "string",
      +              "number",
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "maxItems": 200,
      +          "type": "array"
      +        },
      +        "maxItems": 10000,
      +        "type": "array"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "at",
      +      "rows"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "clear",
      +        "description": "Clear a range.",
      +        "type": "string"
      +      },
      +      "range": {
      +        "description": "A cell or range in A1 form: \"B4\", \"A1:D20\".",
      +        "type": "string"
      +      },
      +      "what": {
      +        "description": "What to clear: inputs, formats, or all (the default).",
      +        "enum": [
      +          "inputs",
      +          "formats",
      +          "all"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "range"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "format": {
      +        "description": "The parts of the format to set; parts left out are kept.",
      +        "properties": {
      +          "align": {
      +            "anyOf": [
      +              {
      +                "enum": [
      +                  "left",
      +                  "center",
      +                  "right"
      +                ],
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Horizontal alignment; null for automatic (numbers right, text left)."
      +          },
      +          "background": {
      +            "description": "Fill colour, #rrggbb; null for none.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "bold": {
      +            "description": "Bold on (true) or off (false).",
      +            "type": "boolean"
      +          },
      +          "color": {
      +            "description": "Text colour, #rrggbb; null for the default.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "currency": {
      +            "description": "The currency symbol: R$ CHF zł kr £ $ € ¥ ₹ ₩ ₽ ₺ ₪ ₫; null for the default.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "decimals": {
      +            "anyOf": [
      +              {
      +                "maximum": 10,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Decimal places, 0 to 10; null for the format’s own."
      +          },
      +          "fontSize": {
      +            "description": "Font size in points, a whole number from 6 to 96; null for the default.",
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "italic": {
      +            "description": "Italic on or off.",
      +            "type": "boolean"
      +          },
      +          "numberFormat": {
      +            "description": "How numbers show: auto, number, percent, currency, accounting, scientific, date, time, datetime, duration, text, custom; null for auto.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "strikethrough": {
      +            "description": "Strikethrough on or off.",
      +            "type": "boolean"
      +          },
      +          "underline": {
      +            "description": "Underline on or off.",
      +            "type": "boolean"
      +          },
      +          "verticalAlign": {
      +            "anyOf": [
      +              {
      +                "enum": [
      +                  "top",
      +                  "middle",
      +                  "bottom"
      +                ],
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Vertical alignment; null for the default (bottom)."
      +          },
      +          "wrap": {
      +            "anyOf": [
      +              {
      +                "enum": [
      +                  "overflow",
      +                  "wrap",
      +                  "clip"
      +                ],
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Long text runs over empty neighbours, wraps, or is clipped; null for overflow."
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "op": {
      +        "const": "format",
      +        "description": "Format a range.",
      +        "type": "string"
      +      },
      +      "range": {
      +        "description": "A cell or range in A1 form: \"B4\", \"A1:D20\".",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "range",
      +      "format"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "at": {
      +        "description": "The row number they go beside (1 is the first row).",
      +        "maximum": 9007199254740991,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "count": {
      +        "description": "How many (default 1).",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "op": {
      +        "const": "insert_rows",
      +        "description": "Insert rows. They take the formats of the row above them (below, at the top), so a table keeps its look. Formulas, rules and charts reading a range grow with rows inserted inside it, not at its edge.",
      +        "type": "string"
      +      },
      +      "side": {
      +        "description": "Before (the default) or after it.",
      +        "enum": [
      +          "before",
      +          "after"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "at"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "at": {
      +        "description": "The column letter they go beside (\"C\").",
      +        "type": "string"
      +      },
      +      "count": {
      +        "description": "How many (default 1).",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "op": {
      +        "const": "insert_cols",
      +        "description": "Insert columns. They take the look of the column left of them (right, at the left edge), not its number format. Formulas, rules and charts reading a range grow with columns inserted inside it, not at its edge; charts keep to the cells they sit on.",
      +        "type": "string"
      +      },
      +      "side": {
      +        "description": "Before (the default) or after it.",
      +        "enum": [
      +          "before",
      +          "after"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "at"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "delete_rows",
      +        "description": "Delete rows, and their cells.",
      +        "type": "string"
      +      },
      +      "rows": {
      +        "description": "A row number or a span: \"3\", \"3:5\".",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "rows"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "cols": {
      +        "description": "A column letter or a span: \"C\", \"C:E\".",
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "delete_cols",
      +        "description": "Delete columns, and their cells.",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "cols"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "rename",
      +        "description": "Rename the sheet.",
      +        "type": "string"
      +      },
      +      "title": {
      +        "description": "The new title, 1 to 60 characters, unique on its tab.",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "title"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "by": {
      +        "description": "The column to sort by, by letter (\"B\").",
      +        "type": "string"
      +      },
      +      "descending": {
      +        "description": "Z to A, largest first (default A to Z).",
      +        "type": "boolean"
      +      },
      +      "header": {
      +        "description": "The range’s first row is a header and stays put.",
      +        "type": "boolean"
      +      },
      +      "op": {
      +        "const": "sort",
      +        "description": "Sort rows by a column.",
      +        "type": "string"
      +      },
      +      "range": {
      +        "description": "Only this range’s cells move. Left out, the whole sheet’s rows are reordered (frozen rows stay).",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "by"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "cols": {
      +        "description": "Columns to freeze; 0 unfreezes.",
      +        "maximum": 26,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "op": {
      +        "const": "freeze",
      +        "description": "Freeze rows and columns at the top and left.",
      +        "type": "string"
      +      },
      +      "rows": {
      +        "description": "Rows to freeze; 0 unfreezes.",
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "integer"
      +      }
      +    },
      +    "required": [
      +      "op"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "help": {
      +        "description": "Said when a value is refused.",
      +        "maxLength": 255,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "validate",
      +        "description": "Set what a range may hold (a dropdown, a checkbox, a number, date or text rule); it replaces the rules the range covered.",
      +        "type": "string"
      +      },
      +      "range": {
      +        "description": "A cell or range in A1 form: \"B4\", \"A1:D20\".",
      +        "type": "string"
      +      },
      +      "reject": {
      +        "description": "Refuse a value it does not allow (default true); false keeps it and marks it.",
      +        "type": "boolean"
      +      },
      +      "rule": {
      +        "description": "The rule.",
      +        "oneOf": [
      +          {
      +            "properties": {
      +              "colors": {
      +                "description": "A colour per option, #rrggbb, or null.",
      +                "items": {
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "type": "array"
      +              },
      +              "display": {
      +                "description": "How it shows (default chip).",
      +                "enum": [
      +                  "chip",
      +                  "arrow",
      +                  "plain"
      +                ],
      +                "type": "string"
      +              },
      +              "options": {
      +                "description": "The values offered, in order.",
      +                "items": {
      +                  "type": "string"
      +                },
      +                "maxItems": 500,
      +                "minItems": 1,
      +                "type": "array"
      +              },
      +              "type": {
      +                "const": "dropdown",
      +                "description": "A rule is a dropdown, dropdown_range, checkbox, number, date or text.",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "options"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "properties": {
      +              "display": {
      +                "enum": [
      +                  "chip",
      +                  "arrow",
      +                  "plain"
      +                ],
      +                "type": "string"
      +              },
      +              "source": {
      +                "description": "The cells (on this sheet) whose values are offered, \"A2:A20\".",
      +                "type": "string"
      +              },
      +              "type": {
      +                "const": "dropdown_range",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "source"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "properties": {
      +              "type": {
      +                "const": "checkbox",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "properties": {
      +              "condition": {
      +                "description": "number: between, not_between, greater_than, greater_than_or_equal, less_than, less_than_or_equal, equal, not_equal. date: valid, before, on_or_before, after, on_or_after, on, between, not_between. text: contains, not_contains, exactly, email, url.",
      +                "type": "string"
      +              },
      +              "type": {
      +                "enum": [
      +                  "number",
      +                  "date",
      +                  "text"
      +                ],
      +                "type": "string"
      +              },
      +              "value": {
      +                "description": "A number, a date (YYYY-MM-DD) or text.",
      +                "type": [
      +                  "number",
      +                  "string"
      +                ]
      +              },
      +              "value2": {
      +                "description": "The second value of between.",
      +                "type": [
      +                  "number",
      +                  "string"
      +                ]
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "condition"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "range",
      +      "rule"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "clear_validation",
      +        "description": "Take a range out of every validation rule.",
      +        "type": "string"
      +      },
      +      "range": {
      +        "description": "A cell or range in A1 form: \"B4\", \"A1:D20\".",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "range"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "first": {
      +        "description": "Put it first in the list (default last): the first rule a cell meets draws it.",
      +        "type": "boolean"
      +      },
      +      "op": {
      +        "const": "conditional_format",
      +        "description": "Add a format rule (last in the list): a condition and a style, or a colour scale.",
      +        "type": "string"
      +      },
      +      "range": {
      +        "description": "A cell or range in A1 form: \"B4\", \"A1:D20\".",
      +        "type": "string"
      +      },
      +      "scale": {
      +        "description": "A colour scale instead of when: each number shaded between the points.",
      +        "properties": {
      +          "max": {
      +            "properties": {
      +              "color": {
      +                "description": "#rrggbb",
      +                "type": "string"
      +              },
      +              "type": {
      +                "enum": [
      +                  "min",
      +                  "max",
      +                  "number",
      +                  "percent",
      +                  "percentile"
      +                ],
      +                "type": "string"
      +              },
      +              "value": {
      +                "description": "For number, percent and percentile.",
      +                "type": "number"
      +              }
      +            },
      +            "required": [
      +              "color",
      +              "type"
      +            ],
      +            "type": "object"
      +          },
      +          "mid": {
      +            "properties": {
      +              "color": {
      +                "description": "#rrggbb",
      +                "type": "string"
      +              },
      +              "type": {
      +                "enum": [
      +                  "min",
      +                  "max",
      +                  "number",
      +                  "percent",
      +                  "percentile"
      +                ],
      +                "type": "string"
      +              },
      +              "value": {
      +                "description": "For number, percent and percentile.",
      +                "type": "number"
      +              }
      +            },
      +            "required": [
      +              "color",
      +              "type"
      +            ],
      +            "type": "object"
      +          },
      +          "min": {
      +            "properties": {
      +              "color": {
      +                "description": "#rrggbb",
      +                "type": "string"
      +              },
      +              "type": {
      +                "enum": [
      +                  "min",
      +                  "max",
      +                  "number",
      +                  "percent",
      +                  "percentile"
      +                ],
      +                "type": "string"
      +              },
      +              "value": {
      +                "description": "For number, percent and percentile.",
      +                "type": "number"
      +              }
      +            },
      +            "required": [
      +              "color",
      +              "type"
      +            ],
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "min",
      +          "max"
      +        ],
      +        "type": "object"
      +      },
      +      "style": {
      +        "description": "when's style.",
      +        "properties": {
      +          "background": {
      +            "description": "#rrggbb",
      +            "type": "string"
      +          },
      +          "bold": {
      +            "type": "boolean"
      +          },
      +          "color": {
      +            "description": "#rrggbb",
      +            "type": "string"
      +          },
      +          "italic": {
      +            "type": "boolean"
      +          },
      +          "strikethrough": {
      +            "type": "boolean"
      +          },
      +          "underline": {
      +            "type": "boolean"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "when": {
      +        "properties": {
      +          "condition": {
      +            "description": "empty, not_empty, contains, not_contains, starts_with, ends_with, exactly, date_before, date_after, date_on, greater_than, greater_than_or_equal, less_than, less_than_or_equal, between, equal, not_equal, or formula.",
      +            "type": "string"
      +          },
      +          "formula": {
      +            "description": "formula's: written for the range's top-left cell, like =$C2>100.",
      +            "type": "string"
      +          },
      +          "value": {
      +            "type": [
      +              "string",
      +              "number"
      +            ]
      +          },
      +          "value2": {
      +            "description": "The second value of between.",
      +            "type": [
      +              "string",
      +              "number"
      +            ]
      +          }
      +        },
      +        "required": [
      +          "condition"
      +        ],
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "range"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "design": {
      +        "description": "A sheet laid out as a template is, on an empty sheet.",
      +        "properties": {
      +          "accent": {
      +            "description": "The colour family of the header rows, title, totals and charts (default blue).",
      +            "enum": [
      +              "emerald",
      +              "violet",
      +              "sky",
      +              "indigo",
      +              "blue",
      +              "amber",
      +              "teal",
      +              "orange",
      +              "rose",
      +              "purple",
      +              "cyan",
      +              "fuchsia"
      +            ],
      +            "type": "string"
      +          },
      +          "blocks": {
      +            "description": "In order. Rows 1 to 3 are the heading, subtitle and a gap. A block without at starts on row 4 (the first) or after one blank row under the block before it, in column A; a table is its header row, then its rows, then its total; fields are their heading (if any), then one row per item. So formulas can name the cells their blocks land on. The answer names each block’s ranges.",
      +            "items": {
      +              "oneOf": [
      +                {
      +                  "properties": {
      +                    "at": {
      +                      "description": "Its header row’s first cell (\"A4\"); stacked when left out.",
      +                      "type": "string"
      +                    },
      +                    "chart": {
      +                      "description": "A chart of the table’s header and body rows (never its total), live from its cells.",
      +                      "properties": {
      +                        "at": {
      +                          "description": "The cell its top-left sits on; right of the table by default.",
      +                          "type": "string"
      +                        },
      +                        "columns": {
      +                          "description": "The columns charted by name, the first the labels; every column when left out.",
      +                          "items": {
      +                            "type": "string"
      +                          },
      +                          "type": "array"
      +                        },
      +                        "height": {
      +                          "description": "px, default 280.",
      +                          "type": "number"
      +                        },
      +                        "palette": {
      +                          "description": "Its colours. Left out: the family of its table’s header (a design’s accent: emerald and teal forest; sky, blue, indigo and cyan ocean; amber and orange sunset; rose, violet, purple and fuchsia berry), else vivid; a line, area or scatter chart of several series vivid, so its lines tell apart.",
      +                          "enum": [
      +                            "vivid",
      +                            "ocean",
      +                            "forest",
      +                            "sunset",
      +                            "berry",
      +                            "earth",
      +                            "grey",
      +                            "contrast"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "type": {
      +                          "description": "column, bar, pie and doughnut draw one series (the first value column); line, area and scatter draw every value column.",
      +                          "enum": [
      +                            "column",
      +                            "bar",
      +                            "line",
      +                            "area",
      +                            "scatter",
      +                            "pie",
      +                            "doughnut"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "width": {
      +                          "description": "px, default 420.",
      +                          "type": "number"
      +                        }
      +                      },
      +                      "required": [
      +                        "type"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    "checkboxes": {
      +                      "description": "Checkbox columns by name (TRUE or FALSE values).",
      +                      "items": {
      +                        "type": "string"
      +                      },
      +                      "type": "array"
      +                    },
      +                    "dropdowns": {
      +                      "additionalProperties": {
      +                        "properties": {
      +                          "colors": {
      +                            "description": "#rrggbb per option, or null.",
      +                            "items": {
      +                              "type": [
      +                                "string",
      +                                "null"
      +                              ]
      +                            },
      +                            "type": "array"
      +                          },
      +                          "options": {
      +                            "items": {
      +                              "type": "string"
      +                            },
      +                            "maxItems": 500,
      +                            "minItems": 1,
      +                            "type": "array"
      +                          }
      +                        },
      +                        "required": [
      +                          "options"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      "description": "Dropdown columns by name, over the body rows: each value a chip in its option’s colour.",
      +                      "propertyNames": {
      +                        "type": "string"
      +                      },
      +                      "type": "object"
      +                    },
      +                    "formats": {
      +                      "additionalProperties": {
      +                        "anyOf": [
      +                          {
      +                            "type": "string"
      +                          },
      +                          {
      +                            "description": "The parts of the format to set; parts left out are kept.",
      +                            "properties": {
      +                              "align": {
      +                                "anyOf": [
      +                                  {
      +                                    "enum": [
      +                                      "left",
      +                                      "center",
      +                                      "right"
      +                                    ],
      +                                    "type": "string"
      +                                  },
      +                                  {
      +                                    "type": "null"
      +                                  }
      +                                ],
      +                                "description": "Horizontal alignment; null for automatic (numbers right, text left)."
      +                              },
      +                              "background": {
      +                                "description": "Fill colour, #rrggbb; null for none.",
      +                                "type": [
      +                                  "string",
      +                                  "null"
      +                                ]
      +                              },
      +                              "bold": {
      +                                "description": "Bold on (true) or off (false).",
      +                                "type": "boolean"
      +                              },
      +                              "color": {
      +                                "description": "Text colour, #rrggbb; null for the default.",
      +                                "type": [
      +                                  "string",
      +                                  "null"
      +                                ]
      +                              },
      +                              "currency": {
      +                                "description": "The currency symbol: R$ CHF zł kr £ $ € ¥ ₹ ₩ ₽ ₺ ₪ ₫; null for the default.",
      +                                "type": [
      +                                  "string",
      +                                  "null"
      +                                ]
      +                              },
      +                              "decimals": {
      +                                "anyOf": [
      +                                  {
      +                                    "maximum": 10,
      +                                    "minimum": 0,
      +                                    "type": "integer"
      +                                  },
      +                                  {
      +                                    "type": "null"
      +                                  }
      +                                ],
      +                                "description": "Decimal places, 0 to 10; null for the format’s own."
      +                              },
      +                              "fontSize": {
      +                                "description": "Font size in points, a whole number from 6 to 96; null for the default.",
      +                                "type": [
      +                                  "number",
      +                                  "null"
      +                                ]
      +                              },
      +                              "italic": {
      +                                "description": "Italic on or off.",
      +                                "type": "boolean"
      +                              },
      +                              "numberFormat": {
      +                                "description": "How numbers show: auto, number, percent, currency, accounting, scientific, date, time, datetime, duration, text, custom; null for auto.",
      +                                "type": [
      +                                  "string",
      +                                  "null"
      +                                ]
      +                              },
      +                              "strikethrough": {
      +                                "description": "Strikethrough on or off.",
      +                                "type": "boolean"
      +                              },
      +                              "underline": {
      +                                "description": "Underline on or off.",
      +                                "type": "boolean"
      +                              },
      +                              "verticalAlign": {
      +                                "anyOf": [
      +                                  {
      +                                    "enum": [
      +                                      "top",
      +                                      "middle",
      +                                      "bottom"
      +                                    ],
      +                                    "type": "string"
      +                                  },
      +                                  {
      +                                    "type": "null"
      +                                  }
      +                                ],
      +                                "description": "Vertical alignment; null for the default (bottom)."
      +                              },
      +                              "wrap": {
      +                                "anyOf": [
      +                                  {
      +                                    "enum": [
      +                                      "overflow",
      +                                      "wrap",
      +                                      "clip"
      +                                    ],
      +                                    "type": "string"
      +                                  },
      +                                  {
      +                                    "type": "null"
      +                                  }
      +                                ],
      +                                "description": "Long text runs over empty neighbours, wraps, or is clipped; null for overflow."
      +                              }
      +                            },
      +                            "type": "object"
      +                          }
      +                        ],
      +                        "description": "A number format by name (auto, number, percent, currency, accounting, scientific, date, time, datetime, duration, text, custom; number, currency and percent show 2 decimals), or a format in words ({\"numberFormat\": \"number\", \"decimals\": 0} for whole numbers)."
      +                      },
      +                      "description": "Formats by column name over the body and total: {\"Amount\": \"currency\", \"Share\": \"percent\"}.",
      +                      "propertyNames": {
      +                        "type": "string"
      +                      },
      +                      "type": "object"
      +                    },
      +                    "head": {
      +                      "description": "The header row: each column’s name.",
      +                      "items": {
      +                        "type": "string"
      +                      },
      +                      "minItems": 1,
      +                      "type": "array"
      +                    },
      +                    "inputs": {
      +                      "description": "Columns meant to be typed over, by name: tinted soft yellow.",
      +                      "items": {
      +                        "type": "string"
      +                      },
      +                      "type": "array"
      +                    },
      +                    "kind": {
      +                      "const": "table",
      +                      "description": "A block is a table, fields or a note.",
      +                      "type": "string"
      +                    },
      +                    "rows": {
      +                      "description": "The body rows, values read as typed (a leading = a formula).",
      +                      "items": {
      +                        "description": "One row, left to right.",
      +                        "items": {
      +                          "description": "A value: text is read as typed in en-GB (a leading = is a formula, \"12%\" a percent, \"03/04/2026\" the 3rd of April), a JSON number or boolean is kept as it is, null clears the cell.",
      +                          "type": [
      +                            "string",
      +                            "number",
      +                            "boolean",
      +                            "null"
      +                          ]
      +                        },
      +                        "maxItems": 200,
      +                        "type": "array"
      +                      },
      +                      "maxItems": 10000,
      +                      "type": "array"
      +                    },
      +                    "total": {
      +                      "description": "A total row under the body, bold and ruled above (\"Total\", null, \"=SUM(C5:C12)\").",
      +                      "items": {
      +                        "description": "A value: text is read as typed in en-GB (a leading = is a formula, \"12%\" a percent, \"03/04/2026\" the 3rd of April), a JSON number or boolean is kept as it is, null clears the cell.",
      +                        "type": [
      +                          "string",
      +                          "number",
      +                          "boolean",
      +                          "null"
      +                        ]
      +                      },
      +                      "type": "array"
      +                    }
      +                  },
      +                  "required": [
      +                    "kind",
      +                    "head",
      +                    "rows"
      +                  ],
      +                  "type": "object"
      +                },
      +                {
      +                  "properties": {
      +                    "at": {
      +                      "description": "Its first cell; stacked when left out.",
      +                      "type": "string"
      +                    },
      +                    "heading": {
      +                      "description": "A ruled heading over them.",
      +                      "type": "string"
      +                    },
      +                    "items": {
      +                      "items": {
      +                        "properties": {
      +                          "format": {
      +                            "anyOf": [
      +                              {
      +                                "type": "string"
      +                              },
      +                              {
      +                                "description": "The parts of the format to set; parts left out are kept.",
      +                                "properties": {
      +                                  "align": {
      +                                    "anyOf": [
      +                                      {
      +                                        "enum": [
      +                                          "left",
      +                                          "center",
      +                                          "right"
      +                                        ],
      +                                        "type": "string"
      +                                      },
      +                                      {
      +                                        "type": "null"
      +                                      }
      +                                    ],
      +                                    "description": "Horizontal alignment; null for automatic (numbers right, text left)."
      +                                  },
      +                                  "background": {
      +                                    "description": "Fill colour, #rrggbb; null for none.",
      +                                    "type": [
      +                                      "string",
      +                                      "null"
      +                                    ]
      +                                  },
      +                                  "bold": {
      +                                    "description": "Bold on (true) or off (false).",
      +                                    "type": "boolean"
      +                                  },
      +                                  "color": {
      +                                    "description": "Text colour, #rrggbb; null for the default.",
      +                                    "type": [
      +                                      "string",
      +                                      "null"
      +                                    ]
      +                                  },
      +                                  "currency": {
      +                                    "description": "The currency symbol: R$ CHF zł kr £ $ € ¥ ₹ ₩ ₽ ₺ ₪ ₫; null for the default.",
      +                                    "type": [
      +                                      "string",
      +                                      "null"
      +                                    ]
      +                                  },
      +                                  "decimals": {
      +                                    "anyOf": [
      +                                      {
      +                                        "maximum": 10,
      +                                        "minimum": 0,
      +                                        "type": "integer"
      +                                      },
      +                                      {
      +                                        "type": "null"
      +                                      }
      +                                    ],
      +                                    "description": "Decimal places, 0 to 10; null for the format’s own."
      +                                  },
      +                                  "fontSize": {
      +                                    "description": "Font size in points, a whole number from 6 to 96; null for the default.",
      +                                    "type": [
      +                                      "number",
      +                                      "null"
      +                                    ]
      +                                  },
      +                                  "italic": {
      +                                    "description": "Italic on or off.",
      +                                    "type": "boolean"
      +                                  },
      +                                  "numberFormat": {
      +                                    "description": "How numbers show: auto, number, percent, currency, accounting, scientific, date, time, datetime, duration, text, custom; null for auto.",
      +                                    "type": [
      +                                      "string",
      +                                      "null"
      +                                    ]
      +                                  },
      +                                  "strikethrough": {
      +                                    "description": "Strikethrough on or off.",
      +                                    "type": "boolean"
      +                                  },
      +                                  "underline": {
      +                                    "description": "Underline on or off.",
      +                                    "type": "boolean"
      +                                  },
      +                                  "verticalAlign": {
      +                                    "anyOf": [
      +                                      {
      +                                        "enum": [
      +                                          "top",
      +                                          "middle",
      +                                          "bottom"
      +                                        ],
      +                                        "type": "string"
      +                                      },
      +                                      {
      +                                        "type": "null"
      +                                      }
      +                                    ],
      +                                    "description": "Vertical alignment; null for the default (bottom)."
      +                                  },
      +                                  "wrap": {
      +                                    "anyOf": [
      +                                      {
      +                                        "enum": [
      +                                          "overflow",
      +                                          "wrap",
      +                                          "clip"
      +                                        ],
      +                                        "type": "string"
      +                                      },
      +                                      {
      +                                        "type": "null"
      +                                      }
      +                                    ],
      +                                    "description": "Long text runs over empty neighbours, wraps, or is clipped; null for overflow."
      +                                  }
      +                                },
      +                                "type": "object"
      +                              }
      +                            ],
      +                            "description": "A number format by name (auto, number, percent, currency, accounting, scientific, date, time, datetime, duration, text, custom; number, currency and percent show 2 decimals), or a format in words ({\"numberFormat\": \"number\", \"decimals\": 0} for whole numbers)."
      +                          },
      +                          "kind": {
      +                            "description": "input: tinted to type over; result: larger, bold, in the accent; value (default).",
      +                            "enum": [
      +                              "input",
      +                              "value",
      +                              "result"
      +                            ],
      +                            "type": "string"
      +                          },
      +                          "label": {
      +                            "description": "In the first column, quiet.",
      +                            "type": "string"
      +                          },
      +                          "value": {
      +                            "description": "In the column right of it.",
      +                            "type": [
      +                              "string",
      +                              "number",
      +                              "boolean",
      +                              "null"
      +                            ]
      +                          }
      +                        },
      +                        "required": [
      +                          "label",
      +                          "value"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      "minItems": 1,
      +                      "type": "array"
      +                    },
      +                    "kind": {
      +                      "const": "fields",
      +                      "description": "Labels and values, two columns.",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "kind",
      +                    "items"
      +                  ],
      +                  "type": "object"
      +                },
      +                {
      +                  "properties": {
      +                    "at": {
      +                      "type": "string"
      +                    },
      +                    "kind": {
      +                      "const": "note",
      +                      "description": "One quiet line.",
      +                      "type": "string"
      +                    },
      +                    "text": {
      +                      "description": "A quiet italic line.",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "kind",
      +                    "text"
      +                  ],
      +                  "type": "object"
      +                }
      +              ]
      +            },
      +            "minItems": 1,
      +            "type": "array"
      +          },
      +          "freeze": {
      +            "description": "Rows frozen at the top; by default through the header of the table with the most rows, when it starts by row 12.",
      +            "maximum": 100,
      +            "minimum": 0,
      +            "type": "integer"
      +          },
      +          "heading": {
      +            "description": "The title in A1, large and in the accent, across the sheet.",
      +            "type": "string"
      +          },
      +          "look": {
      +            "description": "banded (default: filled header, every other row tinted, ruled total), header, boxed (every cell lined), minimal (ruled, no gridlines) or plain.",
      +            "enum": [
      +              "plain",
      +              "header",
      +              "banded",
      +              "boxed",
      +              "minimal"
      +            ],
      +            "type": "string"
      +          },
      +          "subtitle": {
      +            "description": "A quiet line under it, in A2: what the sheet is for, what to type over.",
      +            "type": "string"
      +          },
      +          "widths": {
      +            "description": "Column widths in px from A; each column fitted to its cells when left out.",
      +            "items": {
      +              "type": "number"
      +            },
      +            "type": "array"
      +          }
      +        },
      +        "required": [
      +          "heading",
      +          "blocks"
      +        ],
      +        "type": "object"
      +      },
      +      "op": {
      +        "const": "design",
      +        "description": "Lay an empty sheet out as a template is: its heading, tables, fields and notes, in a look and an accent, with charts.",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "design"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "at": {
      +        "description": "The cell its top-left sits on; right of the range, a column clear, by default.",
      +        "type": "string"
      +      },
      +      "columns": {
      +        "description": "Only these columns of it, by letter ([\"A\", \"D\"]), the first the labels.",
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "height": {
      +        "description": "px, default 280.",
      +        "type": "number"
      +      },
      +      "op": {
      +        "const": "chart",
      +        "description": "Put a chart over the sheet’s cells, reading a range live (it grows with rows inserted inside it).",
      +        "type": "string"
      +      },
      +      "palette": {
      +        "description": "Its colours. Left out: the family of its table’s header (a design’s accent: emerald and teal forest; sky, blue, indigo and cyan ocean; amber and orange sunset; rose, violet, purple and fuchsia berry), else vivid; a line, area or scatter chart of several series vivid, so its lines tell apart.",
      +        "enum": [
      +          "vivid",
      +          "ocean",
      +          "forest",
      +          "sunset",
      +          "berry",
      +          "earth",
      +          "grey",
      +          "contrast"
      +        ],
      +        "type": "string"
      +      },
      +      "range": {
      +        "description": "Its header row (the series’ names) and data rows, the first column the labels: \"A4:C12\".",
      +        "type": "string"
      +      },
      +      "type": {
      +        "description": "column, bar, pie and doughnut draw one series (the first value column); line, area and scatter draw every value column.",
      +        "enum": [
      +          "column",
      +          "bar",
      +          "line",
      +          "area",
      +          "scatter",
      +          "pie",
      +          "doughnut"
      +        ],
      +        "type": "string"
      +      },
      +      "width": {
      +        "description": "px, default 420.",
      +        "type": "number"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "type",
      +      "range"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "clear_charts",
      +        "description": "Take the sheet’s charts off its tab: those reading cells of a range, or every one.",
      +        "type": "string"
      +      },
      +      "range": {
      +        "description": "Only the charts reading cells of this range.",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "cols": {
      +        "description": "Columns, \"C\" or \"A:F\".",
      +        "type": "string"
      +      },
      +      "fit": {
      +        "description": "Columns only: each as wide as the widest value it shows (a dropdown chip’s room included), 56 to 360 px; a cell merged across columns does not count.",
      +        "type": "boolean"
      +      },
      +      "op": {
      +        "const": "resize",
      +        "description": "Size columns (px, or fit to what their cells show) or rows (px).",
      +        "type": "string"
      +      },
      +      "px": {
      +        "description": "Width or height in px: columns 24 to 2000, rows 18 to 2000. A new sheet's are 120 by 28.",
      +        "type": "number"
      +      },
      +      "rows": {
      +        "description": "Rows, \"3\" or \"4:20\".",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "across": {
      +        "description": "Merge each row of the range on its own instead.",
      +        "type": "boolean"
      +      },
      +      "op": {
      +        "const": "merge",
      +        "description": "Merge a range into one cell showing its top-left value; other values in it are cleared.",
      +        "type": "string"
      +      },
      +      "range": {
      +        "description": "A cell or range in A1 form: \"B4\", \"A1:D20\".",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "range"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "unmerge",
      +        "description": "Unmerge every merge touching a range.",
      +        "type": "string"
      +      },
      +      "range": {
      +        "description": "A cell or range in A1 form: \"B4\", \"A1:D20\".",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "range"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "color": {
      +        "description": "#rrggbb (default #cbd5e1).",
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "border",
      +        "description": "Draw borders on a range.",
      +        "type": "string"
      +      },
      +      "range": {
      +        "description": "A cell or range in A1 form: \"B4\", \"A1:D20\".",
      +        "type": "string"
      +      },
      +      "sides": {
      +        "description": "Which lines (default all); none takes them off.",
      +        "enum": [
      +          "all",
      +          "outer",
      +          "inner",
      +          "top",
      +          "bottom",
      +          "left",
      +          "right",
      +          "none"
      +        ],
      +        "type": "string"
      +      },
      +      "style": {
      +        "description": "Default solid.",
      +        "enum": [
      +          "solid",
      +          "dashed",
      +          "dotted"
      +        ],
      +        "type": "string"
      +      },
      +      "width": {
      +        "anyOf": [
      +          {
      +            "const": 1,
      +            "type": "number"
      +          },
      +          {
      +            "const": 2,
      +            "type": "number"
      +          },
      +          {
      +            "const": 3,
      +            "type": "number"
      +          }
      +        ],
      +        "description": "1 (default) to 3 px."
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "range"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "filter",
      +        "description": "Turn the filter on over a range (its first row the header, each column filterable), or off.",
      +        "type": "string"
      +      },
      +      "range": {
      +        "anyOf": [
      +          {
      +            "description": "A cell or range in A1 form: \"B4\", \"A1:D20\".",
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "The range; left out or null turns it off."
      +      }
      +    },
      +    "required": [
      +      "op"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "clear_conditional_formats",
      +        "description": "Remove the format rules touching a range, or every one.",
      +        "type": "string"
      +      },
      +      "range": {
      +        "description": "A cell or range in A1 form: \"B4\", \"A1:D20\".",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op"
      +    ],
      +    "type": "object"
      +  }
      +]
  2. Changed1 schema field changed
    • changedInput schema / properties / changes / items / oneOf
      Previous value: -[
      -  {
      -    "properties": {
      -      "at": {
      -        "description": "The top-left cell, in A1 form (\"A1\").",
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "set",
      -        "description": "Write rows of values from a cell.",
      -        "type": "string"
      -      },
      -      "rows": {
      -        "description": "Rows of values, top to bottom; the sheet grows to fit, up to 10,000 rows and 200 columns.",
      -        "items": {
      -          "description": "One row, left to right.",
      -          "items": {
      -            "description": "A value: text is read as typed in en-GB (a leading = is a formula, \"12%\" a percent, \"03/04/2026\" the 3rd of April), a JSON number or boolean is kept as it is, null clears the cell.",
      -            "type": [
      -              "string",
      -              "number",
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "maxItems": 200,
      -          "type": "array"
      -        },
      -        "maxItems": 10000,
      -        "type": "array"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "at",
      -      "rows"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "op": {
      -        "const": "clear",
      -        "description": "Clear a range.",
      -        "type": "string"
      -      },
      -      "range": {
      -        "description": "A cell or range in A1 form: \"B4\", \"A1:D20\".",
      -        "type": "string"
      -      },
      -      "what": {
      -        "description": "What to clear: inputs, formats, or all (the default).",
      -        "enum": [
      -          "inputs",
      -          "formats",
      -          "all"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "range"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "format": {
      -        "description": "The parts of the format to set; parts left out are kept.",
      -        "properties": {
      -          "align": {
      -            "anyOf": [
      -              {
      -                "enum": [
      -                  "left",
      -                  "center",
      -                  "right"
      -                ],
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "Horizontal alignment; null for automatic (numbers right, text left)."
      -          },
      -          "background": {
      -            "description": "Fill colour, #rrggbb; null for none.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "bold": {
      -            "description": "Bold on (true) or off (false).",
      -            "type": "boolean"
      -          },
      -          "color": {
      -            "description": "Text colour, #rrggbb; null for the default.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "currency": {
      -            "description": "The currency symbol: R$ CHF zł kr £ $ € ¥ ₹ ₩ ₽ ₺ ₪ ₫; null for the default.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "decimals": {
      -            "anyOf": [
      -              {
      -                "maximum": 10,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "Decimal places, 0 to 10; null for the format’s own."
      -          },
      -          "fontSize": {
      -            "description": "Font size in points, a whole number from 6 to 96; null for the default.",
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "italic": {
      -            "description": "Italic on or off.",
      -            "type": "boolean"
      -          },
      -          "numberFormat": {
      -            "description": "How numbers show: auto, number, percent, currency, accounting, scientific, date, time, datetime, duration, text; null for auto.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "strikethrough": {
      -            "description": "Strikethrough on or off.",
      -            "type": "boolean"
      -          },
      -          "underline": {
      -            "description": "Underline on or off.",
      -            "type": "boolean"
      -          },
      -          "verticalAlign": {
      -            "anyOf": [
      -              {
      -                "enum": [
      -                  "top",
      -                  "middle",
      -                  "bottom"
      -                ],
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "Vertical alignment; null for the default (bottom)."
      -          },
      -          "wrap": {
      -            "anyOf": [
      -              {
      -                "enum": [
      -                  "overflow",
      -                  "wrap",
      -                  "clip"
      -                ],
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "Long text runs over empty neighbours, wraps, or is clipped; null for overflow."
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "op": {
      -        "const": "format",
      -        "description": "Format a range.",
      -        "type": "string"
      -      },
      -      "range": {
      -        "description": "A cell or range in A1 form: \"B4\", \"A1:D20\".",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "range",
      -      "format"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "at": {
      -        "description": "The row number they go beside (1 is the first row).",
      -        "maximum": 9007199254740991,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "count": {
      -        "description": "How many (default 1).",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "op": {
      -        "const": "insert_rows",
      -        "description": "Insert rows.",
      -        "type": "string"
      -      },
      -      "side": {
      -        "description": "Before (the default) or after it.",
      -        "enum": [
      -          "before",
      -          "after"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "at"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "at": {
      -        "description": "The column letter they go beside (\"C\").",
      -        "type": "string"
      -      },
      -      "count": {
      -        "description": "How many (default 1).",
      -        "maximum": 1000,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "op": {
      -        "const": "insert_cols",
      -        "description": "Insert columns.",
      -        "type": "string"
      -      },
      -      "side": {
      -        "description": "Before (the default) or after it.",
      -        "enum": [
      -          "before",
      -          "after"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "at"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "op": {
      -        "const": "delete_rows",
      -        "description": "Delete rows, and their cells.",
      -        "type": "string"
      -      },
      -      "rows": {
      -        "description": "A row number or a span: \"3\", \"3:5\".",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "rows"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "cols": {
      -        "description": "A column letter or a span: \"C\", \"C:E\".",
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "delete_cols",
      -        "description": "Delete columns, and their cells.",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "cols"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "op": {
      -        "const": "rename",
      -        "description": "Rename the sheet.",
      -        "type": "string"
      -      },
      -      "title": {
      -        "description": "The new title, 1 to 60 characters, unique on its tab.",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "title"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "by": {
      -        "description": "The column to sort by, by letter (\"B\").",
      -        "type": "string"
      -      },
      -      "descending": {
      -        "description": "Z to A, largest first (default A to Z).",
      -        "type": "boolean"
      -      },
      -      "header": {
      -        "description": "The range’s first row is a header and stays put.",
      -        "type": "boolean"
      -      },
      -      "op": {
      -        "const": "sort",
      -        "description": "Sort rows by a column.",
      -        "type": "string"
      -      },
      -      "range": {
      -        "description": "Only this range’s cells move. Left out, the whole sheet’s rows are reordered (frozen rows stay).",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "by"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "cols": {
      -        "description": "Columns to freeze; 0 unfreezes.",
      -        "maximum": 26,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "op": {
      -        "const": "freeze",
      -        "description": "Freeze rows and columns at the top and left.",
      -        "type": "string"
      -      },
      -      "rows": {
      -        "description": "Rows to freeze; 0 unfreezes.",
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "integer"
      -      }
      -    },
      -    "required": [
      -      "op"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "properties": {
      +      "at": {
      +        "description": "The top-left cell, in A1 form (\"A1\").",
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "set",
      +        "description": "Write rows of values from a cell.",
      +        "type": "string"
      +      },
      +      "rows": {
      +        "description": "Rows of values, top to bottom; the sheet grows to fit, up to 10,000 rows and 200 columns.",
      +        "items": {
      +          "description": "One row, left to right.",
      +          "items": {
      +            "description": "A value: text is read as typed in en-GB (a leading = is a formula, \"12%\" a percent, \"03/04/2026\" the 3rd of April), a JSON number or boolean is kept as it is, null clears the cell.",
      +            "type": [
      +              "string",
      +              "number",
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "maxItems": 200,
      +          "type": "array"
      +        },
      +        "maxItems": 10000,
      +        "type": "array"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "at",
      +      "rows"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "clear",
      +        "description": "Clear a range.",
      +        "type": "string"
      +      },
      +      "range": {
      +        "description": "A cell or range in A1 form: \"B4\", \"A1:D20\".",
      +        "type": "string"
      +      },
      +      "what": {
      +        "description": "What to clear: inputs, formats, or all (the default).",
      +        "enum": [
      +          "inputs",
      +          "formats",
      +          "all"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "range"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "format": {
      +        "description": "The parts of the format to set; parts left out are kept.",
      +        "properties": {
      +          "align": {
      +            "anyOf": [
      +              {
      +                "enum": [
      +                  "left",
      +                  "center",
      +                  "right"
      +                ],
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Horizontal alignment; null for automatic (numbers right, text left)."
      +          },
      +          "background": {
      +            "description": "Fill colour, #rrggbb; null for none.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "bold": {
      +            "description": "Bold on (true) or off (false).",
      +            "type": "boolean"
      +          },
      +          "color": {
      +            "description": "Text colour, #rrggbb; null for the default.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "currency": {
      +            "description": "The currency symbol: R$ CHF zł kr £ $ € ¥ ₹ ₩ ₽ ₺ ₪ ₫; null for the default.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "decimals": {
      +            "anyOf": [
      +              {
      +                "maximum": 10,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Decimal places, 0 to 10; null for the format’s own."
      +          },
      +          "fontSize": {
      +            "description": "Font size in points, a whole number from 6 to 96; null for the default.",
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "italic": {
      +            "description": "Italic on or off.",
      +            "type": "boolean"
      +          },
      +          "numberFormat": {
      +            "description": "How numbers show: auto, number, percent, currency, accounting, scientific, date, time, datetime, duration, text, custom; null for auto.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "strikethrough": {
      +            "description": "Strikethrough on or off.",
      +            "type": "boolean"
      +          },
      +          "underline": {
      +            "description": "Underline on or off.",
      +            "type": "boolean"
      +          },
      +          "verticalAlign": {
      +            "anyOf": [
      +              {
      +                "enum": [
      +                  "top",
      +                  "middle",
      +                  "bottom"
      +                ],
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Vertical alignment; null for the default (bottom)."
      +          },
      +          "wrap": {
      +            "anyOf": [
      +              {
      +                "enum": [
      +                  "overflow",
      +                  "wrap",
      +                  "clip"
      +                ],
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Long text runs over empty neighbours, wraps, or is clipped; null for overflow."
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "op": {
      +        "const": "format",
      +        "description": "Format a range.",
      +        "type": "string"
      +      },
      +      "range": {
      +        "description": "A cell or range in A1 form: \"B4\", \"A1:D20\".",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "range",
      +      "format"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "at": {
      +        "description": "The row number they go beside (1 is the first row).",
      +        "maximum": 9007199254740991,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "count": {
      +        "description": "How many (default 1).",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "op": {
      +        "const": "insert_rows",
      +        "description": "Insert rows.",
      +        "type": "string"
      +      },
      +      "side": {
      +        "description": "Before (the default) or after it.",
      +        "enum": [
      +          "before",
      +          "after"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "at"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "at": {
      +        "description": "The column letter they go beside (\"C\").",
      +        "type": "string"
      +      },
      +      "count": {
      +        "description": "How many (default 1).",
      +        "maximum": 1000,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "op": {
      +        "const": "insert_cols",
      +        "description": "Insert columns.",
      +        "type": "string"
      +      },
      +      "side": {
      +        "description": "Before (the default) or after it.",
      +        "enum": [
      +          "before",
      +          "after"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "at"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "delete_rows",
      +        "description": "Delete rows, and their cells.",
      +        "type": "string"
      +      },
      +      "rows": {
      +        "description": "A row number or a span: \"3\", \"3:5\".",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "rows"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "cols": {
      +        "description": "A column letter or a span: \"C\", \"C:E\".",
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "delete_cols",
      +        "description": "Delete columns, and their cells.",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "cols"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "rename",
      +        "description": "Rename the sheet.",
      +        "type": "string"
      +      },
      +      "title": {
      +        "description": "The new title, 1 to 60 characters, unique on its tab.",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "title"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "by": {
      +        "description": "The column to sort by, by letter (\"B\").",
      +        "type": "string"
      +      },
      +      "descending": {
      +        "description": "Z to A, largest first (default A to Z).",
      +        "type": "boolean"
      +      },
      +      "header": {
      +        "description": "The range’s first row is a header and stays put.",
      +        "type": "boolean"
      +      },
      +      "op": {
      +        "const": "sort",
      +        "description": "Sort rows by a column.",
      +        "type": "string"
      +      },
      +      "range": {
      +        "description": "Only this range’s cells move. Left out, the whole sheet’s rows are reordered (frozen rows stay).",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "by"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "cols": {
      +        "description": "Columns to freeze; 0 unfreezes.",
      +        "maximum": 26,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "op": {
      +        "const": "freeze",
      +        "description": "Freeze rows and columns at the top and left.",
      +        "type": "string"
      +      },
      +      "rows": {
      +        "description": "Rows to freeze; 0 unfreezes.",
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "integer"
      +      }
      +    },
      +    "required": [
      +      "op"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "help": {
      +        "description": "Said when a value is refused.",
      +        "maxLength": 255,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "validate",
      +        "description": "Set what a range may hold (a dropdown, a checkbox, a number, date or text rule); it replaces the rules the range covered.",
      +        "type": "string"
      +      },
      +      "range": {
      +        "description": "A cell or range in A1 form: \"B4\", \"A1:D20\".",
      +        "type": "string"
      +      },
      +      "reject": {
      +        "description": "Refuse a value it does not allow (default true); false keeps it and marks it.",
      +        "type": "boolean"
      +      },
      +      "rule": {
      +        "description": "The rule.",
      +        "oneOf": [
      +          {
      +            "properties": {
      +              "colors": {
      +                "description": "A colour per option, #rrggbb, or null.",
      +                "items": {
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "type": "array"
      +              },
      +              "display": {
      +                "description": "How it shows (default chip).",
      +                "enum": [
      +                  "chip",
      +                  "arrow",
      +                  "plain"
      +                ],
      +                "type": "string"
      +              },
      +              "options": {
      +                "description": "The values offered, in order.",
      +                "items": {
      +                  "type": "string"
      +                },
      +                "maxItems": 500,
      +                "minItems": 1,
      +                "type": "array"
      +              },
      +              "type": {
      +                "const": "dropdown",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "options"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "properties": {
      +              "display": {
      +                "enum": [
      +                  "chip",
      +                  "arrow",
      +                  "plain"
      +                ],
      +                "type": "string"
      +              },
      +              "source": {
      +                "description": "The cells (on this sheet) whose values are offered, \"A2:A20\".",
      +                "type": "string"
      +              },
      +              "type": {
      +                "const": "dropdown_range",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "source"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "properties": {
      +              "type": {
      +                "const": "checkbox",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "properties": {
      +              "condition": {
      +                "description": "number: between, not_between, greater_than, greater_than_or_equal, less_than, less_than_or_equal, equal, not_equal. date: valid, before, on_or_before, after, on_or_after, on, between, not_between. text: contains, not_contains, exactly, email, url.",
      +                "type": "string"
      +              },
      +              "type": {
      +                "enum": [
      +                  "number",
      +                  "date",
      +                  "text"
      +                ],
      +                "type": "string"
      +              },
      +              "value": {
      +                "description": "A number, a date (YYYY-MM-DD) or text.",
      +                "type": [
      +                  "number",
      +                  "string"
      +                ]
      +              },
      +              "value2": {
      +                "description": "The second value of between.",
      +                "type": [
      +                  "number",
      +                  "string"
      +                ]
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "condition"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "range",
      +      "rule"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "clear_validation",
      +        "description": "Take a range out of every validation rule.",
      +        "type": "string"
      +      },
      +      "range": {
      +        "description": "A cell or range in A1 form: \"B4\", \"A1:D20\".",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "range"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "conditional_format",
      +        "description": "Add a format rule (last in the list): a condition and a style, or a colour scale.",
      +        "type": "string"
      +      },
      +      "range": {
      +        "description": "A cell or range in A1 form: \"B4\", \"A1:D20\".",
      +        "type": "string"
      +      },
      +      "scale": {
      +        "description": "A colour scale instead of when: each number shaded between the points.",
      +        "properties": {
      +          "max": {
      +            "properties": {
      +              "color": {
      +                "description": "#rrggbb",
      +                "type": "string"
      +              },
      +              "type": {
      +                "enum": [
      +                  "min",
      +                  "max",
      +                  "number",
      +                  "percent",
      +                  "percentile"
      +                ],
      +                "type": "string"
      +              },
      +              "value": {
      +                "description": "For number, percent and percentile.",
      +                "type": "number"
      +              }
      +            },
      +            "required": [
      +              "color",
      +              "type"
      +            ],
      +            "type": "object"
      +          },
      +          "mid": {
      +            "properties": {
      +              "color": {
      +                "description": "#rrggbb",
      +                "type": "string"
      +              },
      +              "type": {
      +                "enum": [
      +                  "min",
      +                  "max",
      +                  "number",
      +                  "percent",
      +                  "percentile"
      +                ],
      +                "type": "string"
      +              },
      +              "value": {
      +                "description": "For number, percent and percentile.",
      +                "type": "number"
      +              }
      +            },
      +            "required": [
      +              "color",
      +              "type"
      +            ],
      +            "type": "object"
      +          },
      +          "min": {
      +            "properties": {
      +              "color": {
      +                "description": "#rrggbb",
      +                "type": "string"
      +              },
      +              "type": {
      +                "enum": [
      +                  "min",
      +                  "max",
      +                  "number",
      +                  "percent",
      +                  "percentile"
      +                ],
      +                "type": "string"
      +              },
      +              "value": {
      +                "description": "For number, percent and percentile.",
      +                "type": "number"
      +              }
      +            },
      +            "required": [
      +              "color",
      +              "type"
      +            ],
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "min",
      +          "max"
      +        ],
      +        "type": "object"
      +      },
      +      "style": {
      +        "description": "when's style.",
      +        "properties": {
      +          "background": {
      +            "description": "#rrggbb",
      +            "type": "string"
      +          },
      +          "bold": {
      +            "type": "boolean"
      +          },
      +          "color": {
      +            "description": "#rrggbb",
      +            "type": "string"
      +          },
      +          "italic": {
      +            "type": "boolean"
      +          },
      +          "strikethrough": {
      +            "type": "boolean"
      +          },
      +          "underline": {
      +            "type": "boolean"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "when": {
      +        "properties": {
      +          "condition": {
      +            "description": "empty, not_empty, contains, not_contains, starts_with, ends_with, exactly, date_before, date_after, date_on, greater_than, greater_than_or_equal, less_than, less_than_or_equal, between, equal, not_equal, or formula.",
      +            "type": "string"
      +          },
      +          "formula": {
      +            "description": "formula's: written for the range's top-left cell, like =$C2>100.",
      +            "type": "string"
      +          },
      +          "value": {
      +            "type": [
      +              "string",
      +              "number"
      +            ]
      +          },
      +          "value2": {
      +            "description": "The second value of between.",
      +            "type": [
      +              "string",
      +              "number"
      +            ]
      +          }
      +        },
      +        "required": [
      +          "condition"
      +        ],
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "range"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "clear_conditional_formats",
      +        "description": "Remove the format rules touching a range, or every one.",
      +        "type": "string"
      +      },
      +      "range": {
      +        "description": "A cell or range in A1 form: \"B4\", \"A1:D20\".",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op"
      +    ],
      +    "type": "object"
      +  }
      +]
  3. Added

TDQS

A3.6/5.0
Behavior4/5

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

Annotations already flag destructiveHint=true/readOnly=false, and the description adds genuinely non-structured behavior: changes apply in order, an unreadable formula is refused naming the cell, and every collaborator with the document open sees each change at once. It still omits permission requirements and whether deletes are recoverable, which keeps it short of a 5.

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

Conciseness3/5

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

It is front-loaded with the purpose and the A1-notation rule, and the operation list is useful orientation for a 20+ branch schema. However, the giant run-on parenthetical duplicates what the const descriptions already document, so a meaningful share of the text does not earn its place.

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

Completeness4/5

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

For a highly complex multi-op mutation tool with a full output schema and 100% parameter coverage, the description supplies the needed orientation: operation inventory, ordering semantics, refusal behavior, and live-collaboration note. Return values are correctly left to the output schema; only permission/error-depth detail 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 description coverage is 100%, so the baseline is 3. The description's {op, param} shorthand and 'Cells by A1, rows by number, columns by letter' note largely restate the schema's const and property descriptions rather than adding new semantics.

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

Purpose4/5

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

Opens with a specific verb+resource ('Change a sheet') and then enumerates ~20 concrete operations, so an agent immediately knows this mutates an existing sheet rather than reading it like read_sheet or creating it like add_sheet. No sibling is named explicitly, but the operation list itself separates it from list_sheets/read_sheet.

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

Usage Guidelines3/5

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

Usage is implied by the exhaustive operation list, but there is no explicit when-to-use/when-not guidance, no mention of prerequisites (e.g. sheet must exist), and no routing to alternatives like read_sheet for inspection. The agent must infer that this is the mutation path.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources