diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 951a5b1..1656a48 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,6 +31,12 @@ jobs: git add -N content/docs/api/rest git diff --exit-code -- content/docs/api/rest + - name: gen-mcp-docs drift check + run: | + node scripts/gen-mcp-docs.mjs + git add -N content/docs/api/mcp + git diff --exit-code -- content/docs/api/mcp + - name: test-docs (Learn examples) run: node scripts/test-docs.mjs diff --git a/content/docs/api/mcp/chart-insert.mdx b/content/docs/api/mcp/chart-insert.mdx new file mode 100644 index 0000000..507c7f7 --- /dev/null +++ b/content/docs/api/mcp/chart-insert.mdx @@ -0,0 +1,129 @@ +--- +title: "chart:insert" +description: "Inserts a chart." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet `range` is relative to. | +| `range` | `{ from: string; to: string }` | yes | The rectangle to bind the chart to, as A1 corners. | +| `chartType` | `string` | yes | The chart form to draw, a closed wire vocabulary. | +| `options` | `object` | no | Renderer-specific knobs, opaque here on purpose, defaults to `{}`. | + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `chartId` | `string` | yes | The new chart's id. | +| `range` | `{ from: string; to: string }` | yes | Canonicalized top-left/bottom-right corners. | +| `chartType` | `string` | yes | — | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet `range` is relative to.", + "type": "string" + }, + "range": { + "description": "The rectangle to bind the chart to, as A1 corners.", + "$ref": "#/$defs/CellRange" + }, + "chartType": { + "description": "The chart form to draw, a closed wire vocabulary.", + "type": "string" + }, + "options": { + "description": "Renderer-specific knobs, opaque here on purpose, defaults to `{}`.", + "type": "object", + "additionalProperties": true, + "default": {} + } + }, + "required": [ + "sheet", + "range", + "chartType" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "chartId": { + "description": "The new chart's id.", + "type": "string" + }, + "range": { + "description": "Canonicalized top-left/bottom-right corners.", + "$ref": "#/$defs/CellRange" + }, + "chartType": { + "type": "string" + } + }, + "required": [ + "chartId", + "range", + "chartType" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/chart-remove.mdx b/content/docs/api/mcp/chart-remove.mdx new file mode 100644 index 0000000..8ff0f12 --- /dev/null +++ b/content/docs/api/mcp/chart-remove.mdx @@ -0,0 +1,63 @@ +--- +title: "chart:remove" +description: "Removes a chart." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `chartId` | `string` | yes | The chart to remove. | + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `chartId` | `string` | yes | — | +| `removed` | `boolean` | yes | — | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "chartId": { + "description": "The chart to remove.", + "type": "string" + } + }, + "required": [ + "chartId" + ] +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "chartId": { + "type": "string" + }, + "removed": { + "type": "boolean" + } + }, + "required": [ + "chartId", + "removed" + ] +} +``` + diff --git a/content/docs/api/mcp/chart-update.mdx b/content/docs/api/mcp/chart-update.mdx new file mode 100644 index 0000000..00b2e98 --- /dev/null +++ b/content/docs/api/mcp/chart-update.mdx @@ -0,0 +1,83 @@ +--- +title: "chart:update" +description: "Updates a chart." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `chartId` | `string` | yes | The chart to patch. | +| `chartType` | `string or null` | no | The new chart form, or omitted to leave it unchanged. Defaults to `null`. | +| `options` | `object or null` | no | Replaces the chart's options wholesale, or omitted to leave them unchanged. Defaults to `null`. | + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `chartId` | `string` | yes | — | +| `chartType` | `string` | yes | The EFFECTIVE, post-patch chart form, the patch's own value if it supplied one, else the chart's unchanged existing type. | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "chartId": { + "description": "The chart to patch.", + "type": "string" + }, + "chartType": { + "description": "The new chart form, or omitted to leave it unchanged.", + "type": [ + "string", + "null" + ], + "default": null + }, + "options": { + "description": "Replaces the chart's options wholesale, or omitted to leave them unchanged.", + "type": [ + "object", + "null" + ], + "additionalProperties": true, + "default": null + } + }, + "required": [ + "chartId" + ] +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "chartId": { + "type": "string" + }, + "chartType": { + "description": "The EFFECTIVE, post-patch chart form, the patch's own value if it supplied one, else the chart's unchanged existing type.", + "type": "string" + } + }, + "required": [ + "chartId", + "chartType" + ] +} +``` + diff --git a/content/docs/api/mcp/clipboard-paste.mdx b/content/docs/api/mcp/clipboard-paste.mdx new file mode 100644 index 0000000..8a5b0e6 --- /dev/null +++ b/content/docs/api/mcp/clipboard-paste.mdx @@ -0,0 +1,61 @@ +--- +title: "clipboard:paste" +description: "Pastes previously copied or cut cells into a range." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `source` | `string` | yes | The cell the clipboard content was copied/cut FROM, e.g. `"A1"`. | +| `raw` | `string` | yes | The clipboard contents AT COPY/CUT TIME, a literal, a formula, leading `=`, or `""`. | +| `target` | `string` | yes | The cell being pasted INTO, e.g. `"B2"`. | +| `cut` | `boolean` | no | `false` = copy, the default, `true` = cut, move. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "source": { + "description": "The cell the clipboard content was copied/cut FROM, e.g. `\"A1\"`.", + "type": "string" + }, + "raw": { + "description": "The clipboard contents AT COPY/CUT TIME, a literal, a formula, leading `=`, or `\"\"`.", + "type": "string" + }, + "target": { + "description": "The cell being pasted INTO, e.g. `\"B2\"`.", + "type": "string" + }, + "cut": { + "description": "`false` = copy, the default, `true` = cut, move.", + "type": "boolean", + "default": false + } + }, + "required": [ + "sheet", + "source", + "raw", + "target" + ] +} +``` + diff --git a/content/docs/api/mcp/data-clear-filter.mdx b/content/docs/api/mcp/data-clear-filter.mdx new file mode 100644 index 0000000..cd6b201 --- /dev/null +++ b/content/docs/api/mcp/data-clear-filter.mdx @@ -0,0 +1,58 @@ +--- +title: "data:clearFilter" +description: "Clears the filter." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `removed` | `boolean` | yes | A no-op, `false` if `sheet` had no filter. | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + } + }, + "required": [ + "sheet" + ] +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "removed": { + "description": "A no-op, `false` if `sheet` had no filter.", + "type": "boolean" + } + }, + "required": [ + "removed" + ] +} +``` + diff --git a/content/docs/api/mcp/data-delete-named-range.mdx b/content/docs/api/mcp/data-delete-named-range.mdx new file mode 100644 index 0000000..d7df0e9 --- /dev/null +++ b/content/docs/api/mcp/data-delete-named-range.mdx @@ -0,0 +1,69 @@ +--- +title: "data:deleteNamedRange" +description: "Deletes the named range." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `name` | `string` | yes | The named range to remove, e.g. `"MyRange"`. | + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `name` | `string` | yes | — | +| `removed` | `boolean` | yes | Whether a named range by this name actually existed and was removed. | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "name": { + "description": "The named range to remove, e.g. `\"MyRange\"`.", + "type": "string" + } + }, + "required": [ + "sheet", + "name" + ] +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "removed": { + "description": "Whether a named range by this name actually existed and was removed.", + "type": "boolean" + } + }, + "required": [ + "name", + "removed" + ] +} +``` + diff --git a/content/docs/api/mcp/data-insert-pivot.mdx b/content/docs/api/mcp/data-insert-pivot.mdx new file mode 100644 index 0000000..72e8571 --- /dev/null +++ b/content/docs/api/mcp/data-insert-pivot.mdx @@ -0,0 +1,108 @@ +--- +title: "data:insertPivot" +description: "Inserts a pivot table summarizing a range." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `range` | `{ from: string; to: string }` | yes | An inclusive rectangle. `from`/`to` may be equal, a single cell. | + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `range` | `{ from: string; to: string }` | yes | An inclusive rectangle. `from`/`to` may be equal, a single cell. | +| `destSheet` | `string` | yes | The newly-created destination sheet's name. | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "$ref": "#/$defs/CellRange" + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "range": { + "$ref": "#/$defs/CellRange" + }, + "destSheet": { + "description": "The newly-created destination sheet's name.", + "type": "string" + } + }, + "required": [ + "range", + "destSheet" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/data-set-filter.mdx b/content/docs/api/mcp/data-set-filter.mdx new file mode 100644 index 0000000..14833fa --- /dev/null +++ b/content/docs/api/mcp/data-set-filter.mdx @@ -0,0 +1,163 @@ +--- +title: "data:setFilter" +description: "Sets the filter." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `range` | `{ from: string; to: string }` | yes | The filter's own range, its FIRST row is the un-hideable header row. Must span more than one row, a single-row range has no body rows to filter. | +| `criteria` | `array of { column: string; values: array of string }` | no | Per-column checked-value lists to apply right after creating the filter. A column omitted here starts unfiltered. Defaults to `[]`. | + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `range` | `{ from: string; to: string }` | yes | An inclusive rectangle. `from`/`to` may be equal, a single cell. | +| `criteria` | `array of { column: string; values: array of string }` | yes | Echoed back exactly as applied. | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "description": "The filter's own range, its FIRST row is the un-hideable header row. Must span more than one row, a single-row range has no body rows to filter.", + "$ref": "#/$defs/CellRange" + }, + "criteria": { + "description": "Per-column checked-value lists to apply right after creating the filter. A column omitted here starts unfiltered.", + "type": "array", + "items": { + "$ref": "#/$defs/Criterion" + }, + "default": [] + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "Criterion": { + "description": "One column's checked-value list.", + "type": "object", + "properties": { + "column": { + "description": "An A1 column letter INSIDE `range`, e.g. `\"B\"`, case-insensitive.", + "type": "string" + }, + "values": { + "description": "The raw values to keep VISIBLE, checked in this column, every value not listed here hides its row.", + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "column", + "values" + ] + } + } +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "range": { + "$ref": "#/$defs/CellRange" + }, + "criteria": { + "description": "Echoed back exactly as applied.", + "type": "array", + "items": { + "$ref": "#/$defs/Criterion" + } + } + }, + "required": [ + "range", + "criteria" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "Criterion": { + "description": "One column's checked-value list.", + "type": "object", + "properties": { + "column": { + "description": "An A1 column letter INSIDE `range`, e.g. `\"B\"`, case-insensitive.", + "type": "string" + }, + "values": { + "description": "The raw values to keep VISIBLE, checked in this column, every value not listed here hides its row.", + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "column", + "values" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/data-set-named-range.mdx b/content/docs/api/mcp/data-set-named-range.mdx new file mode 100644 index 0000000..9c308a9 --- /dev/null +++ b/content/docs/api/mcp/data-set-named-range.mdx @@ -0,0 +1,124 @@ +--- +title: "data:setNamedRange" +description: "Sets the named range." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet `range` is relative to. | +| `name` | `string` | yes | The named range's identifier, e.g. `"MyRange"`. | +| `range` | `{ from: string; to: string }` | yes | The rectangle to bind `name` to. | + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `name` | `string` | yes | Echoed exactly as the caller sent it, never trimmed or re-cased. | +| `range` | `{ from: string; to: string }` | yes | Not a raw echo of whatever case or corner order `range.from`/`range.to` arrived in. | +| `created` | `boolean` | yes | `true` when this call DEFINED a brand-new name, `false` when it RETARGETED an existing one. | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "`commandId` is not modeled.", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet `range` is relative to.", + "type": "string" + }, + "name": { + "description": "The named range's identifier, e.g. `\"MyRange\"`.", + "type": "string" + }, + "range": { + "description": "The rectangle to bind `name` to.", + "$ref": "#/$defs/CellRange" + } + }, + "required": [ + "sheet", + "name", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "name": { + "description": "Echoed exactly as the caller sent it, never trimmed or re-cased.", + "type": "string" + }, + "range": { + "description": "Not a raw echo of whatever case or corner order `range.from`/`range.to` arrived in.", + "$ref": "#/$defs/CellRange" + }, + "created": { + "description": "`true` when this call DEFINED a brand-new name, `false` when it RETARGETED an existing one.", + "type": "boolean" + } + }, + "required": [ + "name", + "range", + "created" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/data-set-validation.mdx b/content/docs/api/mcp/data-set-validation.mdx new file mode 100644 index 0000000..efed714 --- /dev/null +++ b/content/docs/api/mcp/data-set-validation.mdx @@ -0,0 +1,174 @@ +--- +title: "data:setValidation" +description: "Sets the validation." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `range` | `{ from: string; to: string }` | yes | An inclusive rectangle. `from`/`to` may be equal, a single cell. | +| `rule` | `{ values: array of string; kind: "list" } or null` | no | `Some(_)` sets a rule. Required on the wire, as literal `null` to clear. | + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `range` | `{ from: string; to: string }` | yes | An inclusive rectangle. `from`/`to` may be equal, a single cell. | +| `rule` | `{ values: array of string; kind: "list" } or null` | no | — | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "$ref": "#/$defs/CellRange" + }, + "rule": { + "description": "`Some(_)` sets a rule. Required on the wire, as literal `null` to clear.", + "anyOf": [ + { + "$ref": "#/$defs/WireRule" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "WireRule": { + "description": "The one rule kind on the wire today. because the tag is checked at deserialize time.", + "oneOf": [ + { + "type": "object", + "properties": { + "values": { + "type": "array", + "items": { + "type": "string" + } + }, + "kind": { + "type": "string", + "const": "list" + } + }, + "required": [ + "kind", + "values" + ] + } + ] + } + } +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "description": "**Echoes `payload.range`/`payload.rule` verbatim**.", + "type": "object", + "properties": { + "range": { + "$ref": "#/$defs/CellRange" + }, + "rule": { + "anyOf": [ + { + "$ref": "#/$defs/WireRule" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "WireRule": { + "description": "The one rule kind on the wire today. because the tag is checked at deserialize time.", + "oneOf": [ + { + "type": "object", + "properties": { + "values": { + "type": "array", + "items": { + "type": "string" + } + }, + "kind": { + "type": "string", + "const": "list" + } + }, + "required": [ + "kind", + "values" + ] + } + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/data-sort-range.mdx b/content/docs/api/mcp/data-sort-range.mdx new file mode 100644 index 0000000..f28e566 --- /dev/null +++ b/content/docs/api/mcp/data-sort-range.mdx @@ -0,0 +1,142 @@ +--- +title: "data:sortRange" +description: "Sorts the range." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `range` | `{ from: string; to: string }` | yes | The rectangle to permute. Nothing outside it is read or written. | +| `sortColumn` | `string` | yes | The column whose values order the rows, as an A1 column letter, `"A"`, `"AB"`. Must lie inside `range`. | +| `direction` | `"asc", "desc"` | yes | Sort order for `sortColumn`'s values. | + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `range` | `{ from: string; to: string }` | yes | The normalized rectangle actually sorted. | +| `sortColumn` | `string` | yes | The sort column, canonical uppercase. | +| `direction` | `"asc", "desc"` | yes | Sort order for `sortColumn`'s values. | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "description": "The rectangle to permute. Nothing outside it is read or written.", + "$ref": "#/$defs/CellRange" + }, + "sortColumn": { + "description": "The column whose values order the rows, as an A1 column letter, `\"A\"`, `\"AB\"`. Must lie inside `range`.", + "type": "string" + }, + "direction": { + "$ref": "#/$defs/SortDirection" + } + }, + "required": [ + "sheet", + "range", + "sortColumn", + "direction" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "SortDirection": { + "description": "Sort order for `sortColumn`'s values.", + "type": "string", + "enum": [ + "asc", + "desc" + ] + } + } +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "range": { + "description": "The normalized rectangle actually sorted.", + "$ref": "#/$defs/CellRange" + }, + "sortColumn": { + "description": "The sort column, canonical uppercase.", + "type": "string" + }, + "direction": { + "$ref": "#/$defs/SortDirection" + } + }, + "required": [ + "range", + "sortColumn", + "direction" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "SortDirection": { + "description": "Sort order for `sortColumn`'s values.", + "type": "string", + "enum": [ + "asc", + "desc" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/edit-autofill.mdx b/content/docs/api/mcp/edit-autofill.mdx new file mode 100644 index 0000000..b8216cb --- /dev/null +++ b/content/docs/api/mcp/edit-autofill.mdx @@ -0,0 +1,67 @@ +--- +title: "edit:autofill" +description: "Autofills cell contents." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `source` | `{ from: string; to: string }` | yes | An inclusive rectangle. `from`/`to` may be equal, a single cell. | +| `to` | `string` | yes | — | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "source": { + "$ref": "#/$defs/CellRange" + }, + "to": { + "type": "string" + } + }, + "required": [ + "sheet", + "source", + "to" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/edit-clear.mdx b/content/docs/api/mcp/edit-clear.mdx new file mode 100644 index 0000000..8cdd1aa --- /dev/null +++ b/content/docs/api/mcp/edit-clear.mdx @@ -0,0 +1,62 @@ +--- +title: "edit:clear" +description: "Clears cell contents." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `range` | `{ from: string; to: string }` | yes | An inclusive rectangle. `from`/`to` may be equal, a single cell. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "$ref": "#/$defs/CellRange" + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/edit-fill-down.mdx b/content/docs/api/mcp/edit-fill-down.mdx new file mode 100644 index 0000000..9073d50 --- /dev/null +++ b/content/docs/api/mcp/edit-fill-down.mdx @@ -0,0 +1,62 @@ +--- +title: "edit:fillDown" +description: "Fills a range downward from its top row." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `range` | `{ from: string; to: string }` | yes | An inclusive rectangle. `from`/`to` may be equal, a single cell. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "$ref": "#/$defs/CellRange" + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/edit-fill-right.mdx b/content/docs/api/mcp/edit-fill-right.mdx new file mode 100644 index 0000000..94ac7ca --- /dev/null +++ b/content/docs/api/mcp/edit-fill-right.mdx @@ -0,0 +1,63 @@ +--- +title: "edit:fillRight" +description: "Fills a range rightward from its left column." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `range` | `{ from: string; to: string }` | yes | An inclusive rectangle. `from`/`to` may be equal, a single cell. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "A range whose leading column is the fill source.", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "$ref": "#/$defs/CellRange" + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/edit-find-replace.mdx b/content/docs/api/mcp/edit-find-replace.mdx new file mode 100644 index 0000000..cf99cc7 --- /dev/null +++ b/content/docs/api/mcp/edit-find-replace.mdx @@ -0,0 +1,129 @@ +--- +title: "edit:findReplace" +description: "Finds and replaces text within a range." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `range` | `{ from: string; to: string } or null` | no | The scope to search, the whole sheet's occupied footprint when absent. | +| `query` | `string` | yes | — | +| `replacement` | `string` | yes | — | +| `matchCase` | `boolean` | no | Defaults to `false`. | +| `useRegex` | `boolean` | no | Defaults to `false`. | +| `matchEntireCell` | `boolean` | no | Defaults to `false`. | +| `withinFormulas` | `boolean` | no | Defaults to `false`. | + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `queryCompiled` | `boolean` | yes | Whether `query` compiled as a regex, always `true` when `useRegex` is `false`, since the literal form is always `regex::escape`d before compiling, escaping cannot fail. | +| `matched` | `integer` | yes | How many scope cells' search text matched, counted whether or not the match was eligible to be written back. | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "description": "The scope to search, the whole sheet's occupied footprint when absent.", + "anyOf": [ + { + "$ref": "#/$defs/CellRange" + }, + { + "type": "null" + } + ] + }, + "query": { + "type": "string" + }, + "replacement": { + "type": "string" + }, + "matchCase": { + "type": "boolean", + "default": false + }, + "useRegex": { + "type": "boolean", + "default": false + }, + "matchEntireCell": { + "type": "boolean", + "default": false + }, + "withinFormulas": { + "type": "boolean", + "default": false + } + }, + "required": [ + "sheet", + "query", + "replacement" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "description": "This command's own extra result fields.", + "type": "object", + "properties": { + "queryCompiled": { + "description": "Whether `query` compiled as a regex, always `true` when `useRegex` is `false`, since the literal form is always `regex::escape`d before compiling, escaping cannot fail.", + "type": "boolean" + }, + "matched": { + "description": "How many scope cells' search text matched, counted whether or not the match was eligible to be written back.", + "type": "integer", + "format": "uint", + "minimum": 0 + } + }, + "required": [ + "queryCompiled", + "matched" + ] +} +``` + diff --git a/content/docs/api/mcp/edit-set-cell.mdx b/content/docs/api/mcp/edit-set-cell.mdx new file mode 100644 index 0000000..92e2dda --- /dev/null +++ b/content/docs/api/mcp/edit-set-cell.mdx @@ -0,0 +1,69 @@ +--- +title: "edit:setCell" +description: "Sets the cell." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet name. | +| `a1` | `string` | yes | Target cell, e.g. `"A1"`. | +| `value` | `string` | yes | Raw input: a literal, a formula, leading `=`, or `""` to clear. | +| `inputMode` | `"raw" or null` | no | — | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "a1": { + "description": "Target cell, e.g. `\"A1\"`.", + "type": "string" + }, + "value": { + "description": "Raw input: a literal, a formula, leading `=`, or `\"\"` to clear.", + "type": "string" + }, + "inputMode": { + "anyOf": [ + { + "$ref": "#/$defs/InputMode" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "sheet", + "a1", + "value" + ], + "$defs": { + "InputMode": { + "type": "string", + "enum": [ + "raw" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/edit-set-values.mdx b/content/docs/api/mcp/edit-set-values.mdx new file mode 100644 index 0000000..ecbaad9 --- /dev/null +++ b/content/docs/api/mcp/edit-set-values.mdx @@ -0,0 +1,54 @@ +--- +title: "edit:setValues" +description: "Sets the values." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `anchor` | `string` | yes | — | +| `values` | `array of array of string` | yes | — | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "A rectangular block of raw strings, row-major, anchored at `anchor`.", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "anchor": { + "type": "string" + }, + "values": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "required": [ + "sheet", + "anchor", + "values" + ] +} +``` + diff --git a/content/docs/api/mcp/file-export.mdx b/content/docs/api/mcp/file-export.mdx new file mode 100644 index 0000000..2ad5b0f --- /dev/null +++ b/content/docs/api/mcp/file-export.mdx @@ -0,0 +1,92 @@ +--- +title: "file:export" +description: "Exports a workbook file." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet named on the wire, validated to exist for every `format`. | +| `format` | `"json", "csv", "xlsx"` | yes | Every variant PARSES. | + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `format` | `"json", "csv", "xlsx"` | yes | Every variant PARSES. | +| `content` | `string` | yes | — | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "`commandId` is dropped, the same Batch-0 convention `edit::set_cell::Payload` already uses.", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet named on the wire, validated to exist for every `format`.", + "type": "string" + }, + "format": { + "$ref": "#/$defs/Format" + } + }, + "required": [ + "sheet", + "format" + ], + "$defs": { + "Format": { + "description": "Every variant PARSES.", + "type": "string", + "enum": [ + "json", + "csv", + "xlsx" + ] + } + } +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "description": "`file:export`'s typed result.", + "type": "object", + "properties": { + "format": { + "$ref": "#/$defs/Format" + }, + "content": { + "type": "string" + } + }, + "required": [ + "format", + "content" + ], + "$defs": { + "Format": { + "description": "Every variant PARSES.", + "type": "string", + "enum": [ + "json", + "csv", + "xlsx" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/file-import.mdx b/content/docs/api/mcp/file-import.mdx new file mode 100644 index 0000000..9c53f1c --- /dev/null +++ b/content/docs/api/mcp/file-import.mdx @@ -0,0 +1,105 @@ +--- +title: "file:import" +description: "Imports a workbook file." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `format` | `"json", "csv", "tsv", "xlsx"` | yes | — | +| `encoding` | `"text", "base64"` | no | How `data` is encoded on the wire. `base64` is required for `xlsx`, binary, and allowed for `csv`/`tsv`/`json` too if the caller's bytes happen to be base64-wrapped UTF-8. Defaults to `"text"`. | +| `data` | `string` | yes | — | +| `sheetName` | `string or null` | no | Base name for the created sheet. Omitted defaults to `"Imported"`. NOT validated the way `sheet:add`'s `name` field is. | + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The created sheet's final, deduped, sanitized name. | +| `cellsWritten` | `integer` | yes | Computed by reading the engine back after the write, never a count of attempted writes, the same discipline `sheet:add`/`sheet:rename`/ `edit:setCell` all already apply, never assume a write landed. | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "format": { + "$ref": "#/$defs/Format" + }, + "encoding": { + "$ref": "#/$defs/Encoding", + "default": "text" + }, + "data": { + "type": "string" + }, + "sheetName": { + "description": "Base name for the created sheet. Omitted defaults to `\"Imported\"`. NOT validated the way `sheet:add`'s `name` field is.", + "type": [ + "string", + "null" + ], + "default": null + } + }, + "required": [ + "format", + "data" + ], + "$defs": { + "Format": { + "type": "string", + "enum": [ + "json", + "csv", + "tsv", + "xlsx" + ] + }, + "Encoding": { + "description": "How `data` is encoded on the wire. `base64` is required for `xlsx`, binary, and allowed for `csv`/`tsv`/`json` too if the caller's bytes happen to be base64-wrapped UTF-8.", + "type": "string", + "enum": [ + "text", + "base64" + ] + } + } +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "description": "This command only ever creates one.", + "type": "object", + "properties": { + "sheet": { + "description": "The created sheet's final, deduped, sanitized name.", + "type": "string" + }, + "cellsWritten": { + "description": "Computed by reading the engine back after the write, never a count of attempted writes, the same discipline `sheet:add`/`sheet:rename`/ `edit:setCell` all already apply, never assume a write landed.", + "type": "integer", + "format": "uint", + "minimum": 0 + } + }, + "required": [ + "sheet", + "cellsWritten" + ] +} +``` + diff --git a/content/docs/api/mcp/format-clear.mdx b/content/docs/api/mcp/format-clear.mdx new file mode 100644 index 0000000..5889a81 --- /dev/null +++ b/content/docs/api/mcp/format-clear.mdx @@ -0,0 +1,65 @@ +--- +title: "format:clear" +description: "Clears cell formatting." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet name. | +| `range` | `{ from: string; to: string }` | yes | The target range, e.g. `{"from": "A1", "to": "B3"}`. May legitimately arrive "backwards", `from` below/right of `to`, normalized before use. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "No `value` field.", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/format-fill-color.mdx b/content/docs/api/mcp/format-fill-color.mdx new file mode 100644 index 0000000..a57dc0a --- /dev/null +++ b/content/docs/api/mcp/format-fill-color.mdx @@ -0,0 +1,80 @@ +--- +title: "format:fillColor" +description: "Sets the background fill color of a range." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet name. | +| `range` | `{ from: string; to: string }` | yes | The target range, e.g. `{"from": "A1", "to": "B3"}`. May legitimately arrive "backwards", `from` below/right of `to`, normalized before use. | +| `value` | `string or null` | no | The fill colour to set, or `null` to clear it. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "The fill colour to set, or `null` to clear it.", + "anyOf": [ + { + "$ref": "#/$defs/Color" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "Color": { + "description": "A CSS colour string, `#ff0000`, `#fff2cc`, `rgb(…)`, a named colour.", + "type": "string" + } + } +} +``` + diff --git a/content/docs/api/mcp/format-set-align.mdx b/content/docs/api/mcp/format-set-align.mdx new file mode 100644 index 0000000..92e51fb --- /dev/null +++ b/content/docs/api/mcp/format-set-align.mdx @@ -0,0 +1,96 @@ +--- +title: "format:setAlign" +description: "Sets the horizontal text alignment of a range." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet name. | +| `range` | `{ from: string; to: string }` | yes | The target range, e.g. `{"from": "A1", "to": "B3"}`. May legitimately arrive "backwards", `from` below/right of `to`, normalized before use. | +| `value` | `"left", "center", "right" or null` | no | The horizontal alignment to set, or `null` for automatic, type-based: numbers and dates right, everything else left. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "The horizontal alignment to set, or `null` for automatic, type-based: numbers and dates right, everything else left.", + "anyOf": [ + { + "$ref": "#/$defs/HAlign" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "HAlign": { + "description": "Horizontal text alignment.", + "oneOf": [ + { + "description": "Hug the left edge of the cell box.", + "type": "string", + "const": "left" + }, + { + "description": "Centre within the cell box.", + "type": "string", + "const": "center" + }, + { + "description": "Hug the right edge of the cell box.", + "type": "string", + "const": "right" + } + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/format-set-banded-range.mdx b/content/docs/api/mcp/format-set-banded-range.mdx new file mode 100644 index 0000000..f95e469 --- /dev/null +++ b/content/docs/api/mcp/format-set-banded-range.mdx @@ -0,0 +1,155 @@ +--- +title: "format:setBandedRange" +description: "Sets the banded range." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `range` | `{ from: string; to: string }` | yes | An inclusive rectangle. `from`/`to` may be equal, a single cell. | +| `style` | `{ headerColor?: string or null; firstBandColor: string; secondBandColor: string; footerColor?: string or null }` | yes | The wire shape of a banded range's color assignment. | + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `range` | `{ from: string; to: string }` | yes | An inclusive rectangle. `from`/`to` may be equal, a single cell. | +| `id` | `string` | yes | The new banded range's id. | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "$ref": "#/$defs/CellRange" + }, + "style": { + "$ref": "#/$defs/StyleWire" + } + }, + "required": [ + "sheet", + "range", + "style" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "StyleWire": { + "description": "The wire shape of a banded range's color assignment.", + "type": "object", + "properties": { + "headerColor": { + "anyOf": [ + { + "$ref": "#/$defs/HexColor" + }, + { + "type": "null" + } + ], + "default": null + }, + "firstBandColor": { + "$ref": "#/$defs/HexColor" + }, + "secondBandColor": { + "$ref": "#/$defs/HexColor" + }, + "footerColor": { + "anyOf": [ + { + "$ref": "#/$defs/HexColor" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "required": [ + "firstBandColor", + "secondBandColor" + ] + }, + "HexColor": { + "description": "A strictly-validated `#rgb`/`#rrggbb`/`#rrggbbaa` hex colour.", + "type": "string" + } + } +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "range": { + "$ref": "#/$defs/CellRange" + }, + "id": { + "description": "The new banded range's id.", + "type": "string" + } + }, + "required": [ + "range", + "id" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/format-set-bold.mdx b/content/docs/api/mcp/format-set-bold.mdx new file mode 100644 index 0000000..21c51be --- /dev/null +++ b/content/docs/api/mcp/format-set-bold.mdx @@ -0,0 +1,70 @@ +--- +title: "format:setBold" +description: "Turns bold formatting on or off for a range." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet name. | +| `range` | `{ from: string; to: string }` | yes | The target range, e.g. `{"from": "A1", "to": "B3"}`. May legitimately arrive "backwards", `from` below/right of `to`, normalized before use. | +| `value` | `boolean` | yes | Whether the range should be bold. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "Whether the range should be bold.", + "type": "boolean" + } + }, + "required": [ + "sheet", + "range", + "value" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/format-set-borders.mdx b/content/docs/api/mcp/format-set-borders.mdx new file mode 100644 index 0000000..2bc9a7b --- /dev/null +++ b/content/docs/api/mcp/format-set-borders.mdx @@ -0,0 +1,204 @@ +--- +title: "format:setBorders" +description: "Sets the borders." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet name. | +| `range` | `{ from: string; to: string }` | yes | The target range, e.g. `{"from": "A1", "to": "B3"}`. May legitimately arrive "backwards", `from` below/right of `to`, normalized before use. | +| `mode` | `"all", "inner", "horizontal", "vertical", "outer", "left", "top", "right", "bottom", "clear"` | yes | Which edges to target. | +| `edge` | `{ style: "solid", "dashed", "dotted", "double"; weight: "thin", "medium", "thick"; color: string }` | yes | How the targeted edges should look. Required even for `mode: clear`, parsed but unused there. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "mode": { + "description": "Which edges to target.", + "$ref": "#/$defs/BorderMode" + }, + "edge": { + "description": "How the targeted edges should look. Required even for `mode: clear`, parsed but unused there.", + "$ref": "#/$defs/BorderEdge" + } + }, + "required": [ + "sheet", + "range", + "mode", + "edge" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "BorderMode": { + "description": "The Sheets border-position options.", + "oneOf": [ + { + "description": "Every edge of every cell in the range.", + "type": "string", + "const": "all" + }, + { + "description": "The internal grid lines only, neither the range's outer perimeter.", + "type": "string", + "const": "inner" + }, + { + "description": "The internal horizontal grid lines only, between rows.", + "type": "string", + "const": "horizontal" + }, + { + "description": "The internal vertical grid lines only, between columns.", + "type": "string", + "const": "vertical" + }, + { + "description": "The range's outer perimeter only.", + "type": "string", + "const": "outer" + }, + { + "description": "The range's left edge only.", + "type": "string", + "const": "left" + }, + { + "description": "The range's top edge only.", + "type": "string", + "const": "top" + }, + { + "description": "The range's right edge only.", + "type": "string", + "const": "right" + }, + { + "description": "The range's bottom edge only.", + "type": "string", + "const": "bottom" + }, + { + "description": "Removes borders instead of drawing them, `edge` is parsed but never read for this mode.", + "type": "string", + "const": "clear" + } + ] + }, + "BorderEdge": { + "description": "One drawn edge: how it looks.", + "type": "object", + "properties": { + "style": { + "description": "The line pattern.", + "$ref": "#/$defs/BorderStyle" + }, + "weight": { + "description": "The line weight.", + "$ref": "#/$defs/BorderWeight" + }, + "color": { + "description": "The line colour.", + "$ref": "#/$defs/Color" + } + }, + "additionalProperties": false, + "required": [ + "style", + "weight", + "color" + ] + }, + "BorderStyle": { + "description": "Line pattern for an edge, Sheets' solid / dashed / dotted plus the double rule.", + "oneOf": [ + { + "description": "An unbroken line.", + "type": "string", + "const": "solid" + }, + { + "description": "A dashed line.", + "type": "string", + "const": "dashed" + }, + { + "description": "A dotted line.", + "type": "string", + "const": "dotted" + }, + { + "description": "Two parallel lines.", + "type": "string", + "const": "double" + } + ] + }, + "BorderWeight": { + "description": "Line weight, Sheets' thin / medium / thick.", + "oneOf": [ + { + "description": "The default pen.", + "type": "string", + "const": "thin" + }, + { + "description": "One step heavier.", + "type": "string", + "const": "medium" + }, + { + "description": "The heaviest pen.", + "type": "string", + "const": "thick" + } + ] + }, + "Color": { + "description": "A CSS colour string, `#ff0000`, `#fff2cc`, `rgb(…)`, a named colour.", + "type": "string" + } + } +} +``` + diff --git a/content/docs/api/mcp/format-set-conditional-format.mdx b/content/docs/api/mcp/format-set-conditional-format.mdx new file mode 100644 index 0000000..5171d9d --- /dev/null +++ b/content/docs/api/mcp/format-set-conditional-format.mdx @@ -0,0 +1,259 @@ +--- +title: "format:setConditionalFormat" +description: "Sets the conditional format." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `range` | `{ from: string; to: string }` | yes | An inclusive rectangle. `from`/`to` may be equal, a single cell. | +| `rule` | `{ kind: "singleCondition", … } or { minColor: string; maxColor: string; kind: "colorScale" } or { kind: "customFormula", … }` | yes | One conditional-format rule's wire shape. | + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `range` | `{ from: string; to: string }` | yes | An inclusive rectangle. `from`/`to` may be equal, a single cell. | +| `id` | `string` | yes | The new rule's id. | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "$ref": "#/$defs/CellRange" + }, + "rule": { + "$ref": "#/$defs/RuleWire" + } + }, + "required": [ + "sheet", + "range", + "rule" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "RuleWire": { + "description": "One conditional-format rule's wire shape.", + "oneOf": [ + { + "type": "object", + "properties": { + "operator": { + "$ref": "#/$defs/OperatorWire" + }, + "value": { + "type": "number", + "format": "double" + }, + "value2": { + "type": [ + "number", + "null" + ], + "format": "double" + }, + "style": { + "$ref": "#/$defs/StyleWire" + }, + "kind": { + "type": "string", + "const": "singleCondition" + } + }, + "required": [ + "kind", + "operator", + "value", + "style" + ] + }, + { + "type": "object", + "properties": { + "minColor": { + "$ref": "#/$defs/HexColor" + }, + "maxColor": { + "$ref": "#/$defs/HexColor" + }, + "kind": { + "type": "string", + "const": "colorScale" + } + }, + "required": [ + "kind", + "minColor", + "maxColor" + ] + }, + { + "type": "object", + "properties": { + "formula": { + "type": "string" + }, + "style": { + "$ref": "#/$defs/StyleWire" + }, + "kind": { + "type": "string", + "const": "customFormula" + } + }, + "required": [ + "kind", + "formula", + "style" + ] + } + ] + }, + "OperatorWire": { + "description": "The wire shape of a single-condition rule's numeric comparison operator.", + "type": "string", + "enum": [ + "greaterThan", + "greaterThanOrEqual", + "lessThan", + "lessThanOrEqual", + "equal", + "notEqual", + "between", + "notBetween" + ] + }, + "StyleWire": { + "description": "A conditional-format rule's style, as the wire restricts it.", + "type": "object", + "properties": { + "bold": { + "type": [ + "boolean", + "null" + ] + }, + "italic": { + "type": [ + "boolean", + "null" + ] + }, + "underline": { + "type": [ + "boolean", + "null" + ] + }, + "strike": { + "type": [ + "boolean", + "null" + ] + }, + "color": { + "anyOf": [ + { + "$ref": "#/$defs/HexColor" + }, + { + "type": "null" + } + ] + }, + "fill": { + "anyOf": [ + { + "$ref": "#/$defs/HexColor" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "HexColor": { + "description": "A strictly-validated `#rgb`/`#rrggbb`/`#rrggbbaa` hex colour.", + "type": "string" + } + } +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "range": { + "$ref": "#/$defs/CellRange" + }, + "id": { + "description": "The new rule's id.", + "type": "string" + } + }, + "required": [ + "range", + "id" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/format-set-decimals.mdx b/content/docs/api/mcp/format-set-decimals.mdx new file mode 100644 index 0000000..971f28e --- /dev/null +++ b/content/docs/api/mcp/format-set-decimals.mdx @@ -0,0 +1,119 @@ +--- +title: "format:setDecimals" +description: "Sets the decimals." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet name. | +| `range` | `{ from: string; to: string }` | yes | The target range, e.g. `{"from": "A1", "to": "B3"}`. May legitimately arrive "backwards", `from` below/right of `to`, normalized before use. | +| `value` | `integer` | yes | The decimal count to set. `0` is a real value here. | +| `numberFormat` | `"number", "percent", "currency", "date", "datetime" or null` | no | An optional companion category to set alongside `value` in the same call. Omitted, not merely `null` means "leave the category alone". Defaults to `null`. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "The decimal count to set. `0` is a real value here.", + "$ref": "#/$defs/Decimals" + }, + "numberFormat": { + "description": "An optional companion category to set alongside `value` in the same call. Omitted, not merely `null` means \"leave the category alone\".", + "anyOf": [ + { + "$ref": "#/$defs/NumberFormat" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "required": [ + "sheet", + "range", + "value" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "Decimals": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "NumberFormat": { + "description": "A number-display category, studio#10.", + "oneOf": [ + { + "description": "Grouped fixed-point: `1,234.57`.", + "type": "string", + "const": "number" + }, + { + "description": "The value times 100, with a `%` suffix.", + "type": "string", + "const": "percent" + }, + { + "description": "Grouped fixed-point with a currency symbol.", + "type": "string", + "const": "currency" + }, + { + "description": "The value read as a date serial. **Implies date typing**.", + "type": "string", + "const": "date" + }, + { + "description": "The value read as a date-time serial.", + "type": "string", + "const": "datetime" + } + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/format-set-font-family.mdx b/content/docs/api/mcp/format-set-font-family.mdx new file mode 100644 index 0000000..86bddcc --- /dev/null +++ b/content/docs/api/mcp/format-set-font-family.mdx @@ -0,0 +1,74 @@ +--- +title: "format:setFontFamily" +description: "Sets the font family." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet name. | +| `range` | `{ from: string; to: string }` | yes | The target range, e.g. `{"from": "A1", "to": "B3"}`. May legitimately arrive "backwards", `from` below/right of `to`, normalized before use. | +| `value` | `string` | yes | The font family to set. Non-nullable. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "The font family to set. Non-nullable.", + "$ref": "#/$defs/FontFamily" + } + }, + "required": [ + "sheet", + "range", + "value" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "FontFamily": { + "description": "A font family name.", + "type": "string" + } + } +} +``` + diff --git a/content/docs/api/mcp/format-set-font-size.mdx b/content/docs/api/mcp/format-set-font-size.mdx new file mode 100644 index 0000000..ae48590 --- /dev/null +++ b/content/docs/api/mcp/format-set-font-size.mdx @@ -0,0 +1,75 @@ +--- +title: "format:setFontSize" +description: "Sets the font size." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet name. | +| `range` | `{ from: string; to: string }` | yes | The target range, e.g. `{"from": "A1", "to": "B3"}`. May legitimately arrive "backwards", `from` below/right of `to`, normalized before use. | +| `value` | `number` | yes | The font size to set. Non-nullable. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "The font size to set. Non-nullable.", + "$ref": "#/$defs/FontSize" + } + }, + "required": [ + "sheet", + "range", + "value" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "FontSize": { + "description": "A font size in points.", + "type": "number", + "format": "double" + } + } +} +``` + diff --git a/content/docs/api/mcp/format-set-italic.mdx b/content/docs/api/mcp/format-set-italic.mdx new file mode 100644 index 0000000..171f381 --- /dev/null +++ b/content/docs/api/mcp/format-set-italic.mdx @@ -0,0 +1,70 @@ +--- +title: "format:setItalic" +description: "Turns italic formatting on or off for a range." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet name. | +| `range` | `{ from: string; to: string }` | yes | The target range, e.g. `{"from": "A1", "to": "B3"}`. May legitimately arrive "backwards", `from` below/right of `to`, normalized before use. | +| `value` | `boolean` | yes | Whether the range should be italic. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "Whether the range should be italic.", + "type": "boolean" + } + }, + "required": [ + "sheet", + "range", + "value" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/format-set-number-format.mdx b/content/docs/api/mcp/format-set-number-format.mdx new file mode 100644 index 0000000..1a76878 --- /dev/null +++ b/content/docs/api/mcp/format-set-number-format.mdx @@ -0,0 +1,105 @@ +--- +title: "format:setNumberFormat" +description: "Sets the number format." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet name. | +| `range` | `{ from: string; to: string }` | yes | The target range, e.g. `{"from": "A1", "to": "B3"}`. May legitimately arrive "backwards", `from` below/right of `to`, normalized before use. | +| `value` | `"number", "percent", "currency", "date", "datetime" or null` | no | — | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "anyOf": [ + { + "$ref": "#/$defs/NumberFormat" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "NumberFormat": { + "description": "A number-display category, studio#10.", + "oneOf": [ + { + "description": "Grouped fixed-point: `1,234.57`.", + "type": "string", + "const": "number" + }, + { + "description": "The value times 100, with a `%` suffix.", + "type": "string", + "const": "percent" + }, + { + "description": "Grouped fixed-point with a currency symbol.", + "type": "string", + "const": "currency" + }, + { + "description": "The value read as a date serial. **Implies date typing**.", + "type": "string", + "const": "date" + }, + { + "description": "The value read as a date-time serial.", + "type": "string", + "const": "datetime" + } + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/format-set-rotation.mdx b/content/docs/api/mcp/format-set-rotation.mdx new file mode 100644 index 0000000..09aedb0 --- /dev/null +++ b/content/docs/api/mcp/format-set-rotation.mdx @@ -0,0 +1,81 @@ +--- +title: "format:setRotation" +description: "Sets the rotation." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet name. | +| `range` | `{ from: string; to: string }` | yes | The target range, e.g. `{"from": "A1", "to": "B3"}`. May legitimately arrive "backwards", `from` below/right of `to`, normalized before use. | +| `value` | `number or null` | no | The rotation in degrees to set, or `null`, equivalently `0` to clear it. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "The rotation in degrees to set, or `null`, equivalently `0` to clear it.", + "anyOf": [ + { + "$ref": "#/$defs/Rotation" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "Rotation": { + "description": "Text rotation in degrees: positive tilts counter-clockwise, Sheets' \"up\", negative clockwise, \"down\".", + "type": "number", + "format": "double" + } + } +} +``` + diff --git a/content/docs/api/mcp/format-set-strike.mdx b/content/docs/api/mcp/format-set-strike.mdx new file mode 100644 index 0000000..0ecdd9b --- /dev/null +++ b/content/docs/api/mcp/format-set-strike.mdx @@ -0,0 +1,70 @@ +--- +title: "format:setStrike" +description: "Turns strikethrough formatting on or off for a range." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet name. | +| `range` | `{ from: string; to: string }` | yes | The target range, e.g. `{"from": "A1", "to": "B3"}`. May legitimately arrive "backwards", `from` below/right of `to`, normalized before use. | +| `value` | `boolean` | yes | Whether the range should be strike. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "Whether the range should be strike.", + "type": "boolean" + } + }, + "required": [ + "sheet", + "range", + "value" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/format-set-underline.mdx b/content/docs/api/mcp/format-set-underline.mdx new file mode 100644 index 0000000..4e2c5c6 --- /dev/null +++ b/content/docs/api/mcp/format-set-underline.mdx @@ -0,0 +1,70 @@ +--- +title: "format:setUnderline" +description: "Turns underline formatting on or off for a range." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet name. | +| `range` | `{ from: string; to: string }` | yes | The target range, e.g. `{"from": "A1", "to": "B3"}`. May legitimately arrive "backwards", `from` below/right of `to`, normalized before use. | +| `value` | `boolean` | yes | Whether the range should be underline. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "Whether the range should be underline.", + "type": "boolean" + } + }, + "required": [ + "sheet", + "range", + "value" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/format-set-valign.mdx b/content/docs/api/mcp/format-set-valign.mdx new file mode 100644 index 0000000..19a7cd1 --- /dev/null +++ b/content/docs/api/mcp/format-set-valign.mdx @@ -0,0 +1,96 @@ +--- +title: "format:setValign" +description: "Sets the vertical text alignment of a range." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet name. | +| `range` | `{ from: string; to: string }` | yes | The target range, e.g. `{"from": "A1", "to": "B3"}`. May legitimately arrive "backwards", `from` below/right of `to`, normalized before use. | +| `value` | `"top", "middle", "bottom" or null` | no | The vertical alignment to set, or `null` for Sheets' default, bottom. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "The vertical alignment to set, or `null` for Sheets' default, bottom.", + "anyOf": [ + { + "$ref": "#/$defs/VAlign" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "VAlign": { + "description": "Vertical text alignment within the cell box.", + "oneOf": [ + { + "description": "Top of the cell box.", + "type": "string", + "const": "top" + }, + { + "description": "Vertically centred.", + "type": "string", + "const": "middle" + }, + { + "description": "Bottom of the cell box, Sheets' default.", + "type": "string", + "const": "bottom" + } + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/format-set-wrap.mdx b/content/docs/api/mcp/format-set-wrap.mdx new file mode 100644 index 0000000..b4eb633 --- /dev/null +++ b/content/docs/api/mcp/format-set-wrap.mdx @@ -0,0 +1,70 @@ +--- +title: "format:setWrap" +description: "Sets the text-wrapping mode of a range." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet name. | +| `range` | `{ from: string; to: string }` | yes | The target range, e.g. `{"from": "A1", "to": "B3"}`. May legitimately arrive "backwards", `from` below/right of `to`, normalized before use. | +| `value` | `boolean` | yes | Whether the range should wrap text. `false` clears the attribute. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "Whether the range should wrap text. `false` clears the attribute.", + "type": "boolean" + } + }, + "required": [ + "sheet", + "range", + "value" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/format-text-color.mdx b/content/docs/api/mcp/format-text-color.mdx new file mode 100644 index 0000000..d24d0d6 --- /dev/null +++ b/content/docs/api/mcp/format-text-color.mdx @@ -0,0 +1,80 @@ +--- +title: "format:textColor" +description: "Sets the text color of a range." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet name. | +| `range` | `{ from: string; to: string }` | yes | The target range, e.g. `{"from": "A1", "to": "B3"}`. May legitimately arrive "backwards", `from` below/right of `to`, normalized before use. | +| `value` | `string or null` | no | The text colour to set, or `null` to clear it. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "The text colour to set, or `null` to clear it.", + "anyOf": [ + { + "$ref": "#/$defs/Color" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "Color": { + "description": "A CSS colour string, `#ff0000`, `#fff2cc`, `rgb(…)`, a named colour.", + "type": "string" + } + } +} +``` + diff --git a/content/docs/api/mcp/history-redo.mdx b/content/docs/api/mcp/history-redo.mdx new file mode 100644 index 0000000..2ba1392 --- /dev/null +++ b/content/docs/api/mcp/history-redo.mdx @@ -0,0 +1,49 @@ +--- +title: "history:redo" +description: "Re-applies the most recently undone edit." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +This tool takes no parameters. + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `redone` | `boolean` | yes | `true` only when something was actually popped AND fully reapplied. `false` for a genuinely empty redo stack, a normal, non-error outcome, not a refusal. | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "Deliberately empty.", + "type": "object" +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "redone": { + "description": "`true` only when something was actually popped AND fully reapplied. `false` for a genuinely empty redo stack, a normal, non-error outcome, not a refusal.", + "type": "boolean" + } + }, + "required": [ + "redone" + ] +} +``` + diff --git a/content/docs/api/mcp/history-restore.mdx b/content/docs/api/mcp/history-restore.mdx new file mode 100644 index 0000000..af71ce5 --- /dev/null +++ b/content/docs/api/mcp/history-restore.mdx @@ -0,0 +1,71 @@ +--- +title: "history:restore" +description: "Restores the workbook to a specific point in its edit history." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `steps` | `integer` | yes | How many undo steps to walk back, from wherever the stack is right now. `0` is a legal, trivially-successful no-op. | + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `stepsRequested` | `integer` | yes | Echoed from the payload. | +| `stepsCompleted` | `integer` | yes | How many steps actually completed, equal to `stepsRequested` on full success. | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "steps": { + "description": "How many undo steps to walk back, from wherever the stack is right now. `0` is a legal, trivially-successful no-op.", + "type": "integer", + "format": "uint32", + "minimum": 0 + } + }, + "required": [ + "steps" + ] +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "stepsRequested": { + "description": "Echoed from the payload.", + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "stepsCompleted": { + "description": "How many steps actually completed, equal to `stepsRequested` on full success.", + "type": "integer", + "format": "uint32", + "minimum": 0 + } + }, + "required": [ + "stepsRequested", + "stepsCompleted" + ] +} +``` + diff --git a/content/docs/api/mcp/history-undo.mdx b/content/docs/api/mcp/history-undo.mdx new file mode 100644 index 0000000..95ad1a3 --- /dev/null +++ b/content/docs/api/mcp/history-undo.mdx @@ -0,0 +1,49 @@ +--- +title: "history:undo" +description: "Undoes the workbook's most recent edit." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +This tool takes no parameters. + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `undone` | `boolean` | yes | `true` only when something was actually popped AND fully reverted. `false` for a genuinely empty undo stack, a normal, non-error outcome, not a refusal. | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "Deliberately empty.", + "type": "object" +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "undone": { + "description": "`true` only when something was actually popped AND fully reverted. `false` for a genuinely empty undo stack, a normal, non-error outcome, not a refusal.", + "type": "boolean" + } + }, + "required": [ + "undone" + ] +} +``` + diff --git a/content/docs/api/mcp/index.mdx b/content/docs/api/mcp/index.mdx index e0fc7ae..79fef21 100644 --- a/content/docs/api/mcp/index.mdx +++ b/content/docs/api/mcp/index.mdx @@ -1,8 +1,64 @@ --- title: MCP server -description: TrueCalc tools for MCP clients such as Claude Desktop and Claude Code. +description: TrueCalc's native MCP server exposes 66 tools for reading and editing a workbook to Claude Desktop, Claude Code, and other MCP clients. +seoTitle: "TrueCalc MCP Server: 66 Tools for AI Agents to Edit Spreadsheets" +seoDescription: "TrueCalc's MCP server gives AI agents 66 tools to read and edit a spreadsheet workbook — cells, formatting, charts, sheets, and more — over the Model Context Protocol." +llmsDescription: "TrueCalc's MCP server: a native process exposing 66 tools (edit, format, structure, data, chart, sheet, read, history, file, view, clipboard) for reading and editing one open workbook, for MCP clients like Claude Desktop and Claude Code." --- -Stub — this section will be generated from the `truecalc-mcp` tool schemas -(`evaluate`, `validate`, `explain`, `batch_evaluate`, `list_functions`, and the -upcoming `workbook_*` tools). +TrueCalc ships a native [MCP](https://modelcontextprotocol.io) server: a +process that speaks the Model Context Protocol and exposes spreadsheet +editing and reading as **66 tools**, so an MCP-compatible agent can work with +a TrueCalc workbook the same way a person would in the grid — setting cell +values, formatting ranges, inserting charts, sorting data, and reading back +what's there. + +Each tool is named after the operation it performs, grouped by area with a +colon, like `edit:setCell` or `chart:insert`. The tables below group all 66 +by area; every tool has its own reference page with its full parameter list, +return shape, and JSON Schema. + +## What it replaces + +This section used to describe a different, now-removed tool set from an +earlier, unrelated crate. The server documented here is a new, native +implementation with its own tool surface — nothing on this page describes +that earlier one. + +## Connecting + +The server communicates over **stdio**: it's a subprocess your MCP client +starts and talks to over standard input/output, not a network service you +point a URL at. Because this is a newly shipped server, this page +deliberately doesn't prescribe exact installation or configuration commands +that haven't been verified end-to-end — consult the documentation for the +MCP client you're using (Claude Desktop, Claude Code, or another) for how it +expects a stdio MCP server to be registered, and point it at this server's +executable. + +The server holds **one open workbook per process** — there's no +multi-workbook session or workbook-ID concept in this tool surface. A client +that needs to work with more than one workbook runs more than one server +process. + +## The tool surface + +| Area | Tools | What it covers | +| --- | --- | --- | +| `edit` | 7 | Cell values: set, clear, fill down/right, find & replace | +| `format` | 18 | Cell presentation: bold/italic/underline/strike, colors, number formats, borders, alignment, wrapping, banded ranges, conditional formatting | +| `structure` | 10 | Rows, columns, and merged cells: insert, delete, reorder, merge, unmerge | +| `read` | 9 | Reading back values, formulas, formats, charts, named ranges, banded ranges, conditional formats, and sheet metadata | +| `data` | 7 | Filters, named ranges, data validation, sorting, and pivot tables | +| `sheet` | 5 | Adding, deleting, renaming, reordering, and activating sheets | +| `chart` | 3 | Inserting, updating, and removing charts | +| `history` | 3 | Undo, redo, and restoring an earlier point in the edit history | +| `file` | 2 | Importing and exporting a workbook — see each tool's own page for which formats are implemented today | +| `clipboard` | 1 | Pasting previously copied or cut cells | +| `view` | 1 | Page setup for printing | + +## Reference + +Every one of the 66 tools has its own page in the sidebar under **MCP**, +listing its parameters, what it returns, and its full JSON Schema for +callers that want to validate requests structurally rather than read prose. diff --git a/content/docs/api/mcp/meta.json b/content/docs/api/mcp/meta.json index 26253e2..c7fc3e2 100644 --- a/content/docs/api/mcp/meta.json +++ b/content/docs/api/mcp/meta.json @@ -1,3 +1,72 @@ { - "title": "MCP" + "title": "MCP", + "pages": [ + "index", + "chart-insert", + "chart-remove", + "chart-update", + "clipboard-paste", + "data-clear-filter", + "data-delete-named-range", + "data-insert-pivot", + "data-set-filter", + "data-set-named-range", + "data-set-validation", + "data-sort-range", + "edit-autofill", + "edit-clear", + "edit-fill-down", + "edit-fill-right", + "edit-find-replace", + "edit-set-cell", + "edit-set-values", + "file-export", + "file-import", + "format-clear", + "format-fill-color", + "format-set-align", + "format-set-banded-range", + "format-set-bold", + "format-set-borders", + "format-set-conditional-format", + "format-set-decimals", + "format-set-font-family", + "format-set-font-size", + "format-set-italic", + "format-set-number-format", + "format-set-rotation", + "format-set-strike", + "format-set-underline", + "format-set-valign", + "format-set-wrap", + "format-text-color", + "history-redo", + "history-restore", + "history-undo", + "read-get-banded-ranges", + "read-get-charts", + "read-get-conditional-formats", + "read-get-extent", + "read-get-formats", + "read-get-named-ranges", + "read-get-range", + "read-get-sheets", + "read-get-values", + "sheet-add", + "sheet-delete", + "sheet-rename", + "sheet-reorder", + "sheet-set-active", + "structure-delete-column", + "structure-delete-row", + "structure-insert-column", + "structure-insert-row", + "structure-merge-cells", + "structure-merge-horizontally", + "structure-merge-vertically", + "structure-reorder-columns", + "structure-reorder-rows", + "structure-unmerge-cells", + "view-set-page-setup" + ] } diff --git a/content/docs/api/mcp/read-get-banded-ranges.mdx b/content/docs/api/mcp/read-get-banded-ranges.mdx new file mode 100644 index 0000000..c46e13f --- /dev/null +++ b/content/docs/api/mcp/read-get-banded-ranges.mdx @@ -0,0 +1,141 @@ +--- +title: "read:getBandedRanges" +description: "Gets the banded ranges." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `bandedRanges` | `array of { id: string; range: object; style: object }` | yes | Every banded range on `sheet`, in real precedence order. | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + } + }, + "required": [ + "sheet" + ] +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "bandedRanges": { + "description": "Every banded range on `sheet`, in real precedence order.", + "type": "array", + "items": { + "$ref": "#/$defs/BandedRangeInfo" + } + } + }, + "required": [ + "bandedRanges" + ], + "$defs": { + "BandedRangeInfo": { + "description": "One banded range's identity, target rectangle, and style.", + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "range": { + "$ref": "#/$defs/CellRange" + }, + "style": { + "$ref": "#/$defs/StyleOut" + } + }, + "required": [ + "id", + "range", + "style" + ] + }, + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "StyleOut": { + "description": "A banded range's color assignment, as reported back by this command.", + "type": "object", + "properties": { + "headerColor": { + "anyOf": [ + { + "$ref": "#/$defs/HexColor" + }, + { + "type": "null" + } + ] + }, + "firstBandColor": { + "$ref": "#/$defs/HexColor" + }, + "secondBandColor": { + "$ref": "#/$defs/HexColor" + }, + "footerColor": { + "anyOf": [ + { + "$ref": "#/$defs/HexColor" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "firstBandColor", + "secondBandColor" + ] + }, + "HexColor": { + "description": "A strictly-validated `#rgb`/`#rrggbb`/`#rrggbbaa` hex colour.", + "type": "string" + } + } +} +``` + diff --git a/content/docs/api/mcp/read-get-charts.mdx b/content/docs/api/mcp/read-get-charts.mdx new file mode 100644 index 0000000..1830757 --- /dev/null +++ b/content/docs/api/mcp/read-get-charts.mdx @@ -0,0 +1,108 @@ +--- +title: "read:getCharts" +description: "Gets the charts." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet name. | + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `charts` | `array of { chartId: string; range: object; chartType: string; options: any }` | yes | — | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "No `commandId`/OCC field modeled.", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + } + }, + "required": [ + "sheet" + ] +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "charts": { + "type": "array", + "items": { + "$ref": "#/$defs/ChartInfo" + } + } + }, + "required": [ + "charts" + ], + "$defs": { + "ChartInfo": { + "description": "One chart's identity, placement, form, and renderer options.", + "type": "object", + "properties": { + "chartId": { + "type": "string" + }, + "range": { + "description": "The chart's target rectangle, A1-rendered.", + "$ref": "#/$defs/CellRange" + }, + "chartType": { + "description": "Which chart form to draw, e.g. `\"column\"`, `\"box-plot\"`.", + "type": "string" + }, + "options": { + "description": "Renderer-specific knobs, opaque, unvalidated by this read, matches the TS source's own `options: c.options` passthrough." + } + }, + "required": [ + "chartId", + "range", + "chartType", + "options" + ] + }, + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/read-get-conditional-formats.mdx b/content/docs/api/mcp/read-get-conditional-formats.mdx new file mode 100644 index 0000000..497d982 --- /dev/null +++ b/content/docs/api/mcp/read-get-conditional-formats.mdx @@ -0,0 +1,561 @@ +--- +title: "read:getConditionalFormats" +description: "Gets the conditional formats." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `rules` | `array of { id: string; range: object; rule: object or object or object }` | yes | Every conditional-format rule on `sheet`, in real precedence order. | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + } + }, + "required": [ + "sheet" + ] +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "rules": { + "description": "Every conditional-format rule on `sheet`, in real precedence order.", + "type": "array", + "items": { + "$ref": "#/$defs/ConditionalFormatRuleInfo" + } + } + }, + "required": [ + "rules" + ], + "$defs": { + "ConditionalFormatRuleInfo": { + "description": "One conditional-format rule's identity, target rectangle, and definition.", + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "range": { + "$ref": "#/$defs/CellRange" + }, + "rule": { + "$ref": "#/$defs/RuleOut" + } + }, + "required": [ + "id", + "range", + "rule" + ] + }, + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "RuleOut": { + "description": "One rule's definition, as reported back by this command.", + "oneOf": [ + { + "type": "object", + "properties": { + "operator": { + "$ref": "#/$defs/OperatorOut" + }, + "value": { + "type": "number", + "format": "double" + }, + "value2": { + "type": [ + "number", + "null" + ], + "format": "double" + }, + "style": { + "$ref": "#/$defs/CellFormat" + }, + "kind": { + "type": "string", + "const": "singleCondition" + } + }, + "required": [ + "kind", + "operator", + "value", + "style" + ] + }, + { + "type": "object", + "properties": { + "minColor": { + "$ref": "#/$defs/HexColor" + }, + "maxColor": { + "$ref": "#/$defs/HexColor" + }, + "kind": { + "type": "string", + "const": "colorScale" + } + }, + "required": [ + "kind", + "minColor", + "maxColor" + ] + }, + { + "type": "object", + "properties": { + "formula": { + "type": "string" + }, + "style": { + "$ref": "#/$defs/CellFormat" + }, + "kind": { + "type": "string", + "const": "customFormula" + } + }, + "required": [ + "kind", + "formula", + "style" + ] + } + ] + }, + "OperatorOut": { + "description": "A single-condition rule's operator, as reported back by this command.", + "type": "string", + "enum": [ + "greaterThan", + "greaterThanOrEqual", + "lessThan", + "lessThanOrEqual", + "equal", + "notEqual", + "between", + "notBetween" + ] + }, + "CellFormat": { + "description": "A cell's grid-owned presentation.", + "type": "object", + "properties": { + "bold": { + "description": "Bold text. Absent or `false` = not bold.", + "type": [ + "boolean", + "null" + ] + }, + "italic": { + "description": "Italic text.", + "type": [ + "boolean", + "null" + ] + }, + "strike": { + "description": "Struck-through text.", + "type": [ + "boolean", + "null" + ] + }, + "underline": { + "description": "Underlined text.", + "type": [ + "boolean", + "null" + ] + }, + "fontFamily": { + "description": "Font family. Absent = the grid's default face.", + "anyOf": [ + { + "$ref": "#/$defs/FontFamily" + }, + { + "type": "null" + } + ] + }, + "fontSize": { + "description": "Font size in points. Absent = the grid's default size.", + "anyOf": [ + { + "$ref": "#/$defs/FontSize" + }, + { + "type": "null" + } + ] + }, + "borders": { + "description": "Per-edge cell borders. Absent = no borders, never present-and-empty.", + "anyOf": [ + { + "$ref": "#/$defs/CellBorders" + }, + { + "type": "null" + } + ] + }, + "color": { + "description": "Text colour. Absent = the grid's default.", + "anyOf": [ + { + "$ref": "#/$defs/Color" + }, + { + "type": "null" + } + ] + }, + "fill": { + "description": "Background fill. Absent = none, the grid's own background shows.", + "anyOf": [ + { + "$ref": "#/$defs/Color" + }, + { + "type": "null" + } + ] + }, + "numberFormat": { + "description": "Number-display category. Absent = automatic, the engine's raw display.", + "anyOf": [ + { + "$ref": "#/$defs/NumberFormat" + }, + { + "type": "null" + } + ] + }, + "decimals": { + "anyOf": [ + { + "$ref": "#/$defs/Decimals" + }, + { + "type": "null" + } + ] + }, + "align": { + "description": "Horizontal alignment. Absent = automatic, numbers right, else left.", + "anyOf": [ + { + "$ref": "#/$defs/HAlign" + }, + { + "type": "null" + } + ] + }, + "valign": { + "description": "Vertical alignment. Absent = bottom, Sheets' default.", + "anyOf": [ + { + "$ref": "#/$defs/VAlign" + }, + { + "type": "null" + } + ] + }, + "wrap": { + "description": "Wrap text into lines within the column width, growing the row to fit.", + "type": [ + "boolean", + "null" + ] + }, + "rotation": { + "description": "Text rotation in degrees. Absent, or `0` = none.", + "anyOf": [ + { + "$ref": "#/$defs/Rotation" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "FontFamily": { + "description": "A font family name.", + "type": "string" + }, + "FontSize": { + "description": "A font size in points.", + "type": "number", + "format": "double" + }, + "CellBorders": { + "description": "A cell's borders, any **non-empty** subset of the four edges.", + "type": "object", + "properties": { + "bottom": { + "description": "The bottom edge, if drawn.", + "anyOf": [ + { + "$ref": "#/$defs/BorderEdge" + }, + { + "type": "null" + } + ] + }, + "left": { + "description": "The left edge, if drawn.", + "anyOf": [ + { + "$ref": "#/$defs/BorderEdge" + }, + { + "type": "null" + } + ] + }, + "right": { + "description": "The right edge, if drawn.", + "anyOf": [ + { + "$ref": "#/$defs/BorderEdge" + }, + { + "type": "null" + } + ] + }, + "top": { + "description": "The top edge, if drawn.", + "anyOf": [ + { + "$ref": "#/$defs/BorderEdge" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "BorderEdge": { + "description": "One drawn edge: how it looks.", + "type": "object", + "properties": { + "style": { + "description": "The line pattern.", + "$ref": "#/$defs/BorderStyle" + }, + "weight": { + "description": "The line weight.", + "$ref": "#/$defs/BorderWeight" + }, + "color": { + "description": "The line colour.", + "$ref": "#/$defs/Color" + } + }, + "additionalProperties": false, + "required": [ + "style", + "weight", + "color" + ] + }, + "BorderStyle": { + "description": "Line pattern for an edge, Sheets' solid / dashed / dotted plus the double rule.", + "oneOf": [ + { + "description": "An unbroken line.", + "type": "string", + "const": "solid" + }, + { + "description": "A dashed line.", + "type": "string", + "const": "dashed" + }, + { + "description": "A dotted line.", + "type": "string", + "const": "dotted" + }, + { + "description": "Two parallel lines.", + "type": "string", + "const": "double" + } + ] + }, + "BorderWeight": { + "description": "Line weight, Sheets' thin / medium / thick.", + "oneOf": [ + { + "description": "The default pen.", + "type": "string", + "const": "thin" + }, + { + "description": "One step heavier.", + "type": "string", + "const": "medium" + }, + { + "description": "The heaviest pen.", + "type": "string", + "const": "thick" + } + ] + }, + "Color": { + "description": "A CSS colour string, `#ff0000`, `#fff2cc`, `rgb(…)`, a named colour.", + "type": "string" + }, + "NumberFormat": { + "description": "A number-display category, studio#10.", + "oneOf": [ + { + "description": "Grouped fixed-point: `1,234.57`.", + "type": "string", + "const": "number" + }, + { + "description": "The value times 100, with a `%` suffix.", + "type": "string", + "const": "percent" + }, + { + "description": "Grouped fixed-point with a currency symbol.", + "type": "string", + "const": "currency" + }, + { + "description": "The value read as a date serial. **Implies date typing**.", + "type": "string", + "const": "date" + }, + { + "description": "The value read as a date-time serial.", + "type": "string", + "const": "datetime" + } + ] + }, + "Decimals": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "HAlign": { + "description": "Horizontal text alignment.", + "oneOf": [ + { + "description": "Hug the left edge of the cell box.", + "type": "string", + "const": "left" + }, + { + "description": "Centre within the cell box.", + "type": "string", + "const": "center" + }, + { + "description": "Hug the right edge of the cell box.", + "type": "string", + "const": "right" + } + ] + }, + "VAlign": { + "description": "Vertical text alignment within the cell box.", + "oneOf": [ + { + "description": "Top of the cell box.", + "type": "string", + "const": "top" + }, + { + "description": "Vertically centred.", + "type": "string", + "const": "middle" + }, + { + "description": "Bottom of the cell box, Sheets' default.", + "type": "string", + "const": "bottom" + } + ] + }, + "Rotation": { + "description": "Text rotation in degrees: positive tilts counter-clockwise, Sheets' \"up\", negative clockwise, \"down\".", + "type": "number", + "format": "double" + }, + "HexColor": { + "description": "A strictly-validated `#rgb`/`#rrggbb`/`#rrggbbaa` hex colour.", + "type": "string" + } + } +} +``` + diff --git a/content/docs/api/mcp/read-get-extent.mdx b/content/docs/api/mcp/read-get-extent.mdx new file mode 100644 index 0000000..c3bd4a0 --- /dev/null +++ b/content/docs/api/mcp/read-get-extent.mdx @@ -0,0 +1,70 @@ +--- +title: "read:getExtent" +description: "Gets the extent." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet name. | + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `rows` | `integer` | yes | The highest populated row, 1-based, or `0` if the sheet is empty. | +| `cols` | `integer` | yes | The highest populated column, 1-based, or `0` if the sheet is empty. | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + } + }, + "required": [ + "sheet" + ] +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "description": "The USED extent, not a capacity.", + "type": "object", + "properties": { + "rows": { + "description": "The highest populated row, 1-based, or `0` if the sheet is empty.", + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "cols": { + "description": "The highest populated column, 1-based, or `0` if the sheet is empty.", + "type": "integer", + "format": "uint32", + "minimum": 0 + } + }, + "required": [ + "rows", + "cols" + ] +} +``` + diff --git a/content/docs/api/mcp/read-get-formats.mdx b/content/docs/api/mcp/read-get-formats.mdx new file mode 100644 index 0000000..fc60759 --- /dev/null +++ b/content/docs/api/mcp/read-get-formats.mdx @@ -0,0 +1,507 @@ +--- +title: "read:getFormats" +description: "Gets the formats." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet name. | +| `range` | `{ from: string; to: string }` | yes | The inclusive rectangle to read. | + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `range` | `{ from: string; to: string }` | yes | The rectangle this call answered for, completely. | +| `cells` | `{ [key: string]: { format: object; effectiveFormat: object; merged: boolean; spilled: boolean } }` | yes | One entry per address in `range`, keyed by its plain A1 form. | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The inclusive rectangle to read.", + "$ref": "#/$defs/CellRange" + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "range": { + "description": "The rectangle this call answered for, completely.", + "$ref": "#/$defs/CellRange" + }, + "cells": { + "description": "One entry per address in `range`, keyed by its plain A1 form.", + "type": "object", + "additionalProperties": { + "$ref": "#/$defs/Cell" + } + } + }, + "required": [ + "range", + "cells" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "Cell": { + "description": "One cell's format read-back.", + "type": "object", + "properties": { + "format": { + "description": "This cell's own stored format, grid-owned presentation only.", + "$ref": "#/$defs/CellFormat" + }, + "effectiveFormat": { + "description": "**Known Batch-0 approximation**. Always equal to `format` today, not yet a real base → banded → conditional merge.", + "$ref": "#/$defs/CellFormat" + }, + "merged": { + "description": "Whether this cell falls inside a merged range.", + "type": "boolean" + }, + "spilled": { + "description": "Whether this cell is a spill anchor, an authored formula whose stored array occupies more than itself or one of the cells it spills into, an \"echo\" cell.", + "type": "boolean" + } + }, + "required": [ + "format", + "effectiveFormat", + "merged", + "spilled" + ] + }, + "CellFormat": { + "description": "A cell's grid-owned presentation.", + "type": "object", + "properties": { + "bold": { + "description": "Bold text. Absent or `false` = not bold.", + "type": [ + "boolean", + "null" + ] + }, + "italic": { + "description": "Italic text.", + "type": [ + "boolean", + "null" + ] + }, + "strike": { + "description": "Struck-through text.", + "type": [ + "boolean", + "null" + ] + }, + "underline": { + "description": "Underlined text.", + "type": [ + "boolean", + "null" + ] + }, + "fontFamily": { + "description": "Font family. Absent = the grid's default face.", + "anyOf": [ + { + "$ref": "#/$defs/FontFamily" + }, + { + "type": "null" + } + ] + }, + "fontSize": { + "description": "Font size in points. Absent = the grid's default size.", + "anyOf": [ + { + "$ref": "#/$defs/FontSize" + }, + { + "type": "null" + } + ] + }, + "borders": { + "description": "Per-edge cell borders. Absent = no borders, never present-and-empty.", + "anyOf": [ + { + "$ref": "#/$defs/CellBorders" + }, + { + "type": "null" + } + ] + }, + "color": { + "description": "Text colour. Absent = the grid's default.", + "anyOf": [ + { + "$ref": "#/$defs/Color" + }, + { + "type": "null" + } + ] + }, + "fill": { + "description": "Background fill. Absent = none, the grid's own background shows.", + "anyOf": [ + { + "$ref": "#/$defs/Color" + }, + { + "type": "null" + } + ] + }, + "numberFormat": { + "description": "Number-display category. Absent = automatic, the engine's raw display.", + "anyOf": [ + { + "$ref": "#/$defs/NumberFormat" + }, + { + "type": "null" + } + ] + }, + "decimals": { + "anyOf": [ + { + "$ref": "#/$defs/Decimals" + }, + { + "type": "null" + } + ] + }, + "align": { + "description": "Horizontal alignment. Absent = automatic, numbers right, else left.", + "anyOf": [ + { + "$ref": "#/$defs/HAlign" + }, + { + "type": "null" + } + ] + }, + "valign": { + "description": "Vertical alignment. Absent = bottom, Sheets' default.", + "anyOf": [ + { + "$ref": "#/$defs/VAlign" + }, + { + "type": "null" + } + ] + }, + "wrap": { + "description": "Wrap text into lines within the column width, growing the row to fit.", + "type": [ + "boolean", + "null" + ] + }, + "rotation": { + "description": "Text rotation in degrees. Absent, or `0` = none.", + "anyOf": [ + { + "$ref": "#/$defs/Rotation" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "FontFamily": { + "description": "A font family name.", + "type": "string" + }, + "FontSize": { + "description": "A font size in points.", + "type": "number", + "format": "double" + }, + "CellBorders": { + "description": "A cell's borders, any **non-empty** subset of the four edges.", + "type": "object", + "properties": { + "bottom": { + "description": "The bottom edge, if drawn.", + "anyOf": [ + { + "$ref": "#/$defs/BorderEdge" + }, + { + "type": "null" + } + ] + }, + "left": { + "description": "The left edge, if drawn.", + "anyOf": [ + { + "$ref": "#/$defs/BorderEdge" + }, + { + "type": "null" + } + ] + }, + "right": { + "description": "The right edge, if drawn.", + "anyOf": [ + { + "$ref": "#/$defs/BorderEdge" + }, + { + "type": "null" + } + ] + }, + "top": { + "description": "The top edge, if drawn.", + "anyOf": [ + { + "$ref": "#/$defs/BorderEdge" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "BorderEdge": { + "description": "One drawn edge: how it looks.", + "type": "object", + "properties": { + "style": { + "description": "The line pattern.", + "$ref": "#/$defs/BorderStyle" + }, + "weight": { + "description": "The line weight.", + "$ref": "#/$defs/BorderWeight" + }, + "color": { + "description": "The line colour.", + "$ref": "#/$defs/Color" + } + }, + "additionalProperties": false, + "required": [ + "style", + "weight", + "color" + ] + }, + "BorderStyle": { + "description": "Line pattern for an edge, Sheets' solid / dashed / dotted plus the double rule.", + "oneOf": [ + { + "description": "An unbroken line.", + "type": "string", + "const": "solid" + }, + { + "description": "A dashed line.", + "type": "string", + "const": "dashed" + }, + { + "description": "A dotted line.", + "type": "string", + "const": "dotted" + }, + { + "description": "Two parallel lines.", + "type": "string", + "const": "double" + } + ] + }, + "BorderWeight": { + "description": "Line weight, Sheets' thin / medium / thick.", + "oneOf": [ + { + "description": "The default pen.", + "type": "string", + "const": "thin" + }, + { + "description": "One step heavier.", + "type": "string", + "const": "medium" + }, + { + "description": "The heaviest pen.", + "type": "string", + "const": "thick" + } + ] + }, + "Color": { + "description": "A CSS colour string, `#ff0000`, `#fff2cc`, `rgb(…)`, a named colour.", + "type": "string" + }, + "NumberFormat": { + "description": "A number-display category, studio#10.", + "oneOf": [ + { + "description": "Grouped fixed-point: `1,234.57`.", + "type": "string", + "const": "number" + }, + { + "description": "The value times 100, with a `%` suffix.", + "type": "string", + "const": "percent" + }, + { + "description": "Grouped fixed-point with a currency symbol.", + "type": "string", + "const": "currency" + }, + { + "description": "The value read as a date serial. **Implies date typing**.", + "type": "string", + "const": "date" + }, + { + "description": "The value read as a date-time serial.", + "type": "string", + "const": "datetime" + } + ] + }, + "Decimals": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "HAlign": { + "description": "Horizontal text alignment.", + "oneOf": [ + { + "description": "Hug the left edge of the cell box.", + "type": "string", + "const": "left" + }, + { + "description": "Centre within the cell box.", + "type": "string", + "const": "center" + }, + { + "description": "Hug the right edge of the cell box.", + "type": "string", + "const": "right" + } + ] + }, + "VAlign": { + "description": "Vertical text alignment within the cell box.", + "oneOf": [ + { + "description": "Top of the cell box.", + "type": "string", + "const": "top" + }, + { + "description": "Vertically centred.", + "type": "string", + "const": "middle" + }, + { + "description": "Bottom of the cell box, Sheets' default.", + "type": "string", + "const": "bottom" + } + ] + }, + "Rotation": { + "description": "Text rotation in degrees: positive tilts counter-clockwise, Sheets' \"up\", negative clockwise, \"down\".", + "type": "number", + "format": "double" + } + } +} +``` + diff --git a/content/docs/api/mcp/read-get-named-ranges.mdx b/content/docs/api/mcp/read-get-named-ranges.mdx new file mode 100644 index 0000000..b755984 --- /dev/null +++ b/content/docs/api/mcp/read-get-named-ranges.mdx @@ -0,0 +1,94 @@ +--- +title: "read:getNamedRanges" +description: "Gets the named ranges." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +This tool takes no parameters. + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `namedRanges` | `array of { name: string; sheet: string; range: object }` | yes | Every named range, in declaration order. | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "Deliberately empty.", + "type": "object" +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "namedRanges": { + "description": "Every named range, in declaration order.", + "type": "array", + "items": { + "$ref": "#/$defs/NamedRangeInfo" + } + } + }, + "required": [ + "namedRanges" + ], + "$defs": { + "NamedRangeInfo": { + "description": "One named range's identity and real target.", + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "sheet": { + "description": "The named range's REAL target sheet, parsed from its own `ref`.", + "type": "string" + }, + "range": { + "description": "The named range's target rectangle.", + "$ref": "#/$defs/CellRange" + } + }, + "required": [ + "name", + "sheet", + "range" + ] + }, + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/read-get-range.mdx b/content/docs/api/mcp/read-get-range.mdx new file mode 100644 index 0000000..471a852 --- /dev/null +++ b/content/docs/api/mcp/read-get-range.mdx @@ -0,0 +1,511 @@ +--- +title: "read:getRange" +description: "Gets the range." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet name. | +| `range` | `{ from: string; to: string }` | yes | The inclusive rectangle to read. | + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `range` | `{ from: string; to: string }` | yes | The rectangle this call answered for, completely. | +| `cells` | `{ [key: string]: { value?: any; display: string; formula?: string or null; rawInput: string; format: object } }` | yes | One entry per address in `range`, keyed by its plain A1 form. | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The inclusive rectangle to read.", + "$ref": "#/$defs/CellRange" + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "range": { + "description": "The rectangle this call answered for, completely.", + "$ref": "#/$defs/CellRange" + }, + "cells": { + "description": "One entry per address in `range`, keyed by its plain A1 form.", + "type": "object", + "additionalProperties": { + "$ref": "#/$defs/Cell" + } + } + }, + "required": [ + "range", + "cells" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "Cell": { + "description": "One cell's read-back.", + "type": "object", + "properties": { + "value": { + "description": "`unknown` already covers the `null` case too, so no separate `| null` is needed." + }, + "display": { + "description": "**Known Batch-0 approximation**. Not a real number-format-aware render, a plain literal rendering of `value`.", + "type": "string" + }, + "formula": { + "type": [ + "string", + "null" + ] + }, + "rawInput": { + "description": "The formula string when present, otherwise the same approximation as `display`.", + "type": "string" + }, + "format": { + "description": "This cell's effective format.", + "$ref": "#/$defs/CellFormat" + } + }, + "required": [ + "display", + "rawInput", + "format" + ] + }, + "CellFormat": { + "description": "A cell's grid-owned presentation.", + "type": "object", + "properties": { + "bold": { + "description": "Bold text. Absent or `false` = not bold.", + "type": [ + "boolean", + "null" + ] + }, + "italic": { + "description": "Italic text.", + "type": [ + "boolean", + "null" + ] + }, + "strike": { + "description": "Struck-through text.", + "type": [ + "boolean", + "null" + ] + }, + "underline": { + "description": "Underlined text.", + "type": [ + "boolean", + "null" + ] + }, + "fontFamily": { + "description": "Font family. Absent = the grid's default face.", + "anyOf": [ + { + "$ref": "#/$defs/FontFamily" + }, + { + "type": "null" + } + ] + }, + "fontSize": { + "description": "Font size in points. Absent = the grid's default size.", + "anyOf": [ + { + "$ref": "#/$defs/FontSize" + }, + { + "type": "null" + } + ] + }, + "borders": { + "description": "Per-edge cell borders. Absent = no borders, never present-and-empty.", + "anyOf": [ + { + "$ref": "#/$defs/CellBorders" + }, + { + "type": "null" + } + ] + }, + "color": { + "description": "Text colour. Absent = the grid's default.", + "anyOf": [ + { + "$ref": "#/$defs/Color" + }, + { + "type": "null" + } + ] + }, + "fill": { + "description": "Background fill. Absent = none, the grid's own background shows.", + "anyOf": [ + { + "$ref": "#/$defs/Color" + }, + { + "type": "null" + } + ] + }, + "numberFormat": { + "description": "Number-display category. Absent = automatic, the engine's raw display.", + "anyOf": [ + { + "$ref": "#/$defs/NumberFormat" + }, + { + "type": "null" + } + ] + }, + "decimals": { + "anyOf": [ + { + "$ref": "#/$defs/Decimals" + }, + { + "type": "null" + } + ] + }, + "align": { + "description": "Horizontal alignment. Absent = automatic, numbers right, else left.", + "anyOf": [ + { + "$ref": "#/$defs/HAlign" + }, + { + "type": "null" + } + ] + }, + "valign": { + "description": "Vertical alignment. Absent = bottom, Sheets' default.", + "anyOf": [ + { + "$ref": "#/$defs/VAlign" + }, + { + "type": "null" + } + ] + }, + "wrap": { + "description": "Wrap text into lines within the column width, growing the row to fit.", + "type": [ + "boolean", + "null" + ] + }, + "rotation": { + "description": "Text rotation in degrees. Absent, or `0` = none.", + "anyOf": [ + { + "$ref": "#/$defs/Rotation" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "FontFamily": { + "description": "A font family name.", + "type": "string" + }, + "FontSize": { + "description": "A font size in points.", + "type": "number", + "format": "double" + }, + "CellBorders": { + "description": "A cell's borders, any **non-empty** subset of the four edges.", + "type": "object", + "properties": { + "bottom": { + "description": "The bottom edge, if drawn.", + "anyOf": [ + { + "$ref": "#/$defs/BorderEdge" + }, + { + "type": "null" + } + ] + }, + "left": { + "description": "The left edge, if drawn.", + "anyOf": [ + { + "$ref": "#/$defs/BorderEdge" + }, + { + "type": "null" + } + ] + }, + "right": { + "description": "The right edge, if drawn.", + "anyOf": [ + { + "$ref": "#/$defs/BorderEdge" + }, + { + "type": "null" + } + ] + }, + "top": { + "description": "The top edge, if drawn.", + "anyOf": [ + { + "$ref": "#/$defs/BorderEdge" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "BorderEdge": { + "description": "One drawn edge: how it looks.", + "type": "object", + "properties": { + "style": { + "description": "The line pattern.", + "$ref": "#/$defs/BorderStyle" + }, + "weight": { + "description": "The line weight.", + "$ref": "#/$defs/BorderWeight" + }, + "color": { + "description": "The line colour.", + "$ref": "#/$defs/Color" + } + }, + "additionalProperties": false, + "required": [ + "style", + "weight", + "color" + ] + }, + "BorderStyle": { + "description": "Line pattern for an edge, Sheets' solid / dashed / dotted plus the double rule.", + "oneOf": [ + { + "description": "An unbroken line.", + "type": "string", + "const": "solid" + }, + { + "description": "A dashed line.", + "type": "string", + "const": "dashed" + }, + { + "description": "A dotted line.", + "type": "string", + "const": "dotted" + }, + { + "description": "Two parallel lines.", + "type": "string", + "const": "double" + } + ] + }, + "BorderWeight": { + "description": "Line weight, Sheets' thin / medium / thick.", + "oneOf": [ + { + "description": "The default pen.", + "type": "string", + "const": "thin" + }, + { + "description": "One step heavier.", + "type": "string", + "const": "medium" + }, + { + "description": "The heaviest pen.", + "type": "string", + "const": "thick" + } + ] + }, + "Color": { + "description": "A CSS colour string, `#ff0000`, `#fff2cc`, `rgb(…)`, a named colour.", + "type": "string" + }, + "NumberFormat": { + "description": "A number-display category, studio#10.", + "oneOf": [ + { + "description": "Grouped fixed-point: `1,234.57`.", + "type": "string", + "const": "number" + }, + { + "description": "The value times 100, with a `%` suffix.", + "type": "string", + "const": "percent" + }, + { + "description": "Grouped fixed-point with a currency symbol.", + "type": "string", + "const": "currency" + }, + { + "description": "The value read as a date serial. **Implies date typing**.", + "type": "string", + "const": "date" + }, + { + "description": "The value read as a date-time serial.", + "type": "string", + "const": "datetime" + } + ] + }, + "Decimals": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "HAlign": { + "description": "Horizontal text alignment.", + "oneOf": [ + { + "description": "Hug the left edge of the cell box.", + "type": "string", + "const": "left" + }, + { + "description": "Centre within the cell box.", + "type": "string", + "const": "center" + }, + { + "description": "Hug the right edge of the cell box.", + "type": "string", + "const": "right" + } + ] + }, + "VAlign": { + "description": "Vertical text alignment within the cell box.", + "oneOf": [ + { + "description": "Top of the cell box.", + "type": "string", + "const": "top" + }, + { + "description": "Vertically centred.", + "type": "string", + "const": "middle" + }, + { + "description": "Bottom of the cell box, Sheets' default.", + "type": "string", + "const": "bottom" + } + ] + }, + "Rotation": { + "description": "Text rotation in degrees: positive tilts counter-clockwise, Sheets' \"up\", negative clockwise, \"down\".", + "type": "number", + "format": "double" + } + } +} +``` + diff --git a/content/docs/api/mcp/read-get-sheets.mdx b/content/docs/api/mcp/read-get-sheets.mdx new file mode 100644 index 0000000..9a2e267 --- /dev/null +++ b/content/docs/api/mcp/read-get-sheets.mdx @@ -0,0 +1,74 @@ +--- +title: "read:getSheets" +description: "Gets the sheets." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +This tool takes no parameters. + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheets` | `array of { name: string; order: integer }` | yes | Every sheet, in tab order. | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "Deliberately empty. Accepts any JSON object, including `{}`, ignoring unknown fields.", + "type": "object" +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "sheets": { + "description": "Every sheet, in tab order.", + "type": "array", + "items": { + "$ref": "#/$defs/SheetInfo" + } + } + }, + "required": [ + "sheets" + ], + "$defs": { + "SheetInfo": { + "description": "One sheet's identity and tab position.", + "type": "object", + "properties": { + "name": { + "description": "The sheet's name, exactly as stored.", + "type": "string" + }, + "order": { + "description": "0-based tab position.", + "type": "integer", + "format": "uint", + "minimum": 0 + } + }, + "required": [ + "name", + "order" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/read-get-values.mdx b/content/docs/api/mcp/read-get-values.mdx new file mode 100644 index 0000000..b16f2c9 --- /dev/null +++ b/content/docs/api/mcp/read-get-values.mdx @@ -0,0 +1,193 @@ +--- +title: "read:getValues" +description: "Gets the values." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet name. | +| `range` | `{ from: string; to: string }` | yes | The inclusive rectangle to read. | +| `layers` | `"values", "formulas", "both"` | no | Which layer(s) to read. Google Sheets' own `getValues()` default. | +| `encoding` | `"rows", "a1"` | no | How to shape `values`/`formulas` in the response. Defaults to `"rows"`. | + +## Returns + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `range` | `{ from: string; to: string }` | yes | The rectangle this call answered for, completely. | +| `rows` | `integer` | yes | `range`'s row count. | +| `cols` | `integer` | yes | `range`'s column count. | +| `encoding` | `"rows", "a1"` | yes | Echoes the requested shape, so a caller reading `values`/`formulas` out of band still knows how to interpret it. | +| `nonEmpty` | `array of string` | yes | Every address in `range` whose display text is non-empty or which holds a formula, in row-major, reading order, the sparse summary a caller wants before paying to decode a mostly-empty rectangle. | +| `values` | `any` | no | Present iff `layers` was `values`/`both`. Row-major `Vec>` or an A1-keyed map, depending on `encoding`. | +| `formulas` | `any` | no | Present iff `layers` was `formulas`/`both`. Same shape rule as `values`, an empty string where a cell holds no formula. | + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The inclusive rectangle to read.", + "$ref": "#/$defs/CellRange" + }, + "layers": { + "$ref": "#/$defs/Layers", + "default": "values" + }, + "encoding": { + "$ref": "#/$defs/Encoding", + "default": "rows" + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "Layers": { + "description": "Which layer(s) to read. Google Sheets' own `getValues()` default.", + "type": "string", + "enum": [ + "values", + "formulas", + "both" + ] + }, + "Encoding": { + "description": "How to shape `values`/`formulas` in the response.", + "oneOf": [ + { + "description": "Row-major arrays: `values[i][j]` is the cell at `range`'s `i`-th row, `j`-th column.", + "type": "string", + "const": "rows" + }, + { + "description": "A map keyed by plain A1 form, `\"A1\"`, one entry per address in `range`.", + "type": "string", + "const": "a1" + } + ] + } + } +} +``` + +Response payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "range": { + "description": "The rectangle this call answered for, completely.", + "$ref": "#/$defs/CellRange" + }, + "rows": { + "description": "`range`'s row count.", + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "cols": { + "description": "`range`'s column count.", + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "encoding": { + "description": "Echoes the requested shape, so a caller reading `values`/`formulas` out of band still knows how to interpret it.", + "$ref": "#/$defs/Encoding" + }, + "nonEmpty": { + "description": "Every address in `range` whose display text is non-empty or which holds a formula, in row-major, reading order, the sparse summary a caller wants before paying to decode a mostly-empty rectangle.", + "type": "array", + "items": { + "type": "string" + } + }, + "values": { + "description": "Present iff `layers` was `values`/`both`. Row-major `Vec>` or an A1-keyed map, depending on `encoding`." + }, + "formulas": { + "description": "Present iff `layers` was `formulas`/`both`. Same shape rule as `values`, an empty string where a cell holds no formula." + } + }, + "required": [ + "range", + "rows", + "cols", + "encoding", + "nonEmpty" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "Encoding": { + "description": "How to shape `values`/`formulas` in the response.", + "oneOf": [ + { + "description": "Row-major arrays: `values[i][j]` is the cell at `range`'s `i`-th row, `j`-th column.", + "type": "string", + "const": "rows" + }, + { + "description": "A map keyed by plain A1 form, `\"A1\"`, one entry per address in `range`.", + "type": "string", + "const": "a1" + } + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/sheet-add.mdx b/content/docs/api/mcp/sheet-add.mdx new file mode 100644 index 0000000..8ddca50 --- /dev/null +++ b/content/docs/api/mcp/sheet-add.mdx @@ -0,0 +1,39 @@ +--- +title: "sheet:add" +description: "Adds a sheet." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `name` | `string or null` | no | The name to give the new sheet. When present, this command trims it before validating. An explicit whitespace-only name is therefore refused as malformed, empty after trim, never silently treated as omitted. Defaults to `null`. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "name": { + "description": "The name to give the new sheet. When present, this command trims it before validating. An explicit whitespace-only name is therefore refused as malformed, empty after trim, never silently treated as omitted.", + "type": [ + "string", + "null" + ], + "default": null + } + } +} +``` + diff --git a/content/docs/api/mcp/sheet-delete.mdx b/content/docs/api/mcp/sheet-delete.mdx new file mode 100644 index 0000000..d805985 --- /dev/null +++ b/content/docs/api/mcp/sheet-delete.mdx @@ -0,0 +1,38 @@ +--- +title: "sheet:delete" +description: "Deletes a sheet." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet to delete. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet to delete.", + "type": "string" + } + }, + "required": [ + "sheet" + ] +} +``` + diff --git a/content/docs/api/mcp/sheet-rename.mdx b/content/docs/api/mcp/sheet-rename.mdx new file mode 100644 index 0000000..6e6b21e --- /dev/null +++ b/content/docs/api/mcp/sheet-rename.mdx @@ -0,0 +1,44 @@ +--- +title: "sheet:rename" +description: "Renames a sheet." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet to rename. This is the sheet's NAME. | +| `name` | `string` | yes | The name to rename it to. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet to rename. This is the sheet's NAME.", + "type": "string" + }, + "name": { + "description": "The name to rename it to.", + "type": "string" + } + }, + "required": [ + "sheet", + "name" + ] +} +``` + diff --git a/content/docs/api/mcp/sheet-reorder.mdx b/content/docs/api/mcp/sheet-reorder.mdx new file mode 100644 index 0000000..1d696d6 --- /dev/null +++ b/content/docs/api/mcp/sheet-reorder.mdx @@ -0,0 +1,54 @@ +--- +title: "sheet:reorder" +description: "Reorders a sheet." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet to move. This is the sheet's NAME. | +| `direction` | `"left", "right"` | yes | Which way to move it, one tab position, never an absolute position. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet to move. This is the sheet's NAME.", + "type": "string" + }, + "direction": { + "description": "Which way to move it, one tab position, never an absolute position.", + "$ref": "#/$defs/Direction" + } + }, + "required": [ + "sheet", + "direction" + ], + "$defs": { + "Direction": { + "description": "Which way to move the sheet.", + "type": "string", + "enum": [ + "left", + "right" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/sheet-set-active.mdx b/content/docs/api/mcp/sheet-set-active.mdx new file mode 100644 index 0000000..b442ff6 --- /dev/null +++ b/content/docs/api/mcp/sheet-set-active.mdx @@ -0,0 +1,39 @@ +--- +title: "sheet:setActive" +description: "Sets the active sheet." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | The sheet to make active. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "The sheet to activate.", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet to make active.", + "type": "string" + } + }, + "required": [ + "sheet" + ] +} +``` + diff --git a/content/docs/api/mcp/structure-delete-column.mdx b/content/docs/api/mcp/structure-delete-column.mdx new file mode 100644 index 0000000..85c1098 --- /dev/null +++ b/content/docs/api/mcp/structure-delete-column.mdx @@ -0,0 +1,49 @@ +--- +title: "structure:deleteColumn" +description: "Deletes the column." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `column` | `string` | yes | — | +| `count` | `integer` | no | Defaults to `1`. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "column": { + "type": "string" + }, + "count": { + "type": "integer", + "format": "uint32", + "minimum": 0, + "default": 1 + } + }, + "required": [ + "sheet", + "column" + ] +} +``` + diff --git a/content/docs/api/mcp/structure-delete-row.mdx b/content/docs/api/mcp/structure-delete-row.mdx new file mode 100644 index 0000000..9ae3a82 --- /dev/null +++ b/content/docs/api/mcp/structure-delete-row.mdx @@ -0,0 +1,51 @@ +--- +title: "structure:deleteRow" +description: "Deletes the row." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `row` | `integer` | yes | — | +| `count` | `integer` | no | Defaults to `1`. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "row": { + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "count": { + "type": "integer", + "format": "uint32", + "minimum": 0, + "default": 1 + } + }, + "required": [ + "sheet", + "row" + ] +} +``` + diff --git a/content/docs/api/mcp/structure-insert-column.mdx b/content/docs/api/mcp/structure-insert-column.mdx new file mode 100644 index 0000000..8f0a236 --- /dev/null +++ b/content/docs/api/mcp/structure-insert-column.mdx @@ -0,0 +1,49 @@ +--- +title: "structure:insertColumn" +description: "Inserts the column." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `beforeColumn` | `string` | yes | — | +| `count` | `integer` | no | Defaults to `1`. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "beforeColumn": { + "type": "string" + }, + "count": { + "type": "integer", + "format": "uint32", + "minimum": 0, + "default": 1 + } + }, + "required": [ + "sheet", + "beforeColumn" + ] +} +``` + diff --git a/content/docs/api/mcp/structure-insert-row.mdx b/content/docs/api/mcp/structure-insert-row.mdx new file mode 100644 index 0000000..80f8a17 --- /dev/null +++ b/content/docs/api/mcp/structure-insert-row.mdx @@ -0,0 +1,52 @@ +--- +title: "structure:insertRow" +description: "Inserts the row." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `beforeRow` | `integer` | yes | — | +| `count` | `integer` | no | Defaults to `1`. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "`beforeRow`/`count`, matching studio's `insert-row` schema.", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "beforeRow": { + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "count": { + "type": "integer", + "format": "uint32", + "minimum": 0, + "default": 1 + } + }, + "required": [ + "sheet", + "beforeRow" + ] +} +``` + diff --git a/content/docs/api/mcp/structure-merge-cells.mdx b/content/docs/api/mcp/structure-merge-cells.mdx new file mode 100644 index 0000000..2455392 --- /dev/null +++ b/content/docs/api/mcp/structure-merge-cells.mdx @@ -0,0 +1,62 @@ +--- +title: "structure:mergeCells" +description: "Merges the cells." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `range` | `{ from: string; to: string }` | yes | An inclusive rectangle. `from`/`to` may be equal, a single cell. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "$ref": "#/$defs/CellRange" + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/structure-merge-horizontally.mdx b/content/docs/api/mcp/structure-merge-horizontally.mdx new file mode 100644 index 0000000..04c0791 --- /dev/null +++ b/content/docs/api/mcp/structure-merge-horizontally.mdx @@ -0,0 +1,62 @@ +--- +title: "structure:mergeHorizontally" +description: "Merges each row of a range into one cell, horizontally." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `range` | `{ from: string; to: string }` | yes | An inclusive rectangle. `from`/`to` may be equal, a single cell. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "$ref": "#/$defs/CellRange" + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/structure-merge-vertically.mdx b/content/docs/api/mcp/structure-merge-vertically.mdx new file mode 100644 index 0000000..123c5f3 --- /dev/null +++ b/content/docs/api/mcp/structure-merge-vertically.mdx @@ -0,0 +1,62 @@ +--- +title: "structure:mergeVertically" +description: "Merges each column of a range into one cell, vertically." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `range` | `{ from: string; to: string }` | yes | An inclusive rectangle. `from`/`to` may be equal, a single cell. | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "$ref": "#/$defs/CellRange" + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } +} +``` + diff --git a/content/docs/api/mcp/structure-reorder-columns.mdx b/content/docs/api/mcp/structure-reorder-columns.mdx new file mode 100644 index 0000000..9a13c9a --- /dev/null +++ b/content/docs/api/mcp/structure-reorder-columns.mdx @@ -0,0 +1,54 @@ +--- +title: "structure:reorderColumns" +description: "Reorders the columns." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `fromColumn` | `string` | yes | — | +| `count` | `integer` | no | Defaults to `1`. | +| `toColumn` | `string` | yes | — | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "fromColumn": { + "type": "string" + }, + "count": { + "type": "integer", + "format": "uint32", + "minimum": 0, + "default": 1 + }, + "toColumn": { + "type": "string" + } + }, + "required": [ + "sheet", + "fromColumn", + "toColumn" + ] +} +``` + diff --git a/content/docs/api/mcp/structure-reorder-rows.mdx b/content/docs/api/mcp/structure-reorder-rows.mdx new file mode 100644 index 0000000..6d6ab0a --- /dev/null +++ b/content/docs/api/mcp/structure-reorder-rows.mdx @@ -0,0 +1,58 @@ +--- +title: "structure:reorderRows" +description: "Reorders the rows." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `fromRow` | `integer` | yes | — | +| `count` | `integer` | no | Defaults to `1`. | +| `toRow` | `integer` | yes | — | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "fromRow": { + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "count": { + "type": "integer", + "format": "uint32", + "minimum": 0, + "default": 1 + }, + "toRow": { + "type": "integer", + "format": "uint32", + "minimum": 0 + } + }, + "required": [ + "sheet", + "fromRow", + "toRow" + ] +} +``` + diff --git a/content/docs/api/mcp/structure-unmerge-cells.mdx b/content/docs/api/mcp/structure-unmerge-cells.mdx new file mode 100644 index 0000000..13d346b --- /dev/null +++ b/content/docs/api/mcp/structure-unmerge-cells.mdx @@ -0,0 +1,43 @@ +--- +title: "structure:unmergeCells" +description: "Splits previously merged cells back apart." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `a1` | `string` | yes | — | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "The single cell, anchor or interior whose covering merge should be dissolved.", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "a1": { + "type": "string" + } + }, + "required": [ + "sheet", + "a1" + ] +} +``` + diff --git a/content/docs/api/mcp/view-set-page-setup.mdx b/content/docs/api/mcp/view-set-page-setup.mdx new file mode 100644 index 0000000..9a44cbb --- /dev/null +++ b/content/docs/api/mcp/view-set-page-setup.mdx @@ -0,0 +1,246 @@ +--- +title: "view:setPageSetup" +description: "Sets the page setup." +--- + +{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */} + +## Parameters + +| Name | Type | Required | Description | +| --- | --- | --- | --- | +| `sheet` | `string` | yes | — | +| `orientation` | `"portrait", "landscape" or null` | no | — | +| `scale` | `{ mode: "normal", "fitWidth", "custom"; percent?: number or null } or null` | no | — | +| `marginsMode` | `"normal", "narrow", "custom" or null` | no | — | +| `customMargins` | `{ top: number; right: number; bottom: number; left: number } or null` | no | — | +| `printArea` | `{ r0: integer; r1: integer; c0: integer; c1: integer } or null` | no | Three states. | +| `showGridlines` | `boolean or null` | no | — | +| `header` | `{ left?: string or null; center?: string or null; right?: string or null } or null` | no | — | +| `footer` | `{ left?: string or null; center?: string or null; right?: string or null } or null` | no | — | + +## Returns + +Nothing beyond the standard MCP success envelope. + +## Schema + +Request payload, as JSON Schema: + +```json +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "orientation": { + "anyOf": [ + { + "$ref": "#/$defs/WireOrientation" + }, + { + "type": "null" + } + ] + }, + "scale": { + "anyOf": [ + { + "$ref": "#/$defs/WireScale" + }, + { + "type": "null" + } + ] + }, + "marginsMode": { + "anyOf": [ + { + "$ref": "#/$defs/WireMarginsMode" + }, + { + "type": "null" + } + ] + }, + "customMargins": { + "anyOf": [ + { + "$ref": "#/$defs/WireMargins" + }, + { + "type": "null" + } + ] + }, + "printArea": { + "description": "Three states.", + "anyOf": [ + { + "$ref": "#/$defs/WirePrintArea" + }, + { + "type": "null" + } + ] + }, + "showGridlines": { + "type": [ + "boolean", + "null" + ] + }, + "header": { + "anyOf": [ + { + "$ref": "#/$defs/WireHeaderFooter" + }, + { + "type": "null" + } + ] + }, + "footer": { + "anyOf": [ + { + "$ref": "#/$defs/WireHeaderFooter" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "sheet" + ], + "$defs": { + "WireOrientation": { + "type": "string", + "enum": [ + "portrait", + "landscape" + ] + }, + "WireScale": { + "type": "object", + "properties": { + "mode": { + "$ref": "#/$defs/WireScaleMode" + }, + "percent": { + "type": [ + "number", + "null" + ], + "format": "double" + } + }, + "required": [ + "mode" + ] + }, + "WireScaleMode": { + "type": "string", + "enum": [ + "normal", + "fitWidth", + "custom" + ] + }, + "WireMarginsMode": { + "type": "string", + "enum": [ + "normal", + "narrow", + "custom" + ] + }, + "WireMargins": { + "type": "object", + "properties": { + "top": { + "type": "number", + "format": "double" + }, + "right": { + "type": "number", + "format": "double" + }, + "bottom": { + "type": "number", + "format": "double" + }, + "left": { + "type": "number", + "format": "double" + } + }, + "required": [ + "top", + "right", + "bottom", + "left" + ] + }, + "WirePrintArea": { + "type": "object", + "properties": { + "r0": { + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "r1": { + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "c0": { + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "c1": { + "type": "integer", + "format": "uint32", + "minimum": 0 + } + }, + "required": [ + "r0", + "r1", + "c0", + "c1" + ] + }, + "WireHeaderFooter": { + "type": "object", + "properties": { + "left": { + "type": [ + "string", + "null" + ] + }, + "center": { + "type": [ + "string", + "null" + ] + }, + "right": { + "type": [ + "string", + "null" + ] + } + } + } + } +} +``` + diff --git a/package.json b/package.json index 6c596cf..514b9eb 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "postinstall": "fumadocs-mdx", "test-docs": "node scripts/test-docs.mjs", "gen-docs": "node scripts/gen-docs.mjs", + "gen-mcp-docs": "node scripts/gen-mcp-docs.mjs", "sync:openapi": "node scripts/sync-openapi.mjs", "gen:openapi-docs": "node scripts/gen-openapi-docs.mjs", "lint:enrichment": "node scripts/lint-enrichment.mjs", diff --git a/scripts/gen-mcp-docs.mjs b/scripts/gen-mcp-docs.mjs new file mode 100644 index 0000000..ab3bc6c --- /dev/null +++ b/scripts/gen-mcp-docs.mjs @@ -0,0 +1,499 @@ +#!/usr/bin/env node +/** + * gen-mcp-docs: regenerate content/docs/api/mcp/ from a snapshot of the + * native MCP server's per-tool JSON Schemas. + * + * SOURCE GAP (mirrors gen-docs.mjs's own PINNED_CORE_REF TODO): the schema + * data lives in TrueCalc's private commercial-layer repo, so this script + * does NOT fetch it the way gen-docs.mjs fetches functions.json from the + * public truecalc/core over raw.githubusercontent.com. Instead + * scripts/mcp-source/tool-schemas.json is a manually-placed, committed + * snapshot (66 tools as of writing). TODO(mcp-schema-fetch): automate this + * once the source repo can publish schema dumps somewhere this (public) + * repo can fetch from without private-repo access -- a GitHub App/token with + * read access, or a public release asset. Until then, refreshing these + * pages means re-copying scripts/mcp-source/tool-schemas.json by hand and + * re-running this script. + * + * The schema descriptions are Rust doc comments written for the crate's own + * contributors, not for a docs reader: they reference internal types + * (`EditSetCellSchema`), rustdoc intra-doc links, source files + * (`envelope.ts`), and internal issue IDs (`pro#120`). See cleanText() / + * summaryFor() below for how this script separates user-facing meaning from + * that implementation narration, and falls back to a plain description + * derived from the tool's own wire name rather than publishing anything + * unsalvageable. + * + * CI runs this and fails on drift (`git diff --exit-code -- content/docs/api/mcp`), + * so generated pages must never be edited by hand. + */ +import { mkdirSync, rmSync, writeFileSync, readFileSync, existsSync, readdirSync } from 'node:fs'; +import { join, dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const root = join(dirname(fileURLToPath(import.meta.url)), '..'); +const sourcePath = join(root, 'scripts', 'mcp-source', 'tool-schemas.json'); +const outDir = join(root, 'content', 'docs', 'api', 'mcp'); + +// --------------------------------------------------------------------------- +// Text cleanup: separate user-facing meaning from Rust-implementation +// narration in a JSON Schema `description` field. +// --------------------------------------------------------------------------- + +/** Escape characters MDX would treat as JSX/expressions, but only OUTSIDE + * inline-code spans (backtick content is inert in MDX and must survive + * untouched -- escaping braces there would corrupt things like an inline + * `{}` example). */ +function mdxEscape(text) { + const parts = String(text).split(/(`[^`]*`)/g); + return parts + .map((part, i) => + i % 2 === 1 + ? part + : part.replaceAll('{', '{').replaceAll('}', '}').replaceAll('<', '<').replaceAll('>', '>'), + ) + .join(''); +} + +/** + * Does this clause read as internal-implementation narration rather than + * user-facing meaning? Matches: + * - rustdoc intra-doc links: [`Name`] + * - backticked PascalCase identifiers / crate paths: `CellRange`, `crate::commands` + * - backticked snake_case function names: `resolve_range` + * - backticked source filenames: `envelope.ts` + * - backticked internal issue refs: `pro#120` + * - attribute macros: #[derive(TS)] + * - a fixed set of narration phrases this codebase's doc comments use to + * talk about their own history/structure rather than the tool's behavior. + */ +function isJargon(clause) { + const patterns = [ + /\[`[^`]+`\]/, // intra-doc link + /`[A-Z][A-Za-z0-9]*(::[A-Za-z0-9_]+)*`/, // `CellRange`, `EditSetCellSchema` + /`[a-z][a-z0-9]*(_[a-z0-9]+)+`/, // `resolve_range`, `is_empty` + /`[A-Za-z0-9_-]+\.(ts|rs)`/, // `envelope.ts` + /`[a-z]+#\d+`/, // `pro#120` + /#\[[a-zA-Z]/, // #[derive(TS)] + /`[a-z][a-zA-Z0-9]*:[a-zA-Z]+`'s (wire|own)/, // `file:import`'s wire format / own extra payload + ]; + if (patterns.some((re) => re.test(clause))) return true; + const phrases = [ + 'ported from', + 'ported field-by-field', + 'own doc', + 'module doc', + 'this module', + 'this file', + 'this crate', + 'this pr', + 'grep confirms', + 'batch 0', + 'ts-rs', + 'serde', + 'wire payload', + 'deny_unknown_fields', + 'internally-tagged', + "studio's own", + 'truecalc/studio', + 'truecalc-wasm-workbook', + 'server-layer concern', + 'reserved wire knob', + 'escape hatch', + 'own precedent', + 'own convention', + 'crate::', + 'leaf file', + 'not modeled here', + 'not enforced', + ]; + const lower = clause.toLowerCase(); + return phrases.some((p) => lower.includes(p)); +} + +// Protect abbreviations ("e.g.", "i.e.", "etc.") from being mistaken for a +// sentence end by the period+space sentence splitter below: their periods +// are swapped for a placeholder before splitting, then restored afterward. This +// MUST be a value that cannot occur anywhere in ordinary source text -- a plain +// space is NOT safe: unguardAbbreviations restores it with a blind +// find-and-replace over the whole string, which would turn every space in the +// text into a period, not just the ones this function introduced. U+0000 (NUL) +// qualifies: it can never appear in a JSON string (JSON.parse rejects a raw +// control character there) and JS source never emits it either. +const ABBREV_PLACEHOLDER = '\u0000'; + +function guardAbbreviations(text) { + return text.replace(/\b(e\.g|i\.e|etc)\./gi, (m) => m.split('.').join(ABBREV_PLACEHOLDER)); +} + +function unguardAbbreviations(text) { + return text.split(ABBREV_PLACEHOLDER).join('.'); +} + +/** + * Salvage a plain-English description out of a Rust-doc-comment-style + * `description` string. Rust doc comments put the summary in the first + * paragraph and implementation rationale after it, so only the first + * paragraph is considered. Parenthetical asides are dropped whole when + * they're jargon, or unwrapped in place when they're a legitimate aside + * (e.g. "(a single cell)"). What's left is split into sentences, then + * further into clauses on em dashes/semicolons, and only clauses with no + * jargon survive -- never a word-level strip that could leave a mangled + * fragment. Returns null if nothing salvageable survives. + */ +function cleanText(raw) { + if (!raw) return null; + const firstParagraph = String(raw).split(/\n\s*\n/, 1)[0].replace(/\n/g, ' ').replace(/\s+/g, ' ').trim(); + if (!firstParagraph) return null; + + // Unwrap or drop parenthetical asides. Requires whitespace (or + // start-of-string) right before the "(" so a paren glued directly onto a + // preceding token -- e.g. the `(_)` inside a code span like `` `Some(_)` `` + // -- is left alone rather than torn out of its backticks. + const withoutParens = firstParagraph.replace( + /(^|\s)\(([^()]*)\)/g, + (whole, boundary, inner) => (isJargon(inner) ? '' : `, ${inner}`), + ); + const guarded = guardAbbreviations(withoutParens); + + const sentences = guarded.split(/(?<=[.!?])\s+/).filter(Boolean); + const keptSentences = []; + for (const sentence of sentences) { + const clauses = sentence.split(/\s+—\s+|\s+--\s+|;\s+/).map((c) => c.trim().replace(/[.,;]+$/, '')); + const kept = clauses.filter((c) => c.length >= 3 && !isJargon(c)); + if (kept.length > 0) keptSentences.push(`${kept.join(', ')}.`); + } + if (keptSentences.length === 0) return null; + let result = unguardAbbreviations(keptSentences.join(' ')) + .replace(/\s+/g, ' ') + .replace(/,\s*\./g, '.') + .replace(/^,\s*/, '') + .trim(); + if (!result) return null; + result = result.charAt(0).toUpperCase() + result.slice(1); + return result; +} + +const VERB_PRESENT = { + set: 'Sets', + get: 'Gets', + insert: 'Inserts', + remove: 'Removes', + update: 'Updates', + delete: 'Deletes', + clear: 'Clears', + reorder: 'Reorders', + merge: 'Merges', + unmerge: 'Unmerges', + sort: 'Sorts', + fill: 'Fills', + find: 'Finds', + replace: 'Replaces', + import: 'Imports', + export: 'Exports', + undo: 'Undoes', + redo: 'Redoes', + restore: 'Restores', + add: 'Adds', + rename: 'Renames', + autofill: 'Autofills', + paste: 'Pastes', +}; + +const CATEGORY_LABEL = { + chart: 'a chart', + clipboard: 'the clipboard', + data: 'sheet data', + edit: 'cell contents', + file: 'a workbook file', + format: 'cell formatting', + history: "the workbook's edit history", + read: 'workbook data', + sheet: 'a sheet', + structure: 'the grid structure', + view: 'the page layout', +}; + +// A handful of wire names whose action word doesn't humanize cleanly as +// " the " (an adverb-shaped tail, or a noun-first name with no +// verb at all). Hand-adjusted grammar only -- still a generic paraphrase of +// the wire name itself, not sourced content. +const SUMMARY_OVERRIDES = { + 'edit:fillDown': 'Fills a range downward from its top row.', + 'edit:fillRight': 'Fills a range rightward from its left column.', + 'edit:findReplace': 'Finds and replaces text within a range.', + 'sheet:setActive': 'Sets the active sheet.', + 'format:textColor': 'Sets the text color of a range.', + 'format:fillColor': 'Sets the background fill color of a range.', + 'format:setBold': 'Turns bold formatting on or off for a range.', + 'format:setItalic': 'Turns italic formatting on or off for a range.', + 'format:setStrike': 'Turns strikethrough formatting on or off for a range.', + 'format:setUnderline': 'Turns underline formatting on or off for a range.', + 'format:setAlign': 'Sets the horizontal text alignment of a range.', + 'format:setValign': 'Sets the vertical text alignment of a range.', + 'format:setWrap': 'Sets the text-wrapping mode of a range.', + 'history:undo': "Undoes the workbook's most recent edit.", + 'history:redo': 'Re-applies the most recently undone edit.', + 'history:restore': 'Restores the workbook to a specific point in its edit history.', + 'clipboard:paste': 'Pastes previously copied or cut cells into a range.', + 'structure:mergeHorizontally': 'Merges each row of a range into one cell, horizontally.', + 'structure:mergeVertically': 'Merges each column of a range into one cell, vertically.', + 'structure:unmergeCells': 'Splits previously merged cells back apart.', + 'data:insertPivot': 'Inserts a pivot table summarizing a range.', +}; + +/** Derive a short, honest one-line summary purely from the wire name -- the + * tool-level `description` in this dataset is always boilerplate along the + * lines of "`edit:setCell`'s wire payload -- ported field-by-field from + * `EditSetCellSchema`", with no salvageable plain-English summary of what + * the tool actually does, so this is used unconditionally rather than + * attempting cleanText() on it first. */ +function synthesizeSummary(wireName) { + if (SUMMARY_OVERRIDES[wireName]) return SUMMARY_OVERRIDES[wireName]; + const [category, action] = wireName.split(':'); + const words = action + .replace(/([a-z0-9])([A-Z])/g, '$1 $2') + .toLowerCase() + .split(' '); + const verb = VERB_PRESENT[words[0]]; + if (verb) { + const rest = words.slice(1).join(' ').trim(); + const subject = rest ? `the ${rest}` : (CATEGORY_LABEL[category] ?? category); + return `${verb} ${subject}.`; + } + return `Performs the "${action}" ${CATEGORY_LABEL[category] ?? category} operation.`; +} + +// --------------------------------------------------------------------------- +// Structural JSON-Schema -> type-label rendering. +// --------------------------------------------------------------------------- + +function resolveRef(node, defs) { + if (node && typeof node === 'object' && typeof node.$ref === 'string') { + const name = node.$ref.split('/').pop(); + return defs[name] ?? {}; + } + return node; +} + +/** A short, plain-text type label for a schema node. Never contains a `|` + * (GFM table cells split on an unescaped pipe even inside inline code), and + * is safe to wrap wholesale in a single pair of backticks for the table + * cell -- MDX treats inline-code content as inert text, so stray `{`/`}` + * from an inlined object shape can't be misread as an expression. */ +function typeLabel(nodeIn, defs, depth = 0) { + const node = resolveRef(nodeIn, defs) ?? {}; + const maxDepth = 2; + + if (Array.isArray(node.anyOf)) { + const nonNull = node.anyOf.filter((s) => s.type !== 'null'); + const hasNull = node.anyOf.some((s) => s.type === 'null'); + if (nonNull.length === 1) { + const inner = typeLabel(nonNull[0], defs, depth); + return hasNull ? `${inner} or null` : inner; + } + return node.anyOf.map((s) => typeLabel(s, defs, depth)).join(' or '); + } + if (Array.isArray(node.oneOf)) { + if (node.oneOf.every((s) => s.const !== undefined)) { + return node.oneOf.map((s) => JSON.stringify(s.const)).join(', '); + } + if (node.oneOf.length === 1) return typeLabel(node.oneOf[0], defs, depth); + return node.oneOf.map((s) => typeLabel(s, defs, depth)).join(' or '); + } + if (Array.isArray(node.enum)) { + return node.enum.map((v) => JSON.stringify(v)).join(', '); + } + if (node.const !== undefined) { + return JSON.stringify(node.const); + } + if (Array.isArray(node.type)) { + const nonNull = node.type.filter((t) => t !== 'null'); + const hasNull = node.type.includes('null'); + const base = nonNull.join(' or ') || 'any'; + return hasNull ? `${base} or null` : base; + } + if (node.type === 'array') { + return `array of ${node.items ? typeLabel(node.items, defs, depth + 1) : 'any'}`; + } + if (node.type === 'object' || (!node.type && node.properties)) { + if (node.properties && depth < maxDepth) { + const required = new Set(node.required ?? []); + const fields = Object.entries(node.properties).map( + ([key, val]) => `${key}${required.has(key) ? '' : '?'}: ${typeLabel(val, defs, depth + 1)}`, + ); + // "; " between fields, not ", " -- a field's own type can itself be a + // comma-joined enum/union (e.g. `"solid", "dashed"`), and ", " at both + // levels would make the two indistinguishable. + const inline = `{ ${fields.join('; ')} }`; + if (fields.length > 0 && inline.length <= 160) return inline; + // Too long to inline in full. If this object is one branch of a + // discriminated union (a literal-string `const` field, conventionally + // named `kind`), keep at least that tag rather than falling all the + // way to a bare "object" -- when this shows up beside sibling + // branches in a oneOf/anyOf listing, the tag is exactly what lets a + // reader tell the branches apart; the full field list is still one + // click away in the raw JSON Schema below. + const discriminator = Object.entries(node.properties).find(([, val]) => { + const resolved = resolveRef(val, defs) ?? {}; + return typeof resolved.const === 'string'; + }); + if (discriminator) { + const [key, val] = discriminator; + const resolved = resolveRef(val, defs) ?? {}; + return `{ ${key}: ${JSON.stringify(resolved.const)}, … }`; + } + } + if (node.additionalProperties && typeof node.additionalProperties === 'object' && depth < maxDepth) { + return `{ [key: string]: ${typeLabel(node.additionalProperties, defs, depth + 1)} }`; + } + return 'object'; + } + if (['string', 'number', 'integer', 'boolean', 'null'].includes(node.type)) return node.type; + return 'any'; +} + +/** Build a Markdown parameters/fields table from a JSON Schema object's + * `properties`/`required`, cleaning each property's own description (or, + * lacking one, its resolved `$ref` def's description). */ +function paramsTable(objectSchema, defs) { + const properties = objectSchema.properties ?? {}; + const names = Object.keys(properties); + if (names.length === 0) return null; + const required = new Set(objectSchema.required ?? []); + const rows = names.map((name) => { + const prop = properties[name]; + const type = typeLabel(prop, defs); + const resolved = resolveRef(prop, defs) ?? {}; + let description = cleanText(prop.description) ?? cleanText(resolved.description); + if (prop.default !== undefined && !/default/i.test(description ?? '')) { + const defaultNote = `Defaults to \`${JSON.stringify(prop.default)}\`.`; + description = description ? `${description} ${defaultNote}` : defaultNote; + } + return `| \`${name}\` | \`${type}\` | ${required.has(name) ? 'yes' : 'no'} | ${mdxEscape(description ?? '—')} |`; + }); + return ['| Name | Type | Required | Description |', '| --- | --- | --- | --- |', ...rows].join('\n'); +} + +/** + * Deep-clone a JSON Schema node with every `description` string replaced by + * its cleanText()-salvaged form, or removed entirely when nothing + * salvageable survives. The raw JSON Schema block on each page (below) dumps + * `payload`/`output` verbatim, `$defs` included -- without this pass it + * would leak the exact same Rust-implementation narration (private repo + * names, crate paths, internal issue IDs, source file paths) that + * cleanText()/isJargon() exist to keep out of the prose tables above it. + */ +function sanitizeSchemaForDisplay(node) { + if (Array.isArray(node)) return node.map(sanitizeSchemaForDisplay); + if (node && typeof node === 'object') { + const out = {}; + for (const [key, value] of Object.entries(node)) { + if (key === 'description' && typeof value === 'string') { + const cleaned = cleanText(value); + if (cleaned) out[key] = cleaned; + continue; // nothing salvageable -- drop the key rather than leak it + } + out[key] = sanitizeSchemaForDisplay(value); + } + return out; + } + return node; +} + +// --------------------------------------------------------------------------- +// Page generation. +// --------------------------------------------------------------------------- + +function slugify(wireName) { + return wireName + .replace(/([a-z0-9])([A-Z])/g, '$1-$2') + .replace(/:/g, '-') + .toLowerCase(); +} + +function toolPage(wireName, entry) { + const { payload, output } = entry; + const description = synthesizeSummary(wireName); + + const lines = []; + lines.push('---'); + lines.push(`title: ${JSON.stringify(wireName)}`); + lines.push(`description: ${JSON.stringify(description)}`); + lines.push('---'); + lines.push(''); + lines.push('{/* GENERATED by scripts/gen-mcp-docs.mjs from scripts/mcp-source/tool-schemas.json — do not edit. */}'); + lines.push(''); + + lines.push('## Parameters'); + lines.push(''); + const defs = payload.$defs ?? {}; + const table = paramsTable(payload, defs); + lines.push(table ?? 'This tool takes no parameters.'); + lines.push(''); + + lines.push('## Returns'); + lines.push(''); + const outputIsNull = output?.type === 'null'; + if (outputIsNull) { + lines.push('Nothing beyond the standard MCP success envelope.'); + } else { + const outputDefs = output.$defs ?? {}; + const outputTable = paramsTable(output, outputDefs); + lines.push(outputTable ?? 'An object whose exact shape is shown in the response schema below.'); + } + lines.push(''); + + lines.push('## Schema'); + lines.push(''); + lines.push('Request payload, as JSON Schema:'); + lines.push(''); + lines.push('```json'); + lines.push(JSON.stringify(sanitizeSchemaForDisplay(payload), null, 2)); + lines.push('```'); + lines.push(''); + if (!outputIsNull) { + lines.push('Response payload, as JSON Schema:'); + lines.push(''); + lines.push('```json'); + lines.push(JSON.stringify(sanitizeSchemaForDisplay(output), null, 2)); + lines.push('```'); + lines.push(''); + } + + return lines.join('\n'); +} + +function main() { + const raw = readFileSync(sourcePath, 'utf8'); + const tools = JSON.parse(raw); + const wireNames = Object.keys(tools).sort(); + if (wireNames.length === 0) throw new Error(`No tools found in ${sourcePath}`); + + // index.mdx is hand-written (not generated) -- clear only the generated + // tool pages and meta.json, never the whole directory. + mkdirSync(outDir, { recursive: true }); + if (existsSync(outDir)) { + for (const entry of readdirSync(outDir)) { + if (entry === 'index.mdx') continue; + if (entry.endsWith('.mdx') || entry === 'meta.json') rmSync(join(outDir, entry)); + } + } + + const slugs = []; + for (const wireName of wireNames) { + const slug = slugify(wireName); + if (slugs.includes(slug)) throw new Error(`Duplicate MCP tool slug: ${slug}`); + slugs.push(slug); + writeFileSync(join(outDir, `${slug}.mdx`), toolPage(wireName, tools[wireName]) + '\n'); + } + + writeFileSync( + join(outDir, 'meta.json'), + JSON.stringify({ title: 'MCP', pages: ['index', ...slugs] }, null, 2) + '\n', + ); + + console.log(`gen-mcp-docs: wrote ${wireNames.length} tool page(s) + meta.json to ${outDir}`); +} + +main(); diff --git a/scripts/mcp-source/tool-schemas.json b/scripts/mcp-source/tool-schemas.json new file mode 100644 index 0000000..7b8fc70 --- /dev/null +++ b/scripts/mcp-source/tool-schemas.json @@ -0,0 +1,5572 @@ +{ + "chart:insert": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet `range` is relative to.", + "type": "string" + }, + "range": { + "description": "The rectangle to bind the chart to, as A1 corners.", + "$ref": "#/$defs/CellRange" + }, + "chartType": { + "description": "The chart form to draw, a closed wire vocabulary.", + "type": "string" + }, + "options": { + "description": "Renderer-specific knobs, opaque here on purpose, defaults to `{}`.", + "type": "object", + "additionalProperties": true, + "default": {} + } + }, + "required": [ + "sheet", + "range", + "chartType" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "chartId": { + "description": "The new chart's id.", + "type": "string" + }, + "range": { + "description": "Canonicalized top-left/bottom-right corners.", + "$ref": "#/$defs/CellRange" + }, + "chartType": { + "type": "string" + } + }, + "required": [ + "chartId", + "range", + "chartType" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + } + }, + "chart:update": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "chartId": { + "description": "The chart to patch.", + "type": "string" + }, + "chartType": { + "description": "The new chart form, or omitted to leave it unchanged.", + "type": [ + "string", + "null" + ], + "default": null + }, + "options": { + "description": "Replaces the chart's options wholesale, or omitted to leave them unchanged.", + "type": [ + "object", + "null" + ], + "additionalProperties": true, + "default": null + } + }, + "required": [ + "chartId" + ] + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "chartId": { + "type": "string" + }, + "chartType": { + "description": "The EFFECTIVE, post-patch chart form, the patch's own value if it supplied one, else the chart's unchanged existing type.", + "type": "string" + } + }, + "required": [ + "chartId", + "chartType" + ] + } + }, + "chart:remove": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "chartId": { + "description": "The chart to remove.", + "type": "string" + } + }, + "required": [ + "chartId" + ] + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "chartId": { + "type": "string" + }, + "removed": { + "type": "boolean" + } + }, + "required": [ + "chartId", + "removed" + ] + } + }, + "clipboard:paste": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "source": { + "description": "The cell the clipboard content was copied/cut FROM, e.g. `\"A1\"`.", + "type": "string" + }, + "raw": { + "description": "The clipboard contents AT COPY/CUT TIME, a literal, a formula, leading `=`, or `\"\"`.", + "type": "string" + }, + "target": { + "description": "The cell being pasted INTO, e.g. `\"B2\"`.", + "type": "string" + }, + "cut": { + "description": "`false` = copy, the default, `true` = cut, move.", + "type": "boolean", + "default": false + } + }, + "required": [ + "sheet", + "source", + "raw", + "target" + ] + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "edit:setCell": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "a1": { + "description": "Target cell, e.g. `\"A1\"`.", + "type": "string" + }, + "value": { + "description": "Raw input: a literal, a formula, leading `=`, or `\"\"` to clear.", + "type": "string" + }, + "inputMode": { + "anyOf": [ + { + "$ref": "#/$defs/InputMode" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "sheet", + "a1", + "value" + ], + "$defs": { + "InputMode": { + "type": "string", + "enum": [ + "raw" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "edit:clear": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "$ref": "#/$defs/CellRange" + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "edit:setValues": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "A rectangular block of raw strings, row-major, anchored at `anchor`.", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "anchor": { + "type": "string" + }, + "values": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "required": [ + "sheet", + "anchor", + "values" + ] + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "edit:fillDown": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "$ref": "#/$defs/CellRange" + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "edit:fillRight": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "A range whose leading column is the fill source.", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "$ref": "#/$defs/CellRange" + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "edit:findReplace": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "description": "The scope to search, the whole sheet's occupied footprint when absent.", + "anyOf": [ + { + "$ref": "#/$defs/CellRange" + }, + { + "type": "null" + } + ] + }, + "query": { + "type": "string" + }, + "replacement": { + "type": "string" + }, + "matchCase": { + "type": "boolean", + "default": false + }, + "useRegex": { + "type": "boolean", + "default": false + }, + "matchEntireCell": { + "type": "boolean", + "default": false + }, + "withinFormulas": { + "type": "boolean", + "default": false + } + }, + "required": [ + "sheet", + "query", + "replacement" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "description": "This command's own extra result fields.", + "type": "object", + "properties": { + "queryCompiled": { + "description": "Whether `query` compiled as a regex, always `true` when `useRegex` is `false`, since the literal form is always `regex::escape`d before compiling, escaping cannot fail.", + "type": "boolean" + }, + "matched": { + "description": "How many scope cells' search text matched, counted whether or not the match was eligible to be written back.", + "type": "integer", + "format": "uint", + "minimum": 0 + } + }, + "required": [ + "queryCompiled", + "matched" + ] + } + }, + "edit:autofill": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "source": { + "$ref": "#/$defs/CellRange" + }, + "to": { + "type": "string" + } + }, + "required": [ + "sheet", + "source", + "to" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "format:fillColor": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "The fill colour to set, or `null` to clear it.", + "anyOf": [ + { + "$ref": "#/$defs/Color" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "Color": { + "description": "A CSS colour string, `#ff0000`, `#fff2cc`, `rgb(…)`, a named colour.", + "type": "string" + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "format:setBold": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "Whether the range should be bold.", + "type": "boolean" + } + }, + "required": [ + "sheet", + "range", + "value" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "format:setItalic": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "Whether the range should be italic.", + "type": "boolean" + } + }, + "required": [ + "sheet", + "range", + "value" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "format:setStrike": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "Whether the range should be strike.", + "type": "boolean" + } + }, + "required": [ + "sheet", + "range", + "value" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "format:setUnderline": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "Whether the range should be underline.", + "type": "boolean" + } + }, + "required": [ + "sheet", + "range", + "value" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "format:textColor": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "The text colour to set, or `null` to clear it.", + "anyOf": [ + { + "$ref": "#/$defs/Color" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "Color": { + "description": "A CSS colour string, `#ff0000`, `#fff2cc`, `rgb(…)`, a named colour.", + "type": "string" + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "format:setFontFamily": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "The font family to set. Non-nullable.", + "$ref": "#/$defs/FontFamily" + } + }, + "required": [ + "sheet", + "range", + "value" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "FontFamily": { + "description": "A font family name.", + "type": "string" + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "format:setFontSize": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "The font size to set. Non-nullable.", + "$ref": "#/$defs/FontSize" + } + }, + "required": [ + "sheet", + "range", + "value" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "FontSize": { + "description": "A font size in points.", + "type": "number", + "format": "double" + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "format:setBorders": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "mode": { + "description": "Which edges to target.", + "$ref": "#/$defs/BorderMode" + }, + "edge": { + "description": "How the targeted edges should look. Required even for `mode: clear`, parsed but unused there.", + "$ref": "#/$defs/BorderEdge" + } + }, + "required": [ + "sheet", + "range", + "mode", + "edge" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "BorderMode": { + "description": "The Sheets border-position options.", + "oneOf": [ + { + "description": "Every edge of every cell in the range.", + "type": "string", + "const": "all" + }, + { + "description": "The internal grid lines only, neither the range's outer perimeter.", + "type": "string", + "const": "inner" + }, + { + "description": "The internal horizontal grid lines only, between rows.", + "type": "string", + "const": "horizontal" + }, + { + "description": "The internal vertical grid lines only, between columns.", + "type": "string", + "const": "vertical" + }, + { + "description": "The range's outer perimeter only.", + "type": "string", + "const": "outer" + }, + { + "description": "The range's left edge only.", + "type": "string", + "const": "left" + }, + { + "description": "The range's top edge only.", + "type": "string", + "const": "top" + }, + { + "description": "The range's right edge only.", + "type": "string", + "const": "right" + }, + { + "description": "The range's bottom edge only.", + "type": "string", + "const": "bottom" + }, + { + "description": "Removes borders instead of drawing them, `edge` is parsed but never read for this mode.", + "type": "string", + "const": "clear" + } + ] + }, + "BorderEdge": { + "description": "One drawn edge: how it looks.", + "type": "object", + "properties": { + "style": { + "description": "The line pattern.", + "$ref": "#/$defs/BorderStyle" + }, + "weight": { + "description": "The line weight.", + "$ref": "#/$defs/BorderWeight" + }, + "color": { + "description": "The line colour.", + "$ref": "#/$defs/Color" + } + }, + "additionalProperties": false, + "required": [ + "style", + "weight", + "color" + ] + }, + "BorderStyle": { + "description": "Line pattern for an edge, Sheets' solid / dashed / dotted plus the double rule.", + "oneOf": [ + { + "description": "An unbroken line.", + "type": "string", + "const": "solid" + }, + { + "description": "A dashed line.", + "type": "string", + "const": "dashed" + }, + { + "description": "A dotted line.", + "type": "string", + "const": "dotted" + }, + { + "description": "Two parallel lines.", + "type": "string", + "const": "double" + } + ] + }, + "BorderWeight": { + "description": "Line weight, Sheets' thin / medium / thick.", + "oneOf": [ + { + "description": "The default pen.", + "type": "string", + "const": "thin" + }, + { + "description": "One step heavier.", + "type": "string", + "const": "medium" + }, + { + "description": "The heaviest pen.", + "type": "string", + "const": "thick" + } + ] + }, + "Color": { + "description": "A CSS colour string, `#ff0000`, `#fff2cc`, `rgb(…)`, a named colour.", + "type": "string" + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "format:setAlign": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "The horizontal alignment to set, or `null` for automatic, type-based: numbers and dates right, everything else left.", + "anyOf": [ + { + "$ref": "#/$defs/HAlign" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "HAlign": { + "description": "Horizontal text alignment.", + "oneOf": [ + { + "description": "Hug the left edge of the cell box.", + "type": "string", + "const": "left" + }, + { + "description": "Centre within the cell box.", + "type": "string", + "const": "center" + }, + { + "description": "Hug the right edge of the cell box.", + "type": "string", + "const": "right" + } + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "format:setValign": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "The vertical alignment to set, or `null` for Sheets' default, bottom.", + "anyOf": [ + { + "$ref": "#/$defs/VAlign" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "VAlign": { + "description": "Vertical text alignment within the cell box.", + "oneOf": [ + { + "description": "Top of the cell box.", + "type": "string", + "const": "top" + }, + { + "description": "Vertically centred.", + "type": "string", + "const": "middle" + }, + { + "description": "Bottom of the cell box, Sheets' default.", + "type": "string", + "const": "bottom" + } + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "format:setRotation": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "The rotation in degrees to set, or `null`, equivalently `0` to clear it.", + "anyOf": [ + { + "$ref": "#/$defs/Rotation" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "Rotation": { + "description": "Text rotation in degrees: positive tilts counter-clockwise, Sheets' \"up\", negative clockwise, \"down\".", + "type": "number", + "format": "double" + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "format:setWrap": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "Whether the range should wrap text. `false` clears the attribute.", + "type": "boolean" + } + }, + "required": [ + "sheet", + "range", + "value" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "format:clear": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "No `value` field.", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "format:setNumberFormat": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "anyOf": [ + { + "$ref": "#/$defs/NumberFormat" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "NumberFormat": { + "description": "A number-display category, studio#10.", + "oneOf": [ + { + "description": "Grouped fixed-point: `1,234.57`.", + "type": "string", + "const": "number" + }, + { + "description": "The value times 100, with a `%` suffix.", + "type": "string", + "const": "percent" + }, + { + "description": "Grouped fixed-point with a currency symbol.", + "type": "string", + "const": "currency" + }, + { + "description": "The value read as a date serial. **Implies date typing**.", + "type": "string", + "const": "date" + }, + { + "description": "The value read as a date-time serial.", + "type": "string", + "const": "datetime" + } + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "format:setDecimals": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The target range, e.g. `{\"from\": \"A1\", \"to\": \"B3\"}`. May legitimately arrive \"backwards\", `from` below/right of `to`, normalized before use.", + "$ref": "#/$defs/CellRange" + }, + "value": { + "description": "The decimal count to set. `0` is a real value here.", + "$ref": "#/$defs/Decimals" + }, + "numberFormat": { + "description": "An optional companion category to set alongside `value` in the same call. Omitted, not merely `null` means \"leave the category alone\".", + "anyOf": [ + { + "$ref": "#/$defs/NumberFormat" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "required": [ + "sheet", + "range", + "value" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "Decimals": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "NumberFormat": { + "description": "A number-display category, studio#10.", + "oneOf": [ + { + "description": "Grouped fixed-point: `1,234.57`.", + "type": "string", + "const": "number" + }, + { + "description": "The value times 100, with a `%` suffix.", + "type": "string", + "const": "percent" + }, + { + "description": "Grouped fixed-point with a currency symbol.", + "type": "string", + "const": "currency" + }, + { + "description": "The value read as a date serial. **Implies date typing**.", + "type": "string", + "const": "date" + }, + { + "description": "The value read as a date-time serial.", + "type": "string", + "const": "datetime" + } + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "format:setConditionalFormat": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "$ref": "#/$defs/CellRange" + }, + "rule": { + "$ref": "#/$defs/RuleWire" + } + }, + "required": [ + "sheet", + "range", + "rule" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "RuleWire": { + "description": "One conditional-format rule's wire shape.", + "oneOf": [ + { + "type": "object", + "properties": { + "operator": { + "$ref": "#/$defs/OperatorWire" + }, + "value": { + "type": "number", + "format": "double" + }, + "value2": { + "type": [ + "number", + "null" + ], + "format": "double" + }, + "style": { + "$ref": "#/$defs/StyleWire" + }, + "kind": { + "type": "string", + "const": "singleCondition" + } + }, + "required": [ + "kind", + "operator", + "value", + "style" + ] + }, + { + "type": "object", + "properties": { + "minColor": { + "$ref": "#/$defs/HexColor" + }, + "maxColor": { + "$ref": "#/$defs/HexColor" + }, + "kind": { + "type": "string", + "const": "colorScale" + } + }, + "required": [ + "kind", + "minColor", + "maxColor" + ] + }, + { + "type": "object", + "properties": { + "formula": { + "type": "string" + }, + "style": { + "$ref": "#/$defs/StyleWire" + }, + "kind": { + "type": "string", + "const": "customFormula" + } + }, + "required": [ + "kind", + "formula", + "style" + ] + } + ] + }, + "OperatorWire": { + "description": "The wire shape of a single-condition rule's numeric comparison operator.", + "type": "string", + "enum": [ + "greaterThan", + "greaterThanOrEqual", + "lessThan", + "lessThanOrEqual", + "equal", + "notEqual", + "between", + "notBetween" + ] + }, + "StyleWire": { + "description": "A conditional-format rule's style, as the wire restricts it.", + "type": "object", + "properties": { + "bold": { + "type": [ + "boolean", + "null" + ] + }, + "italic": { + "type": [ + "boolean", + "null" + ] + }, + "underline": { + "type": [ + "boolean", + "null" + ] + }, + "strike": { + "type": [ + "boolean", + "null" + ] + }, + "color": { + "anyOf": [ + { + "$ref": "#/$defs/HexColor" + }, + { + "type": "null" + } + ] + }, + "fill": { + "anyOf": [ + { + "$ref": "#/$defs/HexColor" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "HexColor": { + "description": "A strictly-validated `#rgb`/`#rrggbb`/`#rrggbbaa` hex colour.", + "type": "string" + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "range": { + "$ref": "#/$defs/CellRange" + }, + "id": { + "description": "The new rule's id.", + "type": "string" + } + }, + "required": [ + "range", + "id" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + } + }, + "format:setBandedRange": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "$ref": "#/$defs/CellRange" + }, + "style": { + "$ref": "#/$defs/StyleWire" + } + }, + "required": [ + "sheet", + "range", + "style" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "StyleWire": { + "description": "The wire shape of a banded range's color assignment.", + "type": "object", + "properties": { + "headerColor": { + "anyOf": [ + { + "$ref": "#/$defs/HexColor" + }, + { + "type": "null" + } + ], + "default": null + }, + "firstBandColor": { + "$ref": "#/$defs/HexColor" + }, + "secondBandColor": { + "$ref": "#/$defs/HexColor" + }, + "footerColor": { + "anyOf": [ + { + "$ref": "#/$defs/HexColor" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "required": [ + "firstBandColor", + "secondBandColor" + ] + }, + "HexColor": { + "description": "A strictly-validated `#rgb`/`#rrggbb`/`#rrggbbaa` hex colour.", + "type": "string" + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "range": { + "$ref": "#/$defs/CellRange" + }, + "id": { + "description": "The new banded range's id.", + "type": "string" + } + }, + "required": [ + "range", + "id" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + } + }, + "structure:insertRow": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "`beforeRow`/`count`, matching studio's `insert-row` schema.", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "beforeRow": { + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "count": { + "type": "integer", + "format": "uint32", + "minimum": 0, + "default": 1 + } + }, + "required": [ + "sheet", + "beforeRow" + ] + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "structure:insertColumn": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "beforeColumn": { + "type": "string" + }, + "count": { + "type": "integer", + "format": "uint32", + "minimum": 0, + "default": 1 + } + }, + "required": [ + "sheet", + "beforeColumn" + ] + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "structure:deleteRow": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "row": { + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "count": { + "type": "integer", + "format": "uint32", + "minimum": 0, + "default": 1 + } + }, + "required": [ + "sheet", + "row" + ] + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "structure:deleteColumn": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "column": { + "type": "string" + }, + "count": { + "type": "integer", + "format": "uint32", + "minimum": 0, + "default": 1 + } + }, + "required": [ + "sheet", + "column" + ] + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "structure:reorderRows": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "fromRow": { + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "count": { + "type": "integer", + "format": "uint32", + "minimum": 0, + "default": 1 + }, + "toRow": { + "type": "integer", + "format": "uint32", + "minimum": 0 + } + }, + "required": [ + "sheet", + "fromRow", + "toRow" + ] + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "structure:reorderColumns": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "fromColumn": { + "type": "string" + }, + "count": { + "type": "integer", + "format": "uint32", + "minimum": 0, + "default": 1 + }, + "toColumn": { + "type": "string" + } + }, + "required": [ + "sheet", + "fromColumn", + "toColumn" + ] + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "structure:mergeCells": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "$ref": "#/$defs/CellRange" + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "structure:mergeVertically": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "$ref": "#/$defs/CellRange" + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "structure:mergeHorizontally": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "$ref": "#/$defs/CellRange" + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "structure:unmergeCells": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "The single cell, anchor or interior whose covering merge should be dissolved.", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "a1": { + "type": "string" + } + }, + "required": [ + "sheet", + "a1" + ] + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "data:setValidation": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "$ref": "#/$defs/CellRange" + }, + "rule": { + "description": "`Some(_)` sets a rule. Required on the wire, as literal `null` to clear.", + "anyOf": [ + { + "$ref": "#/$defs/WireRule" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "WireRule": { + "description": "The one rule kind on the wire today. because the tag is checked at deserialize time.", + "oneOf": [ + { + "type": "object", + "properties": { + "values": { + "type": "array", + "items": { + "type": "string" + } + }, + "kind": { + "type": "string", + "const": "list" + } + }, + "required": [ + "kind", + "values" + ] + } + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "description": "**Echoes `payload.range`/`payload.rule` verbatim**.", + "type": "object", + "properties": { + "range": { + "$ref": "#/$defs/CellRange" + }, + "rule": { + "anyOf": [ + { + "$ref": "#/$defs/WireRule" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "WireRule": { + "description": "The one rule kind on the wire today. because the tag is checked at deserialize time.", + "oneOf": [ + { + "type": "object", + "properties": { + "values": { + "type": "array", + "items": { + "type": "string" + } + }, + "kind": { + "type": "string", + "const": "list" + } + }, + "required": [ + "kind", + "values" + ] + } + ] + } + } + } + }, + "data:sortRange": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "description": "The rectangle to permute. Nothing outside it is read or written.", + "$ref": "#/$defs/CellRange" + }, + "sortColumn": { + "description": "The column whose values order the rows, as an A1 column letter, `\"A\"`, `\"AB\"`. Must lie inside `range`.", + "type": "string" + }, + "direction": { + "$ref": "#/$defs/SortDirection" + } + }, + "required": [ + "sheet", + "range", + "sortColumn", + "direction" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "SortDirection": { + "description": "Sort order for `sortColumn`'s values.", + "type": "string", + "enum": [ + "asc", + "desc" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "range": { + "description": "The normalized rectangle actually sorted.", + "$ref": "#/$defs/CellRange" + }, + "sortColumn": { + "description": "The sort column, canonical uppercase.", + "type": "string" + }, + "direction": { + "$ref": "#/$defs/SortDirection" + } + }, + "required": [ + "range", + "sortColumn", + "direction" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "SortDirection": { + "description": "Sort order for `sortColumn`'s values.", + "type": "string", + "enum": [ + "asc", + "desc" + ] + } + } + } + }, + "data:setNamedRange": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "`commandId` is not modeled.", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet `range` is relative to.", + "type": "string" + }, + "name": { + "description": "The named range's identifier, e.g. `\"MyRange\"`.", + "type": "string" + }, + "range": { + "description": "The rectangle to bind `name` to.", + "$ref": "#/$defs/CellRange" + } + }, + "required": [ + "sheet", + "name", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "name": { + "description": "Echoed exactly as the caller sent it, never trimmed or re-cased.", + "type": "string" + }, + "range": { + "description": "Not a raw echo of whatever case or corner order `range.from`/`range.to` arrived in.", + "$ref": "#/$defs/CellRange" + }, + "created": { + "description": "`true` when this call DEFINED a brand-new name, `false` when it RETARGETED an existing one.", + "type": "boolean" + } + }, + "required": [ + "name", + "range", + "created" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + } + }, + "data:deleteNamedRange": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "name": { + "description": "The named range to remove, e.g. `\"MyRange\"`.", + "type": "string" + } + }, + "required": [ + "sheet", + "name" + ] + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "removed": { + "description": "Whether a named range by this name actually existed and was removed.", + "type": "boolean" + } + }, + "required": [ + "name", + "removed" + ] + } + }, + "data:setFilter": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "description": "The filter's own range, its FIRST row is the un-hideable header row. Must span more than one row, a single-row range has no body rows to filter.", + "$ref": "#/$defs/CellRange" + }, + "criteria": { + "description": "Per-column checked-value lists to apply right after creating the filter. A column omitted here starts unfiltered.", + "type": "array", + "items": { + "$ref": "#/$defs/Criterion" + }, + "default": [] + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "Criterion": { + "description": "One column's checked-value list.", + "type": "object", + "properties": { + "column": { + "description": "An A1 column letter INSIDE `range`, e.g. `\"B\"`, case-insensitive.", + "type": "string" + }, + "values": { + "description": "The raw values to keep VISIBLE, checked in this column, every value not listed here hides its row.", + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "column", + "values" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "range": { + "$ref": "#/$defs/CellRange" + }, + "criteria": { + "description": "Echoed back exactly as applied.", + "type": "array", + "items": { + "$ref": "#/$defs/Criterion" + } + } + }, + "required": [ + "range", + "criteria" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "Criterion": { + "description": "One column's checked-value list.", + "type": "object", + "properties": { + "column": { + "description": "An A1 column letter INSIDE `range`, e.g. `\"B\"`, case-insensitive.", + "type": "string" + }, + "values": { + "description": "The raw values to keep VISIBLE, checked in this column, every value not listed here hides its row.", + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "column", + "values" + ] + } + } + } + }, + "data:clearFilter": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + } + }, + "required": [ + "sheet" + ] + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "removed": { + "description": "A no-op, `false` if `sheet` had no filter.", + "type": "boolean" + } + }, + "required": [ + "removed" + ] + } + }, + "data:insertPivot": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "range": { + "$ref": "#/$defs/CellRange" + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "range": { + "$ref": "#/$defs/CellRange" + }, + "destSheet": { + "description": "The newly-created destination sheet's name.", + "type": "string" + } + }, + "required": [ + "range", + "destSheet" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + } + }, + "file:export": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "`commandId` is dropped, the same Batch-0 convention `edit::set_cell::Payload` already uses.", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet named on the wire, validated to exist for every `format`.", + "type": "string" + }, + "format": { + "$ref": "#/$defs/Format" + } + }, + "required": [ + "sheet", + "format" + ], + "$defs": { + "Format": { + "description": "Every variant PARSES.", + "type": "string", + "enum": [ + "json", + "csv", + "xlsx" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "description": "`file:export`'s typed result.", + "type": "object", + "properties": { + "format": { + "$ref": "#/$defs/Format" + }, + "content": { + "type": "string" + } + }, + "required": [ + "format", + "content" + ], + "$defs": { + "Format": { + "description": "Every variant PARSES.", + "type": "string", + "enum": [ + "json", + "csv", + "xlsx" + ] + } + } + } + }, + "file:import": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "format": { + "$ref": "#/$defs/Format" + }, + "encoding": { + "$ref": "#/$defs/Encoding", + "default": "text" + }, + "data": { + "type": "string" + }, + "sheetName": { + "description": "Base name for the created sheet. Omitted defaults to `\"Imported\"`. NOT validated the way `sheet:add`'s `name` field is.", + "type": [ + "string", + "null" + ], + "default": null + } + }, + "required": [ + "format", + "data" + ], + "$defs": { + "Format": { + "type": "string", + "enum": [ + "json", + "csv", + "tsv", + "xlsx" + ] + }, + "Encoding": { + "description": "How `data` is encoded on the wire. `base64` is required for `xlsx`, binary, and allowed for `csv`/`tsv`/`json` too if the caller's bytes happen to be base64-wrapped UTF-8.", + "type": "string", + "enum": [ + "text", + "base64" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "description": "This command only ever creates one.", + "type": "object", + "properties": { + "sheet": { + "description": "The created sheet's final, deduped, sanitized name.", + "type": "string" + }, + "cellsWritten": { + "description": "Computed by reading the engine back after the write, never a count of attempted writes, the same discipline `sheet:add`/`sheet:rename`/ `edit:setCell` all already apply, never assume a write landed.", + "type": "integer", + "format": "uint", + "minimum": 0 + } + }, + "required": [ + "sheet", + "cellsWritten" + ] + } + }, + "read:getRange": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The inclusive rectangle to read.", + "$ref": "#/$defs/CellRange" + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "range": { + "description": "The rectangle this call answered for, completely.", + "$ref": "#/$defs/CellRange" + }, + "cells": { + "description": "One entry per address in `range`, keyed by its plain A1 form.", + "type": "object", + "additionalProperties": { + "$ref": "#/$defs/Cell" + } + } + }, + "required": [ + "range", + "cells" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "Cell": { + "description": "One cell's read-back.", + "type": "object", + "properties": { + "value": { + "description": "`unknown` already covers the `null` case too, so no separate `| null` is needed." + }, + "display": { + "description": "**Known Batch-0 approximation**. Not a real number-format-aware render, a plain literal rendering of `value`.", + "type": "string" + }, + "formula": { + "type": [ + "string", + "null" + ] + }, + "rawInput": { + "description": "The formula string when present, otherwise the same approximation as `display`.", + "type": "string" + }, + "format": { + "description": "This cell's effective format.", + "$ref": "#/$defs/CellFormat" + } + }, + "required": [ + "display", + "rawInput", + "format" + ] + }, + "CellFormat": { + "description": "A cell's grid-owned presentation.", + "type": "object", + "properties": { + "bold": { + "description": "Bold text. Absent or `false` = not bold.", + "type": [ + "boolean", + "null" + ] + }, + "italic": { + "description": "Italic text.", + "type": [ + "boolean", + "null" + ] + }, + "strike": { + "description": "Struck-through text.", + "type": [ + "boolean", + "null" + ] + }, + "underline": { + "description": "Underlined text.", + "type": [ + "boolean", + "null" + ] + }, + "fontFamily": { + "description": "Font family. Absent = the grid's default face.", + "anyOf": [ + { + "$ref": "#/$defs/FontFamily" + }, + { + "type": "null" + } + ] + }, + "fontSize": { + "description": "Font size in points. Absent = the grid's default size.", + "anyOf": [ + { + "$ref": "#/$defs/FontSize" + }, + { + "type": "null" + } + ] + }, + "borders": { + "description": "Per-edge cell borders. Absent = no borders, never present-and-empty.", + "anyOf": [ + { + "$ref": "#/$defs/CellBorders" + }, + { + "type": "null" + } + ] + }, + "color": { + "description": "Text colour. Absent = the grid's default.", + "anyOf": [ + { + "$ref": "#/$defs/Color" + }, + { + "type": "null" + } + ] + }, + "fill": { + "description": "Background fill. Absent = none, the grid's own background shows.", + "anyOf": [ + { + "$ref": "#/$defs/Color" + }, + { + "type": "null" + } + ] + }, + "numberFormat": { + "description": "Number-display category. Absent = automatic, the engine's raw display.", + "anyOf": [ + { + "$ref": "#/$defs/NumberFormat" + }, + { + "type": "null" + } + ] + }, + "decimals": { + "anyOf": [ + { + "$ref": "#/$defs/Decimals" + }, + { + "type": "null" + } + ] + }, + "align": { + "description": "Horizontal alignment. Absent = automatic, numbers right, else left.", + "anyOf": [ + { + "$ref": "#/$defs/HAlign" + }, + { + "type": "null" + } + ] + }, + "valign": { + "description": "Vertical alignment. Absent = bottom, Sheets' default.", + "anyOf": [ + { + "$ref": "#/$defs/VAlign" + }, + { + "type": "null" + } + ] + }, + "wrap": { + "description": "Wrap text into lines within the column width, growing the row to fit.", + "type": [ + "boolean", + "null" + ] + }, + "rotation": { + "description": "Text rotation in degrees. Absent, or `0` = none.", + "anyOf": [ + { + "$ref": "#/$defs/Rotation" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "FontFamily": { + "description": "A font family name.", + "type": "string" + }, + "FontSize": { + "description": "A font size in points.", + "type": "number", + "format": "double" + }, + "CellBorders": { + "description": "A cell's borders, any **non-empty** subset of the four edges.", + "type": "object", + "properties": { + "bottom": { + "description": "The bottom edge, if drawn.", + "anyOf": [ + { + "$ref": "#/$defs/BorderEdge" + }, + { + "type": "null" + } + ] + }, + "left": { + "description": "The left edge, if drawn.", + "anyOf": [ + { + "$ref": "#/$defs/BorderEdge" + }, + { + "type": "null" + } + ] + }, + "right": { + "description": "The right edge, if drawn.", + "anyOf": [ + { + "$ref": "#/$defs/BorderEdge" + }, + { + "type": "null" + } + ] + }, + "top": { + "description": "The top edge, if drawn.", + "anyOf": [ + { + "$ref": "#/$defs/BorderEdge" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "BorderEdge": { + "description": "One drawn edge: how it looks.", + "type": "object", + "properties": { + "style": { + "description": "The line pattern.", + "$ref": "#/$defs/BorderStyle" + }, + "weight": { + "description": "The line weight.", + "$ref": "#/$defs/BorderWeight" + }, + "color": { + "description": "The line colour.", + "$ref": "#/$defs/Color" + } + }, + "additionalProperties": false, + "required": [ + "style", + "weight", + "color" + ] + }, + "BorderStyle": { + "description": "Line pattern for an edge, Sheets' solid / dashed / dotted plus the double rule.", + "oneOf": [ + { + "description": "An unbroken line.", + "type": "string", + "const": "solid" + }, + { + "description": "A dashed line.", + "type": "string", + "const": "dashed" + }, + { + "description": "A dotted line.", + "type": "string", + "const": "dotted" + }, + { + "description": "Two parallel lines.", + "type": "string", + "const": "double" + } + ] + }, + "BorderWeight": { + "description": "Line weight, Sheets' thin / medium / thick.", + "oneOf": [ + { + "description": "The default pen.", + "type": "string", + "const": "thin" + }, + { + "description": "One step heavier.", + "type": "string", + "const": "medium" + }, + { + "description": "The heaviest pen.", + "type": "string", + "const": "thick" + } + ] + }, + "Color": { + "description": "A CSS colour string, `#ff0000`, `#fff2cc`, `rgb(…)`, a named colour.", + "type": "string" + }, + "NumberFormat": { + "description": "A number-display category, studio#10.", + "oneOf": [ + { + "description": "Grouped fixed-point: `1,234.57`.", + "type": "string", + "const": "number" + }, + { + "description": "The value times 100, with a `%` suffix.", + "type": "string", + "const": "percent" + }, + { + "description": "Grouped fixed-point with a currency symbol.", + "type": "string", + "const": "currency" + }, + { + "description": "The value read as a date serial. **Implies date typing**.", + "type": "string", + "const": "date" + }, + { + "description": "The value read as a date-time serial.", + "type": "string", + "const": "datetime" + } + ] + }, + "Decimals": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "HAlign": { + "description": "Horizontal text alignment.", + "oneOf": [ + { + "description": "Hug the left edge of the cell box.", + "type": "string", + "const": "left" + }, + { + "description": "Centre within the cell box.", + "type": "string", + "const": "center" + }, + { + "description": "Hug the right edge of the cell box.", + "type": "string", + "const": "right" + } + ] + }, + "VAlign": { + "description": "Vertical text alignment within the cell box.", + "oneOf": [ + { + "description": "Top of the cell box.", + "type": "string", + "const": "top" + }, + { + "description": "Vertically centred.", + "type": "string", + "const": "middle" + }, + { + "description": "Bottom of the cell box, Sheets' default.", + "type": "string", + "const": "bottom" + } + ] + }, + "Rotation": { + "description": "Text rotation in degrees: positive tilts counter-clockwise, Sheets' \"up\", negative clockwise, \"down\".", + "type": "number", + "format": "double" + } + } + } + }, + "read:getValues": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The inclusive rectangle to read.", + "$ref": "#/$defs/CellRange" + }, + "layers": { + "$ref": "#/$defs/Layers", + "default": "values" + }, + "encoding": { + "$ref": "#/$defs/Encoding", + "default": "rows" + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "Layers": { + "description": "Which layer(s) to read. Google Sheets' own `getValues()` default.", + "type": "string", + "enum": [ + "values", + "formulas", + "both" + ] + }, + "Encoding": { + "description": "How to shape `values`/`formulas` in the response.", + "oneOf": [ + { + "description": "Row-major arrays: `values[i][j]` is the cell at `range`'s `i`-th row, `j`-th column.", + "type": "string", + "const": "rows" + }, + { + "description": "A map keyed by plain A1 form, `\"A1\"`, one entry per address in `range`.", + "type": "string", + "const": "a1" + } + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "range": { + "description": "The rectangle this call answered for, completely.", + "$ref": "#/$defs/CellRange" + }, + "rows": { + "description": "`range`'s row count.", + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "cols": { + "description": "`range`'s column count.", + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "encoding": { + "description": "Echoes the requested shape, so a caller reading `values`/`formulas` out of band still knows how to interpret it.", + "$ref": "#/$defs/Encoding" + }, + "nonEmpty": { + "description": "Every address in `range` whose display text is non-empty or which holds a formula, in row-major, reading order, the sparse summary a caller wants before paying to decode a mostly-empty rectangle.", + "type": "array", + "items": { + "type": "string" + } + }, + "values": { + "description": "Present iff `layers` was `values`/`both`. Row-major `Vec>` or an A1-keyed map, depending on `encoding`." + }, + "formulas": { + "description": "Present iff `layers` was `formulas`/`both`. Same shape rule as `values`, an empty string where a cell holds no formula." + } + }, + "required": [ + "range", + "rows", + "cols", + "encoding", + "nonEmpty" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "Encoding": { + "description": "How to shape `values`/`formulas` in the response.", + "oneOf": [ + { + "description": "Row-major arrays: `values[i][j]` is the cell at `range`'s `i`-th row, `j`-th column.", + "type": "string", + "const": "rows" + }, + { + "description": "A map keyed by plain A1 form, `\"A1\"`, one entry per address in `range`.", + "type": "string", + "const": "a1" + } + ] + } + } + } + }, + "read:getSheets": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "Deliberately empty. Accepts any JSON object, including `{}`, ignoring unknown fields.", + "type": "object" + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "sheets": { + "description": "Every sheet, in tab order.", + "type": "array", + "items": { + "$ref": "#/$defs/SheetInfo" + } + } + }, + "required": [ + "sheets" + ], + "$defs": { + "SheetInfo": { + "description": "One sheet's identity and tab position.", + "type": "object", + "properties": { + "name": { + "description": "The sheet's name, exactly as stored.", + "type": "string" + }, + "order": { + "description": "0-based tab position.", + "type": "integer", + "format": "uint", + "minimum": 0 + } + }, + "required": [ + "name", + "order" + ] + } + } + } + }, + "read:getFormats": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + }, + "range": { + "description": "The inclusive rectangle to read.", + "$ref": "#/$defs/CellRange" + } + }, + "required": [ + "sheet", + "range" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "range": { + "description": "The rectangle this call answered for, completely.", + "$ref": "#/$defs/CellRange" + }, + "cells": { + "description": "One entry per address in `range`, keyed by its plain A1 form.", + "type": "object", + "additionalProperties": { + "$ref": "#/$defs/Cell" + } + } + }, + "required": [ + "range", + "cells" + ], + "$defs": { + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "Cell": { + "description": "One cell's format read-back.", + "type": "object", + "properties": { + "format": { + "description": "This cell's own stored format, grid-owned presentation only.", + "$ref": "#/$defs/CellFormat" + }, + "effectiveFormat": { + "description": "**Known Batch-0 approximation**. Always equal to `format` today, not yet a real base → banded → conditional merge.", + "$ref": "#/$defs/CellFormat" + }, + "merged": { + "description": "Whether this cell falls inside a merged range.", + "type": "boolean" + }, + "spilled": { + "description": "Whether this cell is a spill anchor, an authored formula whose stored array occupies more than itself or one of the cells it spills into, an \"echo\" cell.", + "type": "boolean" + } + }, + "required": [ + "format", + "effectiveFormat", + "merged", + "spilled" + ] + }, + "CellFormat": { + "description": "A cell's grid-owned presentation.", + "type": "object", + "properties": { + "bold": { + "description": "Bold text. Absent or `false` = not bold.", + "type": [ + "boolean", + "null" + ] + }, + "italic": { + "description": "Italic text.", + "type": [ + "boolean", + "null" + ] + }, + "strike": { + "description": "Struck-through text.", + "type": [ + "boolean", + "null" + ] + }, + "underline": { + "description": "Underlined text.", + "type": [ + "boolean", + "null" + ] + }, + "fontFamily": { + "description": "Font family. Absent = the grid's default face.", + "anyOf": [ + { + "$ref": "#/$defs/FontFamily" + }, + { + "type": "null" + } + ] + }, + "fontSize": { + "description": "Font size in points. Absent = the grid's default size.", + "anyOf": [ + { + "$ref": "#/$defs/FontSize" + }, + { + "type": "null" + } + ] + }, + "borders": { + "description": "Per-edge cell borders. Absent = no borders, never present-and-empty.", + "anyOf": [ + { + "$ref": "#/$defs/CellBorders" + }, + { + "type": "null" + } + ] + }, + "color": { + "description": "Text colour. Absent = the grid's default.", + "anyOf": [ + { + "$ref": "#/$defs/Color" + }, + { + "type": "null" + } + ] + }, + "fill": { + "description": "Background fill. Absent = none, the grid's own background shows.", + "anyOf": [ + { + "$ref": "#/$defs/Color" + }, + { + "type": "null" + } + ] + }, + "numberFormat": { + "description": "Number-display category. Absent = automatic, the engine's raw display.", + "anyOf": [ + { + "$ref": "#/$defs/NumberFormat" + }, + { + "type": "null" + } + ] + }, + "decimals": { + "anyOf": [ + { + "$ref": "#/$defs/Decimals" + }, + { + "type": "null" + } + ] + }, + "align": { + "description": "Horizontal alignment. Absent = automatic, numbers right, else left.", + "anyOf": [ + { + "$ref": "#/$defs/HAlign" + }, + { + "type": "null" + } + ] + }, + "valign": { + "description": "Vertical alignment. Absent = bottom, Sheets' default.", + "anyOf": [ + { + "$ref": "#/$defs/VAlign" + }, + { + "type": "null" + } + ] + }, + "wrap": { + "description": "Wrap text into lines within the column width, growing the row to fit.", + "type": [ + "boolean", + "null" + ] + }, + "rotation": { + "description": "Text rotation in degrees. Absent, or `0` = none.", + "anyOf": [ + { + "$ref": "#/$defs/Rotation" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "FontFamily": { + "description": "A font family name.", + "type": "string" + }, + "FontSize": { + "description": "A font size in points.", + "type": "number", + "format": "double" + }, + "CellBorders": { + "description": "A cell's borders, any **non-empty** subset of the four edges.", + "type": "object", + "properties": { + "bottom": { + "description": "The bottom edge, if drawn.", + "anyOf": [ + { + "$ref": "#/$defs/BorderEdge" + }, + { + "type": "null" + } + ] + }, + "left": { + "description": "The left edge, if drawn.", + "anyOf": [ + { + "$ref": "#/$defs/BorderEdge" + }, + { + "type": "null" + } + ] + }, + "right": { + "description": "The right edge, if drawn.", + "anyOf": [ + { + "$ref": "#/$defs/BorderEdge" + }, + { + "type": "null" + } + ] + }, + "top": { + "description": "The top edge, if drawn.", + "anyOf": [ + { + "$ref": "#/$defs/BorderEdge" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "BorderEdge": { + "description": "One drawn edge: how it looks.", + "type": "object", + "properties": { + "style": { + "description": "The line pattern.", + "$ref": "#/$defs/BorderStyle" + }, + "weight": { + "description": "The line weight.", + "$ref": "#/$defs/BorderWeight" + }, + "color": { + "description": "The line colour.", + "$ref": "#/$defs/Color" + } + }, + "additionalProperties": false, + "required": [ + "style", + "weight", + "color" + ] + }, + "BorderStyle": { + "description": "Line pattern for an edge, Sheets' solid / dashed / dotted plus the double rule.", + "oneOf": [ + { + "description": "An unbroken line.", + "type": "string", + "const": "solid" + }, + { + "description": "A dashed line.", + "type": "string", + "const": "dashed" + }, + { + "description": "A dotted line.", + "type": "string", + "const": "dotted" + }, + { + "description": "Two parallel lines.", + "type": "string", + "const": "double" + } + ] + }, + "BorderWeight": { + "description": "Line weight, Sheets' thin / medium / thick.", + "oneOf": [ + { + "description": "The default pen.", + "type": "string", + "const": "thin" + }, + { + "description": "One step heavier.", + "type": "string", + "const": "medium" + }, + { + "description": "The heaviest pen.", + "type": "string", + "const": "thick" + } + ] + }, + "Color": { + "description": "A CSS colour string, `#ff0000`, `#fff2cc`, `rgb(…)`, a named colour.", + "type": "string" + }, + "NumberFormat": { + "description": "A number-display category, studio#10.", + "oneOf": [ + { + "description": "Grouped fixed-point: `1,234.57`.", + "type": "string", + "const": "number" + }, + { + "description": "The value times 100, with a `%` suffix.", + "type": "string", + "const": "percent" + }, + { + "description": "Grouped fixed-point with a currency symbol.", + "type": "string", + "const": "currency" + }, + { + "description": "The value read as a date serial. **Implies date typing**.", + "type": "string", + "const": "date" + }, + { + "description": "The value read as a date-time serial.", + "type": "string", + "const": "datetime" + } + ] + }, + "Decimals": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "HAlign": { + "description": "Horizontal text alignment.", + "oneOf": [ + { + "description": "Hug the left edge of the cell box.", + "type": "string", + "const": "left" + }, + { + "description": "Centre within the cell box.", + "type": "string", + "const": "center" + }, + { + "description": "Hug the right edge of the cell box.", + "type": "string", + "const": "right" + } + ] + }, + "VAlign": { + "description": "Vertical text alignment within the cell box.", + "oneOf": [ + { + "description": "Top of the cell box.", + "type": "string", + "const": "top" + }, + { + "description": "Vertically centred.", + "type": "string", + "const": "middle" + }, + { + "description": "Bottom of the cell box, Sheets' default.", + "type": "string", + "const": "bottom" + } + ] + }, + "Rotation": { + "description": "Text rotation in degrees: positive tilts counter-clockwise, Sheets' \"up\", negative clockwise, \"down\".", + "type": "number", + "format": "double" + } + } + } + }, + "read:getCharts": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "No `commandId`/OCC field modeled.", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + } + }, + "required": [ + "sheet" + ] + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "charts": { + "type": "array", + "items": { + "$ref": "#/$defs/ChartInfo" + } + } + }, + "required": [ + "charts" + ], + "$defs": { + "ChartInfo": { + "description": "One chart's identity, placement, form, and renderer options.", + "type": "object", + "properties": { + "chartId": { + "type": "string" + }, + "range": { + "description": "The chart's target rectangle, A1-rendered.", + "$ref": "#/$defs/CellRange" + }, + "chartType": { + "description": "Which chart form to draw, e.g. `\"column\"`, `\"box-plot\"`.", + "type": "string" + }, + "options": { + "description": "Renderer-specific knobs, opaque, unvalidated by this read, matches the TS source's own `options: c.options` passthrough." + } + }, + "required": [ + "chartId", + "range", + "chartType", + "options" + ] + }, + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + } + }, + "read:getConditionalFormats": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + } + }, + "required": [ + "sheet" + ] + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "rules": { + "description": "Every conditional-format rule on `sheet`, in real precedence order.", + "type": "array", + "items": { + "$ref": "#/$defs/ConditionalFormatRuleInfo" + } + } + }, + "required": [ + "rules" + ], + "$defs": { + "ConditionalFormatRuleInfo": { + "description": "One conditional-format rule's identity, target rectangle, and definition.", + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "range": { + "$ref": "#/$defs/CellRange" + }, + "rule": { + "$ref": "#/$defs/RuleOut" + } + }, + "required": [ + "id", + "range", + "rule" + ] + }, + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "RuleOut": { + "description": "One rule's definition, as reported back by this command.", + "oneOf": [ + { + "type": "object", + "properties": { + "operator": { + "$ref": "#/$defs/OperatorOut" + }, + "value": { + "type": "number", + "format": "double" + }, + "value2": { + "type": [ + "number", + "null" + ], + "format": "double" + }, + "style": { + "$ref": "#/$defs/CellFormat" + }, + "kind": { + "type": "string", + "const": "singleCondition" + } + }, + "required": [ + "kind", + "operator", + "value", + "style" + ] + }, + { + "type": "object", + "properties": { + "minColor": { + "$ref": "#/$defs/HexColor" + }, + "maxColor": { + "$ref": "#/$defs/HexColor" + }, + "kind": { + "type": "string", + "const": "colorScale" + } + }, + "required": [ + "kind", + "minColor", + "maxColor" + ] + }, + { + "type": "object", + "properties": { + "formula": { + "type": "string" + }, + "style": { + "$ref": "#/$defs/CellFormat" + }, + "kind": { + "type": "string", + "const": "customFormula" + } + }, + "required": [ + "kind", + "formula", + "style" + ] + } + ] + }, + "OperatorOut": { + "description": "A single-condition rule's operator, as reported back by this command.", + "type": "string", + "enum": [ + "greaterThan", + "greaterThanOrEqual", + "lessThan", + "lessThanOrEqual", + "equal", + "notEqual", + "between", + "notBetween" + ] + }, + "CellFormat": { + "description": "A cell's grid-owned presentation.", + "type": "object", + "properties": { + "bold": { + "description": "Bold text. Absent or `false` = not bold.", + "type": [ + "boolean", + "null" + ] + }, + "italic": { + "description": "Italic text.", + "type": [ + "boolean", + "null" + ] + }, + "strike": { + "description": "Struck-through text.", + "type": [ + "boolean", + "null" + ] + }, + "underline": { + "description": "Underlined text.", + "type": [ + "boolean", + "null" + ] + }, + "fontFamily": { + "description": "Font family. Absent = the grid's default face.", + "anyOf": [ + { + "$ref": "#/$defs/FontFamily" + }, + { + "type": "null" + } + ] + }, + "fontSize": { + "description": "Font size in points. Absent = the grid's default size.", + "anyOf": [ + { + "$ref": "#/$defs/FontSize" + }, + { + "type": "null" + } + ] + }, + "borders": { + "description": "Per-edge cell borders. Absent = no borders, never present-and-empty.", + "anyOf": [ + { + "$ref": "#/$defs/CellBorders" + }, + { + "type": "null" + } + ] + }, + "color": { + "description": "Text colour. Absent = the grid's default.", + "anyOf": [ + { + "$ref": "#/$defs/Color" + }, + { + "type": "null" + } + ] + }, + "fill": { + "description": "Background fill. Absent = none, the grid's own background shows.", + "anyOf": [ + { + "$ref": "#/$defs/Color" + }, + { + "type": "null" + } + ] + }, + "numberFormat": { + "description": "Number-display category. Absent = automatic, the engine's raw display.", + "anyOf": [ + { + "$ref": "#/$defs/NumberFormat" + }, + { + "type": "null" + } + ] + }, + "decimals": { + "anyOf": [ + { + "$ref": "#/$defs/Decimals" + }, + { + "type": "null" + } + ] + }, + "align": { + "description": "Horizontal alignment. Absent = automatic, numbers right, else left.", + "anyOf": [ + { + "$ref": "#/$defs/HAlign" + }, + { + "type": "null" + } + ] + }, + "valign": { + "description": "Vertical alignment. Absent = bottom, Sheets' default.", + "anyOf": [ + { + "$ref": "#/$defs/VAlign" + }, + { + "type": "null" + } + ] + }, + "wrap": { + "description": "Wrap text into lines within the column width, growing the row to fit.", + "type": [ + "boolean", + "null" + ] + }, + "rotation": { + "description": "Text rotation in degrees. Absent, or `0` = none.", + "anyOf": [ + { + "$ref": "#/$defs/Rotation" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "FontFamily": { + "description": "A font family name.", + "type": "string" + }, + "FontSize": { + "description": "A font size in points.", + "type": "number", + "format": "double" + }, + "CellBorders": { + "description": "A cell's borders, any **non-empty** subset of the four edges.", + "type": "object", + "properties": { + "bottom": { + "description": "The bottom edge, if drawn.", + "anyOf": [ + { + "$ref": "#/$defs/BorderEdge" + }, + { + "type": "null" + } + ] + }, + "left": { + "description": "The left edge, if drawn.", + "anyOf": [ + { + "$ref": "#/$defs/BorderEdge" + }, + { + "type": "null" + } + ] + }, + "right": { + "description": "The right edge, if drawn.", + "anyOf": [ + { + "$ref": "#/$defs/BorderEdge" + }, + { + "type": "null" + } + ] + }, + "top": { + "description": "The top edge, if drawn.", + "anyOf": [ + { + "$ref": "#/$defs/BorderEdge" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "BorderEdge": { + "description": "One drawn edge: how it looks.", + "type": "object", + "properties": { + "style": { + "description": "The line pattern.", + "$ref": "#/$defs/BorderStyle" + }, + "weight": { + "description": "The line weight.", + "$ref": "#/$defs/BorderWeight" + }, + "color": { + "description": "The line colour.", + "$ref": "#/$defs/Color" + } + }, + "additionalProperties": false, + "required": [ + "style", + "weight", + "color" + ] + }, + "BorderStyle": { + "description": "Line pattern for an edge, Sheets' solid / dashed / dotted plus the double rule.", + "oneOf": [ + { + "description": "An unbroken line.", + "type": "string", + "const": "solid" + }, + { + "description": "A dashed line.", + "type": "string", + "const": "dashed" + }, + { + "description": "A dotted line.", + "type": "string", + "const": "dotted" + }, + { + "description": "Two parallel lines.", + "type": "string", + "const": "double" + } + ] + }, + "BorderWeight": { + "description": "Line weight, Sheets' thin / medium / thick.", + "oneOf": [ + { + "description": "The default pen.", + "type": "string", + "const": "thin" + }, + { + "description": "One step heavier.", + "type": "string", + "const": "medium" + }, + { + "description": "The heaviest pen.", + "type": "string", + "const": "thick" + } + ] + }, + "Color": { + "description": "A CSS colour string, `#ff0000`, `#fff2cc`, `rgb(…)`, a named colour.", + "type": "string" + }, + "NumberFormat": { + "description": "A number-display category, studio#10.", + "oneOf": [ + { + "description": "Grouped fixed-point: `1,234.57`.", + "type": "string", + "const": "number" + }, + { + "description": "The value times 100, with a `%` suffix.", + "type": "string", + "const": "percent" + }, + { + "description": "Grouped fixed-point with a currency symbol.", + "type": "string", + "const": "currency" + }, + { + "description": "The value read as a date serial. **Implies date typing**.", + "type": "string", + "const": "date" + }, + { + "description": "The value read as a date-time serial.", + "type": "string", + "const": "datetime" + } + ] + }, + "Decimals": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "HAlign": { + "description": "Horizontal text alignment.", + "oneOf": [ + { + "description": "Hug the left edge of the cell box.", + "type": "string", + "const": "left" + }, + { + "description": "Centre within the cell box.", + "type": "string", + "const": "center" + }, + { + "description": "Hug the right edge of the cell box.", + "type": "string", + "const": "right" + } + ] + }, + "VAlign": { + "description": "Vertical text alignment within the cell box.", + "oneOf": [ + { + "description": "Top of the cell box.", + "type": "string", + "const": "top" + }, + { + "description": "Vertically centred.", + "type": "string", + "const": "middle" + }, + { + "description": "Bottom of the cell box, Sheets' default.", + "type": "string", + "const": "bottom" + } + ] + }, + "Rotation": { + "description": "Text rotation in degrees: positive tilts counter-clockwise, Sheets' \"up\", negative clockwise, \"down\".", + "type": "number", + "format": "double" + }, + "HexColor": { + "description": "A strictly-validated `#rgb`/`#rrggbb`/`#rrggbbaa` hex colour.", + "type": "string" + } + } + } + }, + "read:getBandedRanges": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + } + }, + "required": [ + "sheet" + ] + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "bandedRanges": { + "description": "Every banded range on `sheet`, in real precedence order.", + "type": "array", + "items": { + "$ref": "#/$defs/BandedRangeInfo" + } + } + }, + "required": [ + "bandedRanges" + ], + "$defs": { + "BandedRangeInfo": { + "description": "One banded range's identity, target rectangle, and style.", + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "range": { + "$ref": "#/$defs/CellRange" + }, + "style": { + "$ref": "#/$defs/StyleOut" + } + }, + "required": [ + "id", + "range", + "style" + ] + }, + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + }, + "StyleOut": { + "description": "A banded range's color assignment, as reported back by this command.", + "type": "object", + "properties": { + "headerColor": { + "anyOf": [ + { + "$ref": "#/$defs/HexColor" + }, + { + "type": "null" + } + ] + }, + "firstBandColor": { + "$ref": "#/$defs/HexColor" + }, + "secondBandColor": { + "$ref": "#/$defs/HexColor" + }, + "footerColor": { + "anyOf": [ + { + "$ref": "#/$defs/HexColor" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "firstBandColor", + "secondBandColor" + ] + }, + "HexColor": { + "description": "A strictly-validated `#rgb`/`#rrggbb`/`#rrggbbaa` hex colour.", + "type": "string" + } + } + } + }, + "read:getNamedRanges": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "Deliberately empty.", + "type": "object" + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "namedRanges": { + "description": "Every named range, in declaration order.", + "type": "array", + "items": { + "$ref": "#/$defs/NamedRangeInfo" + } + } + }, + "required": [ + "namedRanges" + ], + "$defs": { + "NamedRangeInfo": { + "description": "One named range's identity and real target.", + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "sheet": { + "description": "The named range's REAL target sheet, parsed from its own `ref`.", + "type": "string" + }, + "range": { + "description": "The named range's target rectangle.", + "$ref": "#/$defs/CellRange" + } + }, + "required": [ + "name", + "sheet", + "range" + ] + }, + "CellRange": { + "description": "An inclusive rectangle. `from`/`to` may be equal, a single cell.", + "type": "object", + "properties": { + "from": { + "description": "Top-left cell, e.g. `\"A1\"`.", + "type": "string" + }, + "to": { + "description": "Bottom-right cell, e.g. `\"B3\"`.", + "type": "string" + } + }, + "required": [ + "from", + "to" + ] + } + } + } + }, + "read:getExtent": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet name.", + "type": "string" + } + }, + "required": [ + "sheet" + ] + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "description": "The USED extent, not a capacity.", + "type": "object", + "properties": { + "rows": { + "description": "The highest populated row, 1-based, or `0` if the sheet is empty.", + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "cols": { + "description": "The highest populated column, 1-based, or `0` if the sheet is empty.", + "type": "integer", + "format": "uint32", + "minimum": 0 + } + }, + "required": [ + "rows", + "cols" + ] + } + }, + "sheet:add": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "name": { + "description": "The name to give the new sheet. When present, this command trims it before validating. An explicit whitespace-only name is therefore refused as malformed, empty after trim, never silently treated as omitted.", + "type": [ + "string", + "null" + ], + "default": null + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "sheet:delete": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet to delete.", + "type": "string" + } + }, + "required": [ + "sheet" + ] + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "sheet:rename": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet to rename. This is the sheet's NAME.", + "type": "string" + }, + "name": { + "description": "The name to rename it to.", + "type": "string" + } + }, + "required": [ + "sheet", + "name" + ] + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "sheet:reorder": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet to move. This is the sheet's NAME.", + "type": "string" + }, + "direction": { + "description": "Which way to move it, one tab position, never an absolute position.", + "$ref": "#/$defs/Direction" + } + }, + "required": [ + "sheet", + "direction" + ], + "$defs": { + "Direction": { + "description": "Which way to move the sheet.", + "type": "string", + "enum": [ + "left", + "right" + ] + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "sheet:setActive": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "The sheet to activate.", + "type": "object", + "properties": { + "sheet": { + "description": "The sheet to make active.", + "type": "string" + } + }, + "required": [ + "sheet" + ] + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "view:setPageSetup": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "sheet": { + "type": "string" + }, + "orientation": { + "anyOf": [ + { + "$ref": "#/$defs/WireOrientation" + }, + { + "type": "null" + } + ] + }, + "scale": { + "anyOf": [ + { + "$ref": "#/$defs/WireScale" + }, + { + "type": "null" + } + ] + }, + "marginsMode": { + "anyOf": [ + { + "$ref": "#/$defs/WireMarginsMode" + }, + { + "type": "null" + } + ] + }, + "customMargins": { + "anyOf": [ + { + "$ref": "#/$defs/WireMargins" + }, + { + "type": "null" + } + ] + }, + "printArea": { + "description": "Three states.", + "anyOf": [ + { + "$ref": "#/$defs/WirePrintArea" + }, + { + "type": "null" + } + ] + }, + "showGridlines": { + "type": [ + "boolean", + "null" + ] + }, + "header": { + "anyOf": [ + { + "$ref": "#/$defs/WireHeaderFooter" + }, + { + "type": "null" + } + ] + }, + "footer": { + "anyOf": [ + { + "$ref": "#/$defs/WireHeaderFooter" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "sheet" + ], + "$defs": { + "WireOrientation": { + "type": "string", + "enum": [ + "portrait", + "landscape" + ] + }, + "WireScale": { + "type": "object", + "properties": { + "mode": { + "$ref": "#/$defs/WireScaleMode" + }, + "percent": { + "type": [ + "number", + "null" + ], + "format": "double" + } + }, + "required": [ + "mode" + ] + }, + "WireScaleMode": { + "type": "string", + "enum": [ + "normal", + "fitWidth", + "custom" + ] + }, + "WireMarginsMode": { + "type": "string", + "enum": [ + "normal", + "narrow", + "custom" + ] + }, + "WireMargins": { + "type": "object", + "properties": { + "top": { + "type": "number", + "format": "double" + }, + "right": { + "type": "number", + "format": "double" + }, + "bottom": { + "type": "number", + "format": "double" + }, + "left": { + "type": "number", + "format": "double" + } + }, + "required": [ + "top", + "right", + "bottom", + "left" + ] + }, + "WirePrintArea": { + "type": "object", + "properties": { + "r0": { + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "r1": { + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "c0": { + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "c1": { + "type": "integer", + "format": "uint32", + "minimum": 0 + } + }, + "required": [ + "r0", + "r1", + "c0", + "c1" + ] + }, + "WireHeaderFooter": { + "type": "object", + "properties": { + "left": { + "type": [ + "string", + "null" + ] + }, + "center": { + "type": [ + "string", + "null" + ] + }, + "right": { + "type": [ + "string", + "null" + ] + } + } + } + } + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "null", + "type": "null" + } + }, + "history:undo": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "Deliberately empty.", + "type": "object" + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "undone": { + "description": "`true` only when something was actually popped AND fully reverted. `false` for a genuinely empty undo stack, a normal, non-error outcome, not a refusal.", + "type": "boolean" + } + }, + "required": [ + "undone" + ] + } + }, + "history:redo": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "description": "Deliberately empty.", + "type": "object" + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "redone": { + "description": "`true` only when something was actually popped AND fully reapplied. `false` for a genuinely empty redo stack, a normal, non-error outcome, not a refusal.", + "type": "boolean" + } + }, + "required": [ + "redone" + ] + } + }, + "history:restore": { + "payload": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payload", + "type": "object", + "properties": { + "steps": { + "description": "How many undo steps to walk back, from wherever the stack is right now. `0` is a legal, trivially-successful no-op.", + "type": "integer", + "format": "uint32", + "minimum": 0 + } + }, + "required": [ + "steps" + ] + }, + "output": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Output", + "type": "object", + "properties": { + "stepsRequested": { + "description": "Echoed from the payload.", + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "stepsCompleted": { + "description": "How many steps actually completed, equal to `stepsRequested` on full success.", + "type": "integer", + "format": "uint32", + "minimum": 0 + } + }, + "required": [ + "stepsRequested", + "stepsCompleted" + ] + } + } +}