Read · Section 01

Workbook Refresh — Fill Your Own Spreadsheet from the Filings, With Citations

Fills an existing comp sheet or monitoring book from as-filed XBRL — input cells only, an accession beside every figure, UNKNOWN where the filing is silent.

Nobody models in a blank sheet. The comp sheet, the monitoring book, the covenant tracker — they already exist, shaped the way your desk thinks, and the work each quarter is not designing them again. It is re-keying them: opening filing after filing, copying a revenue line, a margin, an EPS, and hoping nobody transposed a digit into a cell that four other cells depend on.

This recipe fills a workbook you already have. It reads the sheet's own shape, maps each column to the filing that answers it, writes the input cells, and leaves the accession number beside every figure it wrote — so the sheet can be checked by someone who wasn't there when it was filled.

Why this works with edgar.tools MCP

A spreadsheet refresh is the workflow where an ungrounded model does the most damage, because a wrong number in a cell does not look wrong. Prose hedges; a cell just sits there being confidently incorrect, and the formulas downstream launder it into a valuation.

  • financial_statements returns the as-filed XBRL line items with the source_accession of the filing that reported them — so every value written into a cell has a filing behind it, not a recollection.
  • company_filings confirms which filing you are reading before any number moves, which is what stops a fiscal-period mix-up.
  • data_quality rides on every response with as_of, freshness_lag_days, and is_stale — the signal that tells you the sheet you are about to refresh will still be behind after you refresh it.

The discipline the recipe adds is mostly about restraint: write only what a filing states, leave everything else visibly empty, and never let a derived column compute over a half-filled row.

How to use

Open the workbook and, with edgar.tools connected, ask:

Refresh this sheet from the latest annual filings. Cite every number, and flag anything you could not fill.

Works the same way on a sheet of your own or on one of the Excel templates. Outside a spreadsheet client, paste the header row and the ticker column and you will get the filled table back as markdown.

Prompt — paste this into Claude, ChatGPT, or Gemini

The framework (v1.0)

You are filling an analyst's existing workbook from SEC filings. The workbook is the specification: you do not redesign it, you populate it. Your output is judged on whether every number you wrote is traceable and whether every number you could not source was left visibly empty rather than guessed.

Non-negotiables

  • Read the sheet's shape before fetching anything. Identify the header row, the column that holds tickers or company names, and the period each column wants. Fetching first and mapping afterwards is how a value lands in the wrong column.
  • Write input cells only. Never overwrite a formula. If a target cell contains a formula, leave it alone, put the value in the nearest free cell or a note, and say so in your summary. A formula is somebody's modelling decision; a number is just a number.
  • Every figure names its filing. Put the accession in the sheet's source column if it has one; otherwise add a Sources row or a cell comment. A figure with no source is a figure the analyst cannot defend in a meeting.
  • If the filing does not state it, write `UNKNOWN`. Do not substitute a near-neighbour: a pre-tax margin is not an operating margin, and a segment total is not a consolidated one. Silently swapping metrics is the single most damaging thing you can do here, because the column header will still say the metric you did not use.
  • Never compute across a half-filled row. Leave derived cells to the workbook's own formulas. Excel reads a blank as zero, so a difference or a ratio you compute over missing inputs produces a confident number that means nothing.
  • Check the period labels. A column headed "FY2025" means different dates for different filers — fiscal years end in October as readily as December. Put the period-end date in the sheet, or in your summary, so two rows are never silently compared across different year-ends.
  • Surface staleness. If data_quality.is_stale is true, or the latest filing predates the period the sheet asks for, say so rather than filling the column as though it were current.

Workflow (ordered, mandatory)

Step 1 — Map the sheet

State back, in one short block: the sheet name, the header row, which column identifies the company, which rows are to be filled, and which columns you believe each map to. Name any column you cannot map — "column E 'Quality score' looks like a house metric; I will leave it" — and do not fetch anything for it. If the ticker column is empty, stop and ask; there is nothing to fill.

Step 2 — Confirm the filing, per company

Call company_filings({ company: "<ticker>", form: "10-K" }) (or 10-Q when the sheet wants quarters) and note the accession and filing date you are about to read. This is one cheap call that prevents the expensive error: reading a period the sheet did not ask for.

Skip it when the sheet only wants the latest annual figures and you will accept whatever financial_statements returns as latest — but then report the source_accession it used, so the period is still visible.

Step 3 — Pull the numbers

Call financial_statements({ company: "<ticker>", statement: "income_statement", period: "annual" }) — one call per company covers most comp sheets. Use balance_sheet or cash_flow only if the sheet's columns actually ask for them; each extra statement is another call and most comp sheets do not need them.

Read values off line_items by standard_concept where present (Revenue, Operating Income, EPS Diluted, Net Income), falling back to label when it is not. Take the value under the period-end date the sheet wants, not simply the first one.

Not every filer reports every line. Many report no consolidated operating-income line at all, going straight from costs to a pre-tax figure. When the concept you need is absent, that cell is UNKNOWN — say which line the filer reports instead, in your summary, and let the analyst decide whether it is an acceptable substitute. That decision is theirs, not yours.

Optional (+1 call per company). financial_snapshot returns pre-computed ratios if the sheet wants margins and returns you would otherwise derive. Use it when several ratio columns are wanted; skip it for two or three.

Step 4 — Write, then account for what you wrote

Fill the input cells. Then produce a short written account: how many cells you filled, how many you left UNKNOWN and why, any formula cell you declined to touch, any period mismatch between rows, and any staleness warning you saw.

Do not skip this because the sheet "looks right". The account is what makes the refresh checkable without re-reading every filing.

Required output

Write the cells, then reply in Markdown — no code block — using this shape:


WORKBOOK REFRESH — [sheet name] [N] companies · [period] · refreshed YYYY-MM-DD

Company[metric][metric][metric]Source
Form + date

Filled — [N] cells across [N] rows. Left empty — [cell refs]: [why, naming the line the filer does report if there is one]. Not touched — [any formula cells, and what you did instead]. Period note — [any row whose fiscal period differs from the others]. Freshness — [any is_stale or lag worth stating].


Stopping conditions

  • No ticker or company column → stop and ask. There is nothing to map.
  • A ticker resolves to candidates → list them and ask; do not pick.
  • The sheet asks for a metric no filing reports (analyst estimates, consensus, target prices, market data) → say so plainly. Consensus is not in EDGAR, and no amount of searching filings will produce it.
  • The whole column would be UNKNOWN → report that before writing anything; the column probably wants a metric the filings express under another name, and the analyst can tell you which.
Then askRun this on CAT.

What MCP-grounded refreshing adds

Workflow elementWithout MCPWith MCP
The figuresThe model's recollection, often the wrong fiscal yearAs-filed XBRL line items with the reporting filing's accession
Which filingUnstatedsource_accession on the response, confirmable via company_filings
Missing metricsQuietly substituted with a near-neighbourAbsent concept is visible, so the cell can be left UNKNOWN
Period alignmentAssumedPeriod-end dates are explicit per value, so an October year-end shows up
StalenessInvisibledata_quality.freshness_lag_days / is_stale on every response
AuditabilityA number in a cellA number in a cell with the filing beside it

Sample output structure

A refresh of a three-name machinery comp sheet — CAT, DE, PCAR — on the latest annual filings. The sample is worth reading for what it could not fill: two of the three filers report no consolidated operating-income line, and Deere's fiscal year ends in October while the other two end in December.

Sample LLM output — what this recipe returnsPreview

WORKBOOK REFRESH — Machinery comps 3 companies · latest FY (10-K) · refreshed 2026-08-30

CompanyRevenue ($M)Operating marginDiluted EPSPeriod endSource
Caterpillar67,58916.5%18.812025-12-3110-K, filed 2026-02-13
Deere & Co45,684UNKNOWN18.502025-10-3110-K, filed 2025-12-18
Paccar28,445UNKNOWN4.512025-12-3110-K, filed 2026-02-18

Filled — 10 cells across 3 rows.

Left empty — C3, C4 (operating margin, Deere and Paccar): neither filer reports a consolidated operating-income line. Deere goes from total costs to Income of Consolidated Group before Income Taxes ($6,257M); Paccar reports Income before income taxes ($2,677.4M). Both are pre-tax, both include items an operating margin excludes — a pre-tax margin here would be 13.7% and 9.4%, which is not the metric column C asks for. Substituting one for the other would make the column silently incomparable, so the decision is yours: keep the column operating-only and accept two blanks, or re-label it pre-tax and I will fill all three.

Not touched — no formula cells in the filled range; the EV/EBIT column is left to the sheet's own formulas.

Period note — Deere's fiscal year ends 2025-10-31, two months before the other two. The rows are one fiscal year each but not the same twelve months; a revenue-growth column across these three would compare different windows.

Freshness — Caterpillar's backing source carried is_stale: true (freshness_lag_days: 116) at capture. The FY2025 10-K is the latest annual filing for all three, but a newer 10-Q may exist for any of them.

Sample captured 2026-08-30 from live `financial_statements` and `company_filings` calls on the linked filings — refreshed when the figures age a fiscal year.

The shape holds for any sheet: what got filled, what did not and why, what was left alone, and what the periods actually mean. A refresh that reports two honest blanks is worth more than one that fills every cell and leaves you unable to say which numbers are the same metric.

  • 10-K Speedrun — when a refreshed row raises a question about a name you don't know well, the speedrun is the read behind the numbers.
  • Insider Activity Interpreter — for the monitoring book rather than the comp sheet: what the insiders did in the names you already hold.
  • Earnings Release Decoder — a filed 10-K lags the print; when a company has just reported, the release is where the newest quarter lives.