Spreadsheets for AI Agents
D2B for Agents — API / MCP / CLI / SDK
Spreadsheets for AI Agents
Take spreadsheets made for people in at the door, hand your agent typed, row-identified, versioned, governed tables, and return the result to humans as Excel in its original formatting. Not just answers — every number traceable to where it came from.
Free, no card requireddiff, lineage and undo over MCPLeast-privilege PAT scopesIdempotency-Key on every mutationproblem+json with suggested\_fix
install
MCPCLIPythonTypeScriptcurl
bashCopy
claude mcp add d2b --transport http https://d2b.dev/mcp/ \
--header "Authorization: Bearer $D2B_PAT"Codex / Cursor / VS Code / Claude Desktop → docs.d2b.dev/ja/mcp
01
Ingest → transform → deliver → version
Four steps
Letting an LLM write and run Python in a sandbox gets you an answer, but not how it got there — you can't trace it or run it again. D2B records the same work as transforms with lineage, so a changed input recomputes and every version can be restored.
PythonTypeScript
pythonCopy
from d2b import D2BClientclient = D2BClient(api_key="d2b_pat_...", base_url="https://d2b.dev")
wb = client.workbooks.create(title="monthly-sales")["id"]
1) a spreadsheet made for people in → typed tables (raw kept, lineage from day one)
client.sources.upload(wb, "sales_2026-06.xlsx", wait=True)2) logic as a transform — {{ arg }} bindings keep lineage
client.transforms.create(
wb, name="agg/monthly", kind="sql", artifact_name="product_sales",
template='CREATE TABLE "{{ artifact_name }}" AS '
'SELECT product, sum(amount) AS revenue FROM "{{ src }}" GROUP BY 1',
args={"src": "sales"},
)3) back to humans as Excel, 4) a named, revertible version
xlsx = client.export.tables(wb, tables=["product_sales"])
client.versions.commit(wb, "2026-06")1upload takes the Excel as it is — before any cleanup — and lands typed tables in two stages: a faithful raw copy, then the LLM-structured table. The raw copy is kept after structuring, so the original values are always there to return to.
2Derived tables are transforms, not row edits. {{ arg }} bindings keep lineage, so a changed input recomputes.
3export is one sheet per table as xlsx — or the original file with only the value cells replaced (styles, formulas and other sheets untouched).
4version.commit pins an immutable label. Revert restores derived tables through snapshots and row edits through the edit log.
02
Types, history, permissions, delivery — built into every table.
Primitives
A foundation that survives an agent's mistakes: concurrent writes are caught, any number can be traced and rolled back, permissions hold at the data layer, and results go back to people as Excel.
Lineage and versions
Transforms are stored content-addressed; the DAG is queryable upstream and down. Snapshots, named versions, an op log and undo — plus a diff between any two versions: unified diffs of the transforms, rows touched, and every artifact the change reaches. An agent can find out why a number moved, fix it, and compare.
Typed, row-identified, optimistically locked
Every table is typed with row ids; writes require expected\_version, so concurrent edits are never silently overwritten. A per-table row JSON Schema is available at runtime for constrained decoding.
Governance (column tags × roles)
mask / deny are enforced in the data layer — the same policy applies to SQL, export and MCP, with no side door. Audited.
Delivery to humans
xlsx / csv, write-back into the original workbook's formatting, live per-row Excel formulas, export = branch → re-import = 3-way merge. Round trips on Excel users' own terms.
Plugs into:Claude CodeCodexClaude DesktopCursorVS CodeLangGraphOpenAI Agents SDKn8n / DifyGitHub Actions
03
Your workbook, in your git.
Workbook as code
Pull transforms (SQL / Python), sheets, charts and opted-in base tables as CSV into a repository, review them in a pull request, push them back. Reviewing the SQL an AI wrote before it counts becomes an ordinary workflow.
01 · pull
transforms/ sheets/ charts/ data/ plus d2b.json (the merge-base hashes).
02 · review
git diff / PR. Transforms the chat agent wrote show up in the same place.
03 · push
Only what changed: re-run, PUT, 3-way merge. Refused when both sides moved (--force overrides). The git sha becomes a named version.
bashCopy
d2b pull --workbook WB --data customers # transforms/ sheets/ charts/ data/ + d2b.json
git add -A && git commit -m "pull from D2B"
d2b push --dry-run
d2b push --commit "$(git rev-parse --short HEAD)"
d2b github-workflow > .github/workflows/d2b.yml # push on merge, scheduled pull → PR04
Pay for data operations and storage.
Pricing
Billing is metered in ops (data operations) and GB-months. Calls from your own agent with your own LLM carry no LLM charge — LLM usage is added only when you use D2B's built-in agent. Capability is identical on every plan.
Free
$0
No credit card
- 100K ops during the trial
- Evaluation, hackathons, side projects
- 14-day trial — continue seamlessly on PAYG
- 3 workspaces
- 10M ops + 20 GB / month included
- Overage $5 / 1M ops · $0.15 / GB-month
- 10 workspaces
- Email support
- 100M ops + 200 GB / month included
- Overage $4 / 1M ops · $0.12 / GB-month
- Unlimited workspaces
- Invoicing, priority support
- VPC, SSO / SAML, residency
- Sub-accounts
- Dedicated support
- $6 / 1M ops · $0.18 / GB-month
- Up to 3 workspaces
- Continue after the trial with just a card on file (never pauses)
Solo
$29 / mo
Production for individuals and small teams
Pro
$199 / mo
Products embedding D2B at volume
Enterprise
Custom
OEM / large organisations
Pay as you go$0 + usageCard on file, no monthly fee
1 op = one write-side data operation (row writes, transform runs, commits, version operations). Reads are currently not billed.
One minute to your first call over MCP.
Mint a PAT and run one claude mcp add. Five minutes with the CLI or an SDK.
