Case study · Sheets Diff
A production case study: human-approved Google Sheets diffs
A spreadsheet edit is the smallest-looking dangerous thing an agent can do. This is how Sheets Diff makes each one big enough to read before it lands.
Last verified . Hosts and protocols move fast, so details here may be stale. Check the primary sources before you build.
"Update the monthly total." In a chat transcript that request is four words, and its smallness is the danger. Four words hide which workbook, which sheet, which range, which formulas, and which values are about to be replaced. The Sheets Diff MCP app exists to drag every one of those questions into the light before the workbook changes.
The failure mode
The unit of trust is the patch
The app never begins by writing. It reads the selected context, builds a proposed patch, and renders the before-and-after values in a widget where a person can apply, reject, or revise. Compare that to a single "update range" tool, which gives the model room to compress reasoning and execution into one step. Even when the model finds the right cells, the user meets the consequences only after the workbook has changed, and recovery requires knowing the previous values, the formulas, and the range version.
The safer unit is small enough to read in full:
{
workbook: "Gastos Mensais",
sheet: "Sheet1",
range: "Z11:Z11",
before: [["Pending"]],
after: [["Reviewed"]]
}
That object can be validated, displayed, approved, applied exactly once, and recorded. A sentence in a chat transcript can do none of those things.
Seven steps, one write
Resolve the context
Identify the spreadsheet, the sheet, and the target range under the authenticated account. "Monthly total" becomes a concrete address.
Read the before state
Capture the current values and formulas. This is the material that review and rollback are made of.
Normalize the patch
Explicit A1 ranges and rectangular value arrays. Nothing the server would have to interpret later.
Render the diff
Show the unchanged context, the removed values, the added values, and the total cell count.
Wait for a person
The write tool accepts a proposal identifier, never freshly generated text.
Revalidate, then apply
Confirm the source still matches the preview, then write the exact patch.
Return a receipt
Record the range, the resulting state, and the data needed for a guarded revert.
A broad range is a policy error
Spreadsheet APIs will cheerfully accept a broad range that happens to contain a small edit. The widget displays the narrowest affected range, and the server rejects mismatched dimensions outright. When a one-cell proposal arrives targeting a whole column, the server treats it as a policy error rather than an implementation convenience.
Formulas get their own handling, because a rendered value is not always the source value. The preview distinguishes a formula change from its calculated result, so the person approving knows exactly what will persist in the cell.
The sheet can move between preview and click
Between the moment the diff renders and the moment someone clicks apply, another person or an automation may edit the workbook. So before applying, the server compares the current source state against the captured before state, or a revision token. If anything changed, the proposal dies and a fresh diff is generated. Quietly overwriting the newer state would make the entire review misleading, which is worse than having no review at all.
An approval covers one exact patch against one known source state. It is never a standing permission to make an approximately similar edit later.
The widget is the review surface chat lacks
The widget earns its place by showing what chat text cannot: aligned cells, color-coded additions and removals, the identity of the range, warnings, and a button whose label states the effect. It also keeps the proposal visible after the conversation scrolls on.
And none of this is really about spreadsheets. An email preview is a patch to an outbox. A Slack preview is a patch to a channel. In every case the agent converts an ambiguous request into a concrete proposed effect, and a person authorizes that effect and nothing else.
Production checks
- OAuth scopes are limited to the operation the app performs.
- Proposal identifiers are user-bound, short-lived, and single-use.
- Apply and revert operations are idempotent.
- Logs carry identifiers and outcomes without copying unnecessary sheet content.
- The same preview and approval path works in ChatGPT and Claude.
- A network interruption produces a recoverable status, not a blind retry.
The whole apparatus costs one click over a silent write and is much faster than auditing a damaged workbook. What it buys is a clean division of labor: the agent does the precision work, the person keeps the authority. In a spreadsheet, where the smallest edits are the ones nobody rechecks, that is the right place to spend a click.