Aller au contenu

Utiliser D2B depuis un agent de code

D2B offre deux voies aux agents. MCP (tool calling : Claude Code / Claude Desktop / Cursor / VS Code, etc.) et la CLI (d2b : agents pilotés par le shell, synchronisation git, traitements par lots). Les deux exposent la même surface : sortie JSON, erreurs avec suggested_fix, clé d’idempotence sur chaque mutation, aucune invite interactive.

Les règles d’usage viennent du serveur. Quand un hôte se connecte par MCP, la réponse d’initialisation porte instructions — quel outil, dans quel ordre — et le même texte se lit comme ressource d2b://guide. Vous ne collez pas une longue procédure dans le dépôt ; vous collez la connexion et le choix de la voie (ci-dessous).

  1. Émettre un PAT à privilèges minimaux — pour un agent, un jeton limité à un workbook avec quota (pour déléguer tout un workspace, utilisez "resource": "workspace:<WS_ID>"; la création y est aussi épinglée. Un jeton appartient toujours à un seul compte ; omettez account_id pour le compte par défaut) :
Fenêtre de terminal
curl -X POST $BASE/api/v1/me/tokens -H "Authorization: Bearer $JWT" \
-d '{"name": "agent", "scopes": ["workbooks:read", "workbooks:write"],
"resource": "workbook:<WB_ID>", "rate_limit_per_minute": 60}'
  1. Se connecter — par MCP, Claude Code tient en une commande (autres hôtes : Se connecter via MCP) :
Fenêtre de terminal
claude mcp add d2b --transport http https://d2b.dev/mcp/ --header "Authorization: Bearer $PAT"

d2b init écrit la partie dépôt — il ajoute la section AGENTS.md ci-dessous et affiche l’entrée MCP canonique que tout hôte peut reprendre. Les hôtes connus fusionnent directement dans leur fichier avec --host claude-code|cursor|vscode|codex|windsurf|claude-desktop ; tout autre via --config PATH (JSON ou TOML). Le jeton reste une référence à une variable d’environnement, jamais écrit dans un fichier.

Pour la CLI, exportez D2B_API_KEY / D2B_BASE_URL (Claude Code ne lit pas .env de lui-même) et installez avec pipx install d2b-sdk ou uvx --from d2b-sdk d2b (uv add d2b-sdk + uv run d2b en dépendance de projet).

Le snippet du dépôt (connexion et choix seulement)

Section intitulée « Le snippet du dépôt (connexion et choix seulement) »

Les règles viennent du serveur : ne recopiez pas la procédure ici ; une copie ne suit pas les nouveaux outils et se périme.

## D2B
- Le travail sur les données passe par D2B. Le serveur MCP `d2b` est connecté — suivre d'abord les règles de `d2b://guide`.
- Pour la gestion git (`d2b pull` / `d2b push`) et les lots, la CLI `uvx --from d2b-sdk d2b ...` (sortie JSON ; auth via env D2B_API_KEY / D2B_BASE_URL).
- Destinations, import de fichiers et versions sont dans le guide. En cas de doute, demander à l'humain.

Les règles qu’un agent suit (fournies par le serveur)

Section intitulée « Les règles qu’un agent suit (fournies par le serveur) »

L’essentiel de instructions / d2b://guide, avec l’équivalent CLI. Les règles ne dépendent pas de la surface ; seuls les noms d’outils changent.

RègleMCPCLI
S’orienter d’abordlist_my_data → get_schemad2b workbooks list → d2b tables list --workbook WB
Confirmer la destination par son nom avant de créerlist_my_workspaces → create_workbookd2b workspaces list → d2b workbooks create --workspace-id …
Importer les fichiers par référence (jamais via son propre contexte)ingest_url / request_upload → ingest_upload / import_cloud_filed2b upload FILE --workbook WB --wait (d2b jobs wait JOB_ID for long runs)
Feuilles désordonnées : inspecter la structure avant de matérialiseringest_file (staged) → analyze_source → update_parse_spec → materialize_sourced2b upload --mode staged → d2b sources analyze → … materialize
Dériver par transforms, pas par édition de lignesadd_transform / list_transformsd2b transforms add; d2b pull writes them to transforms/
Sur 409, relire et réappliquer (jamais écraser à l’aveugle)relire edit_version avec read_tablerelire edit_version avec d2b tables rows NAME --workbook WB
Poser une version aux jalons pour pouvoir revenircommit_snapshot / restore_snapshot / undo_opd2b versions commit / d2b versions revert
Vérifier les chiffres avant de les rapporterreview_table / review_workbook (mode agent : suivre la tâche avec get_job)d2b review --workbook WB [--table NAME] [--agent]
Nettoyerdelete_workbookd2b workbooks delete WB

d2b pull --workbook $WB écrit transforms/ sheets/ charts/ + d2b.json (--data TABLE ajoute le CSV d’une table de base). Éditer → vérifier avec d2b push --dry-run → d2b push --commit $(git rev-parse --short HEAD) → committer d2b.json. push n’envoie que les changements (transforms réexécutés, data fusionnée à 3 voies) ; en cas de refus, pull, fusion, puis push. charts/ est en lecture seule. Détails : Gérer un workbook dans git.

Édition fidèle à l’original (revise = corriger uniquement les lignes visées et rendre l’Excel d’origine)

Section intitulée « Édition fidèle à l’original (revise = corriger uniquement les lignes visées et rendre l’Excel d’origine) »

« Garder l’Excel d’origine intact, ne corriger que les lignes visées et produire un nouveau fichier » tient en un seul appel revise (qui replie en interne analyze → materialize → transform → réécriture). Le calcul reste un transform SQL côté serveur (lineage récupérable), et styles, charts, autres feuilles et formules hors plage sont conservés tels quels.

Fenêtre de terminal
d2b sources revise equipment.xlsx --workbook $WB \
--transform-name merge_tokyo_sites --range A3:N8 --sheet Summary \
--sql-file merge.sql -o output.xlsx

merge.sql est la vue {{ artifact_name }} ({{ src }} est lié à la table de la plage visée). Comment bien écrire une agrégation qui replie des lignes :

  • Les colonnes additives (unités, occurrences, montants) : SUM.
  • Les ratios (taux d’utilisation, taux d’achèvement) ne se moyennent pas. Recalculez après sommation : SUM(分子) / NULLIF(SUM(分母), 0).
  • Les moyennes (MTBF, MTTR, etc.) : moyenne pondérée, pas moyenne simple : SUM(値 * 重み) / NULLIF(SUM(重み), 0) (le poids est une colonne qui a du sens — nombre d’unités, d’occurrences…).
  • Les catégories (une note, par exemple) : une valeur représentative : arg_max(rating, units_managed).
  • Pour préserver la position des lignes, mettez MIN("__d2b_row_id") dans le SELECT (la ligne agrégée prend la position du premier membre, les lignes libérées sont vidées sur place ; les autres lignes ne bougent pas).
CREATE OR REPLACE VIEW "{{ artifact_name }}" AS
SELECT
CASE WHEN site IN ('Tokyo Site 1','Tokyo Site 2') THEN 'Tokyo' ELSE site END AS site,
SUM(units_managed) AS units_managed,
SUM(units_active) * 1.0 / NULLIF(SUM(units_managed), 0) AS utilization,
SUM("MTBF(h)" * units_managed) / NULLIF(SUM(units_managed), 0) AS "MTBF(h)",
arg_max(rating, units_managed) AS rating,
MIN("__d2b_row_id") AS "__d2b_row_id"
FROM {{ src }}
GROUP BY 1
ORDER BY MIN("__d2b_row_id")

Si la plage contient des lignes de total ou de sous-total (=SUM(...)), ces cellules de formule ne sont pas écrasées mais conservées (Excel recalcule). Une édition qui ajouterait des lignes au-delà de la plage du template casserait la géométrie : elle est refusée (409). Même voie via revise_source en MCP et sources.revise(...) en SDK.

Livrer des constantes en « formules vivantes » (formula column)

Section intitulée « Livrer des constantes en « formules vivantes » (formula column) »

Une colonne posée en constantes (ex. : un taux d’utilisation) peut être remplacée à l’export par une formule Excel ligne par ligne. Les valeurs ne sont pas touchées : c’est une « projection de livraison » qui ajoute seulement la manière de re-dériver la valeur dans le .xlsx livré. Les références s’écrivent avec des placeholders {列名} (pas d’adresses de cellules A1 — ancrées à l’identité pour ne pas se décaler au tri ou au filtre). Le serveur résout les coordonnées à l’export.

Fenêtre de terminal
# Deliver utilization = units_active / units_total as a live per-row formula
d2b tables set-formula equipment utilization "{units_active} / {units_total}" --workbook <WB>
out = client.tables.set_formula(wb, "equipment", "utilization", "{units_active} / {units_total}")
out["verification"] # {checked, rows, matches, mismatches} — does it reproduce the current constants?

Les valeurs faisant foi, l’écriture renvoie un rapport de vérification (la formule reproduit-elle les valeurs actuelles de la colonne, à la tolérance près ?). Le remplacement « constantes → formule » peut donc être vérifié avant la livraison. En MCP : set_formula_column / list_formula_columns / clear_formula_column. S’applique aujourd’hui à l’export xlsx (combinable avec les transforms SQL {{ ... }} et la réécriture fidèle à l’original de revise). Les fonctions (SUM/IF, etc.) ne reçoivent qu’une vérification structurelle, sans vérification numérique. underline n’est pas pris en charge.

Références inter-feuilles : {table!column} référence la plage de données entière d’une colonne d’une autre table (à l’export de plusieurs tables dans un seul fichier, compilée en référence absolue vers la feuille portant cette colonne : 'rates'!$B$2:$B$N). À envelopper dans une fonction d’agrégation :

# Revenue share = this row's amount ÷ the sum of rates.weight
client.tables.set_formula(wb, "sales", "share", "{amount} / SUM({rates!weight})")
client.export.tables(wb, tables=["sales", "rates"], format="xlsx")
# → each share row compiles to =B2/SUM('rates'!$B$2:$B$N) (same-table {amount} relative, cross-refs absolute)

Si la table référencée n’est pas incluse dans le même export, la formule ne peut pas être résolue et retombe sur la valeur. Une jointure par clé façon VLOOKUP s’exprime non pas en formule mais par un transform JOIN (add_transform) (le lineage est conservé).

  • Dans les sandbox cloud (Codex, etc.), les restrictions d’egress peuvent demander d’autoriser explicitement l’accès réseau à l’API
  • Pour les agents au timeout Bash court, le duo « upload asynchrone → jobs wait » est plus sûr qu’upload --wait