Change a sheet
edit_sheetChanges a sheet, read at "base": the version (v N) your last get, read or changes showed. Addresses, rows and headers mean what they meant at that version, wherever they moved since; so do chart and format numbers (#N, by order in the outline; a chart an earlier op here makes takes the next number) and sheet names (after a rename by an earlier op, either works). Every op applies, or none: a cell someone changed since is refused, naming who, so read again and apply on the new version. Answers each cell old → new, results that changed, and the new version. "dryRun" answers the same without saving; "undo" takes back a change of yours.
Tool call template
Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.
{
"id": 1,
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"arguments": {
"doc": "<doc>"
},
"name": "edit_sheet"
}
}Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| doc | Yes | The doc's link or its code. | |
| key | No | A retry key, up to 64 characters. Default: one made from the request, so the same request on the same version applies once. | |
| ops | No | Changes, applied in order; "sheet" can be left out when there's one. Each is one of: {"set": "Tasks!E17", "value": "Done"} · {"set": "Tasks!B2:C3", "values": [["Tile grout", "Kitchen"], ["Vent cover", "Bathrooms"]]} (the sheet grows past its edge) {"update": {"sheet": "Tasks", "where": "Area = Kitchen and Status = Open", "set": {"Status": "Done"}, "max": 50}} (rows matching at base, by header; max is 1 unless set, and more matches are refused) {"append": {"sheet": "Tasks", "rows": [{"ID": "T-214", "Item": "Gutter downspout", "Status": "Open"}]}} (after the last filled row, by header; column formulas carry down unless you give a value) {"insertRows": {"sheet": "Tasks", "after": 40, "count": 2}} (0: the top) · {"deleteRows": {"sheet": "Tasks", "rows": "9, 41:42"}} · {"moveRows": {"sheet": "Tasks", "rows": "5:6", "after": 10}} {"insertCols": {"sheet": "Tasks", "after": "C", "count": 1}} ("": before A) · {"deleteCols": {"sheet": "Tasks", "cols": "D:E"}} · {"moveCols": {"sheet": "Tasks", "cols": "F", "after": "B"}} {"format": {"range": "Tasks!1:1", "bold": true, "fill": "#fff2cc"}} (cells, rows or columns; null clears. bold italic underline strike wrap · size in points · font · color fill "#rrggbb" · hAlign left center right justify · vAlign top middle bottom · indent · borderTop/Right/Bottom/Left "thin #d0d5dd" (thin medium thick dashed dotted double) · numFmt as Excel's, "$#,##0.00") {"resize": {"range": "Tasks!B:C", "size": 120}} (points or "auto"; "hidden": true) · {"merge": "Tasks!A1:G1"} · {"unmerge": "Tasks!A1:G1"} {"copy": {"from": "Tasks!A2:C9", "to": "Tasks!F2"}} (a paste: references move, formats come; "to" a first cell or a range to repeat over; "paste": "values", "formats", "formulas" or "widths"; "transpose": true; copies cells as before this edit) {"addSheet": {"name": "Hours", "after": "Tasks"}} · {"renameSheet": {"sheet": "Hours", "name": "Time"}} · {"moveSheet": {"sheet": "Time", "first": true}} · {"deleteSheet": "Old"} · {"sheetProps": {"frozenRows": 1, "frozenCols": 0, "hidden": false, "tabColor": "#4472c4"}} {"setName": {"name": "Rate", "range": "Summary!B2"}} · {"deleteName": "Rate"} {"addTable": {"range": "Tasks!A1:G40", "name": "Tasks"}} (header and banded rows) · {"setTable": {"table": "Tasks", "range": "Tasks!A1:G60", "totals": true}} · {"deleteTable": "Tasks"} (cells stay) {"validate": {"range": "Tasks!E2:E", "list": ["Open", "In progress", "Done"], "reject": true, "help": "Pick a status"}} (E2:E: row 2 down, later rows too; reject refuses others, else marks them) · one kind: "list", "from": "Lists!A2:A20", "checkbox": true, "number": {"between": [0, 100]} ("equal to", "not equal to", "greater than", "at least", "less than", "at most", "not between"), "date": {"after": "2026-01-01"} ("before", "on or after", "on or before", "on", "not on", "between"; true: any), "text": {"contains": "x"} ("not contains", "exactly"), "email": true, "url": true, "length": {"at most": 50}, "formula": "=F2<G2" · a dropdown (list or from): "colors": {"Done": "green", "Blocked": "#f6d3d0"} (chips: grey, red, orange, yellow, green, teal, blue, purple, pink, brown, or "#rrggbb"), "show": "chip" (default), "arrow" (text with ▾) or "plain" · "remove": true {"conditional": {"range": "Tasks!E2:E", "text is": "Blocked", "format": {"fill": "#f6d3d0", "bold": true}}} (the outline lists rules as format #N; the first that matches wins; new go last) · one condition: "empty", "not empty": true, "text contains", "text not contains", "text starts with", "text ends with", "text is": "x", "date is", "date before", "date after": "today", "yesterday", "past week", "past month", "past year" or a date, "number": {"greater than": 8} (validate's words), "formula": "=$F2<TODAY()", "scale": {"min": "#ffffff", "mid": "#ffd666", "max": "#57bb8a"} (no format), "duplicate", "unique": true, "top", "bottom": 10 or "10%", "above average", "below average": true · format: bold italic underline strike color fill · "before": 2 or "first": true places it · {"conditional": {"rule": 3, "first": true}} moves or, with fields, changes rule 3 · "remove": true with a rule or a range {"replace": {"find": "Lee", "with": "Priya", "in": "Owner"}} (one change; "in" a column by header or letter, or a range; left out, the sheet) · "case", "whole", "regex" (RE2, $1), "formulas": true searches formula text · the answer says what was left and why {"chart": {"range": "Tasks!A1:C40", "type": "column", "title": "Costs by area"}} (chart #N in the outline; first row names series, first column labels points) · "header", "labels": true or false, guessed when left out · type: column, bar, line, area, pie, donut, scatter (first column x), "stacked column", "stacked bar", "stacked area", "doughnut", "horizontal bar" · "stacked": true for column, bar, area · "at": "E2", "below", "beside", "below chart #2", "beside chart #2" (default: beside the range, over nothing) · "width", "height" px · "x title", "y title" · "legend": right, bottom, top, none · "colors": ["#4285f4", null] · {"chart": {"chart": 2, "type": "line"}} changes it · {"chart": {"chart": 2, "remove": true}} Values: a number, true or false, null (empty), a string ("=…" a formula: "=SUM(F2:F40)", "=[@Hours]*85", "=Tasks[Hours]"), {"text": "=shown as typed"}, {"date": "2026-10-19"}, {"text": "Quote", "link": "https://…"} (or "mailto:…", "#Costs!A1:C9"). Formulas spill as in Excel ("=FILTER(A2:D40,D2:D40=\"Open\")", "=SORT(B2#)"); #SPILL! when blocked. | |
| base | No | The version you read: v N in the answer. | |
| note | No | Why, in a few words. Shown with the change in the sheet and in changes. | |
| undo | No | Undo your own change that made this version, as one change. Goes alone: no base, ops or expect. | |
| dryRun | No | Work it out and answer, saving nothing. | |
| expect | No | Cells that must hold these values before the ops, as at base, or nothing applies: {"Tasks!E17": "Open"}. Not what the ops should make: the answer shows that. |