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.
claude mcp add d2b --transport http https://d2b.dev/mcp/ \
--header "Authorization: Bearer $D2B_PAT"
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.
from d2b import D2BClient
client = D2BClient(api_key="d2b_pat_...", base_url="https://d2b.dev")
wb = client.workbooks.create(title="monthly-sales")["id"]
client.sources.upload(wb, "sales_2026-06.xlsx", wait=True)
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"},
)
xlsx = client.export.tables(wb, tables=["product_sales"])
client.versions.commit(wb, "2026-06")
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.
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.
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.
mask / deny are enforced in the data layer — the same policy applies to SQL, export and MCP, with no side door. Audited.
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.
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.
transforms/ sheets/ charts/ data/ plus d2b.json (the merge-base hashes).
git diff / PR. Transforms the chat agent wrote show up in the same place.
Only what changed: re-run, PUT, 3-way merge. Refused when both sides moved (--force overrides). The git sha becomes a named version.
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 → PR
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.
1 op = one write-side data operation (row writes, transform runs, commits, version operations). Reads are currently not billed.
Mint a PAT and run one claude mcp add. Five minutes with the CLI or an SDK.