build-google-sheet
Build or extend a Google Sheet that does real work: financial models, budgets, P&L and cash-flow statements, accounting ledgers and reconciliations, trackers, dashboards and data tables with formulas, number formats, validation, conditional formatting, named ranges, protection and charts, then verify it computes. Use whenever the deliverable is a spreadsheet or the user asks for changes to one. Requires google-workspace-mcp.
- License 许可
- MIT
- 最近更新
- 2026-11-13
- Stars
- ★ 29
- Forks
- 156
01 前言 Front Matter
- name
- build-google-sheet
- description
- Build or extend a Google Sheet that does real work: financial models, budgets, P&L and cash-flow statements, accounting ledgers and reconciliations, trackers, dashboards and data tables with formulas, number formats, validation, conditional formatting, named ranges, protection and charts, then verify it computes. Use whenever the deliverable is a spreadsheet or the user asks for changes to one. Requires google-workspace-mcp.
03 SKILL.md 正文
Building spreadsheets that compute
A good sheet separates inputs from logic, uses formulas rather than pasted numbers, labels
every row, formats so numbers read at a glance, and proves itself with check rows. Devin
builds it in passes, reading back after each one. Tool signatures: google-workspace-mcp.
Pass 0: agree the shape
For a model or statement, confirm in one message: periods (months/quarters/years and how many), currency and units, the inputs the user controls, the outputs they care about, and whether existing data should be imported. Default layout for a model:
Inputstab: one assumption per row (label, value, unit/notes); the only cells a user edits.- One tab per statement or calculation (
P&L,Cash flow,Headcount...): row labels in column A, periods across columns, every number a formula referencingInputsor the row above. Checksrows (or tab): identities that must hold (balance sheet balances, totals match the source, no negative inventory), showingok/CHECK.Datatabs for raw imports, untouched by formulas; summaries pull from them withSUMIFS/QUERY/FILTER.
For a ledger/reconciliation: a transactions table with a header row, consistent columns
(date, account, description, debit, credit, balance), the balance as a running formula, a
trial-balance or reconciliation tab with SUMIFS by account and a difference row.
Pass 1: create the workbook and tabs
- New file:
create_file(name, type: "spreadsheet", folderId?), optionally with CSVcontentfor a first data tab. Thenread_sheet(spreadsheetId)for the defaultsheetId. - Tabs:
update_spreadsheetwithaddSheet: {properties: {title, gridProperties: {rowCount, columnCount, frozenRowCount: 1}}}; rename the default tab withupdateSheetProperties(fields: "title"). The replies carry each newsheetId: keep them, every later grid request needs them. - Existing workbook:
read_sheetwith no range (tabs, sizes, named ranges) and the ranges in play withvalueRender: "formula"before changing anything. Never overwrite a tab you have not read.
Pass 2: write values and formulas
write_sheet(spreadsheetId, range: "'Inputs'!A1", values: [[...], ...]): a 2-D array laid
down from the top-left cell. Strings that look like formulas, numbers, dates (2027-01-01)
or percents (12%) are parsed as such; raw: true keeps them literal (ids, zip codes).
- Write formulas as strings (
"=Inputs!$B$2*(1+Inputs!$B$3)^(B$1-1)"), build the per-period row in code so each column's references are right, and keep absolute references ($B$2) on inputs. Cross-tab references use'Tab name'!A1. - Prefer one formula pattern per row over hand-typed values; prefer
SUMIFS,XLOOKUP/INDEX-MATCH,IFERROR,ARRAYFORMULA,QUERY,SEQUENCE/EDATEfor period headers. - Appending transactions:
write_sheet(range: "'Ledger'!A:F", values, append: true). - Lay down labels and headers in the same write so the sheet is never half-labelled.
Pass 3: make it readable and safe (update_spreadsheet)
| Need | Request |
|---|---|
| Currency / percent / date formats | repeatCell with cell.userEnteredFormat.numberFormat: {type: "CURRENCY", pattern: "$#,##0;($#,##0)"} (or PERCENT 0.0%, DATE mmm yyyy), fields: "userEnteredFormat.numberFormat" |
| Bold header, fill, borders, wrap | repeatCell with textFormat.bold, backgroundColor, horizontalAlignment; updateBorders |
| Freeze headers / label column | updateSheetProperties gridProperties.frozenRowCount / frozenColumnCount |
| Column widths | autoResizeDimensions or updateDimensionProperties (pixelSize) |
| Input cells visibly editable | light fill on Inputs!B cells; setDataValidation (NUMBER_BETWEEN, ONE_OF_LIST for dropdowns, DATE_IS_VALID) with strict: true. strict: true did not stop a write_sheet value in testing, so add a check cell rather than rely on it for values you write |
| Protect formula tabs | addProtectedRange with warningOnly: true (users get a warning, not a lock-out) on each calculation tab |
| Flag problems | addConditionalFormatRule (NUMBER_LESS 0 -> red text; TEXT_EQ "CHECK" -> red fill; CUSTOM_FORMULA for row-wise rules) |
| Names for key inputs | addNamedRange (growth_rate = Inputs!B3) so formulas read =Revenue*(1+growth_rate) |
| Charts | addChart with spec.basicChart (COLUMN, LINE, BAR) or pieChart; domains/series as sourceRanges; position with anchorCell; reply has chartId. With row-oriented data and headerCount: 1, start domains and series at the label column. Starting at the first value drops that point and uses it as the legend text |
| Totals / grouping | addDimensionGroup; autoFill; sortRange; setBasicFilter on data tabs |
Grid ranges: {sheetId, startRowIndex, endRowIndex, startColumnIndex, endColumnIndex},
0-based, end-exclusive; omit an end to run to the sheet edge (but see the repeatCell gotcha below). Group related requests in one
call per tab; the whole call fails if one request is wrong, so a failure names
requests[<n>] to fix.
Pass 4: verify it computes
read_sheet(range, valueRender: "unformatted")on every output row: no#REF!,#DIV/0!,#NAME?,#N/A; totals equal the sum of their parts; check rows sayok.read_sheet(range, valueRender: "formula")on one column: references point where intended (off-by-one columns are the common bug).- Recompute two or three headline numbers independently (from the inputs, in code) and compare.
- For a rendered check,
download_file(fileId: <spreadsheet id>, exportMimeType: "application/pdf")(or xlsx) fromscripted_tools. - Fix with
write_sheet/update_spreadsheeton the same file; do not create a new one.
Deliver
Link, where it lives, which tab holds the inputs, and the one or two assumptions the user should confirm. Mention anything imported that did not fit (unparsed dates, blank ids).
Conventions and gotchas
- Displayed values are strings (
"$100,000"): compare numbers withvalueRender: "unformatted". - Bound every
repeatCellwithstartColumnIndexandendColumnIndex. A whole-row fill widens the PDF print area and shrinks the tab until it is unreadable. write_sheetcannot extend a tab beyond itsrowCount/columnCount: grow it first withappendDimensionorupdateSheetProperties.- Tab names with spaces or symbols need quotes in A1 ranges (
'P&L'!A1:G12). update_file content=...replaces the whole workbook with a single CSV tab; for a workbook with several tabs usewrite_sheet/update_spreadsheet.- Never hard-code a computed number into a cell the user will trust as a formula; if a value must be pasted (an external actual), mark the cell as an input.
- Dates: write ISO strings and format the column with a
DATEnumber format.read_sheetreturns dates as displayed strings even withvalueRender: "unformatted";dateTimeRender: "serial"gives the serial day numbers for arithmetic. - Charts and conditional formats reference
sheetIds; renaming a tab is safe, deleting and re-adding one is not.
04 同仓库更多 Skills
business-data
暂无简介
workflow
Creates durable, resumable workflows using Vercel's Workflow SDK. Use when building workflows that need to survive restarts, pause for external events, retry on failure, or coordinate multi-step operations over time. Triggers on mentions of "workflow", "durable functions", "resumable", "workflow sdk", "queue", "event", "push", "subscribe", or step-based orchestration.
workflow
Vercel Workflow SDK expert guidance. Use when building durable workflows, long-running tasks, API routes or agents that need pause/resume, retries, step-based execution, or crash-safe orchestration with Vercel Workflow.
verification
Full-story verification — infers what the user is building, then verifies the complete flow end-to-end: browser → API → data → response. Triggers on dev server start and 'why isn't this working' signals.
vercel-storage
Vercel storage expert guidance — Blob, Global Config (formerly Edge Config), and Marketplace storage (Neon Postgres, Upstash Redis). Use when choosing, configuring, or using data storage with Vercel applications.
vercel-services
Configure and troubleshoot Vercel Services for multiple frontends and backends in one project. Use when composing a polyglot or multi-service application on one Vercel deployment; defining the `services` key, service-targeted rewrites, or service bindings in `vercel.json`; or running all services with `vercel dev`.