Usar D2B desde un agente de código
D2B ofrece dos vías a los agentes. MCP (tool calling: Claude Code / Claude Desktop / Cursor / VS Code, etc.) y la CLI (d2b: agentes por shell, sincronización con git, trabajo por lotes). Ambas exponen la misma superficie: salida JSON, errores con suggested_fix, clave de idempotencia en cada mutación, sin prompts interactivos.
Las normas de uso las entrega el servidor. Al conectar por MCP, la respuesta de inicialización lleva instructions — qué herramienta y en qué orden — y el mismo texto se lee como recurso d2b://guide. No pegue un procedimiento largo en el repositorio; pegue solo la conexión y la elección de vía (abajo).
Configuración (lo que hace el humano)
Sección titulada «Configuración (lo que hace el humano)»- Emitir un PAT de mínimo privilegio — para un agente, un token acotado a un workbook con límite de tasa (para delegar un workspace entero use
"resource": "workspace:<WS_ID>"; la creación también queda fijada ahí. Un token pertenece siempre a una cuenta; omitaaccount_idpara la cuenta por defecto):
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}'- Conectar — por MCP, Claude Code es un comando (otros hosts: Conectar por MCP):
claude mcp add d2b --transport http https://d2b.dev/mcp/ --header "Authorization: Bearer $PAT"d2b init escribe la parte del repositorio: añade la sección de AGENTS.md de abajo e imprime la entrada MCP canónica que cualquier host puede usar. Los hosts conocidos se fusionan directamente en su archivo con --host claude-code|cursor|vscode|codex|windsurf|claude-desktop; cualquier otro, con --config PATH (JSON o TOML). El token queda como referencia a una variable de entorno, nunca en un archivo.
Para la CLI, exporte D2B_API_KEY / D2B_BASE_URL (Claude Code no lee .env por sí solo) e instale con pipx install d2b-sdk o uvx --from d2b-sdk d2b (uv add d2b-sdk + uv run d2b como dependencia del proyecto).
El snippet del repositorio (solo conexión y elección)
Sección titulada «El snippet del repositorio (solo conexión y elección)»Las normas vienen del servidor: no copie el procedimiento aquí; una copia no sigue las herramientas nuevas y queda obsoleta.
## D2B- El trabajo con datos pasa por D2B. El servidor MCP `d2b` está conectado: seguir primero las normas de `d2b://guide`.- Para gestión con git (`d2b pull` / `d2b push`) y trabajo por lotes, la CLI `uvx --from d2b-sdk d2b ...` (salida JSON; auth desde env D2B_API_KEY / D2B_BASE_URL).- Destinos, cómo traer archivos y versiones están en la guía. Ante la duda, preguntar al humano.Las normas que sigue un agente (entregadas por el servidor)
Sección titulada «Las normas que sigue un agente (entregadas por el servidor)»Lo esencial de instructions / d2b://guide, con el equivalente en CLI. Las normas no dependen de la superficie; solo cambian los nombres de las herramientas.
| Norma | MCP | CLI |
|---|---|---|
| Orientarse primero | list_my_data → get_schema | d2b workbooks list → d2b tables list --workbook WB |
| Confirmar el destino por nombre antes de crear | list_my_workspaces → create_workbook | d2b workspaces list → d2b workbooks create --workspace-id … |
| Traer archivos por referencia (nunca por el propio contexto) | ingest_url / request_upload → ingest_upload / import_cloud_file | d2b upload FILE --workbook WB --wait (d2b jobs wait JOB_ID for long runs) |
| Hojas desordenadas: revisar la estructura antes de materializar | ingest_file (staged) → analyze_source → update_parse_spec → materialize_source | d2b upload --mode staged → d2b sources analyze → … materialize |
| Derivar con transforms, no con edición de filas | add_transform / list_transforms | d2b transforms add; d2b pull writes them to transforms/ |
| Ante un 409, releer y reaplicar (nunca sobrescribir a ciegas) | releer edit_version con read_table | releer edit_version con d2b tables rows NAME --workbook WB |
| Cortar una versión en los hitos para poder volver | commit_snapshot / restore_snapshot / undo_op | d2b versions commit / d2b versions revert |
| Comprobar las cifras antes de informarlas | review_table / review_workbook (modo agente: sigue el trabajo con get_job) | d2b review --workbook WB [--table NAME] [--agent] |
| Limpiar | delete_workbook | d2b workbooks delete WB |
Gestionar un workbook en git (CLI)
Sección titulada «Gestionar un workbook en git (CLI)»d2b pull --workbook $WB escribe transforms/ sheets/ charts/ + d2b.json (--data TABLE añade el CSV de una tabla base). Editar → comprobar con d2b push --dry-run → d2b push --commit $(git rev-parse --short HEAD) → confirmar d2b.json. push envía solo lo cambiado (los transforms se reejecutan, data se fusiona a 3 vías); si se rechaza, pull, fusionar y volver a push. charts/ es de solo lectura. Detalles: Gestionar un workbook en git.
Edición que respeta el original (revise = corregir solo las filas afectadas y devolver el Excel original)
Sección titulada «Edición que respeta el original (revise = corregir solo las filas afectadas y devolver el Excel original)»“Mantener el Excel original entero y producir un archivo nuevo con solo las filas afectadas corregidas” se logra con una sola llamada a revise (que internamente pliega analyze → materialize → transform → escritura de vuelta). El cálculo queda como transform SQL del lado del servidor (con lineage consultable), y los estilos, los charts, las demás hojas y las fórmulas fuera del rango se conservan tal cual.
d2b sources revise equipment.xlsx --workbook $WB \ --transform-name merge_tokyo_sites --range A3:N8 --sheet Summary \ --sql-file merge.sql -o output.xlsxmerge.sql es la vista {{ artifact_name }} (a {{ src }} se liga la tabla del rango objetivo). Cómo escribir bien una agregación que colapsa filas:
- Las columnas aditivas (unidades, conteos, importes) van con
SUM. - Los ratios (tasa de operación, tasa de completitud) no se promedian. Se recalculan después de sumar:
SUM(分子) / NULLIF(SUM(分母), 0). - Los promedios (MTBF, MTTR, etc.) usan promedio ponderado, no promedio simple:
SUM(値 * 重み) / NULLIF(SUM(重み), 0)(el peso es una columna con significado, como unidades o conteos). - Las categorías (una calificación, por ejemplo) usan un valor representativo:
arg_max(rating, units_managed). - Para conservar la posición de las filas, incluye
MIN("__d2b_row_id")en el SELECT (la fila combinada ocupa la posición del primer miembro, las filas que quedan libres se vacían en su lugar y las demás no se mueven).
CREATE OR REPLACE VIEW "{{ artifact_name }}" ASSELECT 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 1ORDER BY MIN("__d2b_row_id")Aunque el rango contenga filas de totales/subtotales (=SUM(...)), esas celdas de fórmula no se sobrescriben: se preservan (Excel las recalcula). Una edición que agregue más filas que el rango de la plantilla rompe la geometría y se rechaza (409). En MCP la misma vía es revise_source; en el SDK, sources.revise(...).
Entregar constantes como “fórmulas vivas” (formula column)
Sección titulada «Entregar constantes como “fórmulas vivas” (formula column)»Una columna de constantes (por ejemplo, la tasa de operación) puede reemplazarse al exportar por fórmulas de Excel por fila. Es una “proyección de entrega” que no toca los valores en sí: solo adjunta la forma de re-derivarlos en el .xlsx entregado. Las referencias se escriben con placeholders {列名} (nada de direcciones de celda A1 — quedan ancladas a la identidad para que no se corran con ordenamientos o filtros). El servidor resuelve las coordenadas al exportar.
# Deliver utilization = units_active / units_total as a live per-row formulad2b 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?Como los valores son lo canónico, la escritura devuelve un reporte de verificación (si la fórmula reproduce los valores actuales de la columna dentro de la tolerancia). Puedes confirmar el “reemplazo de constantes por fórmulas” antes de entregar. En MCP: set_formula_column / list_formula_columns / clear_formula_column. Por ahora aplica al export a xlsx (combinable con los transforms SQL de {{ ... }} y con la escritura de vuelta de revise que respeta el original). Las funciones (SUM/IF, etc.) solo pasan por verificación estructural; la numérica se omite. underline no está soportado.
Referencias entre hojas: con {table!column} puedes referenciar el rango completo de datos de la columna de otra tabla (al exportar varias tablas a un solo archivo, se compila a la referencia absoluta de la hoja donde está esa columna: 'rates'!$B$2:$B$N). Se usa envuelta en una función de agregación:
# Revenue share = this row's amount ÷ the sum of rates.weightclient.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 tabla referenciada no está incluida en el mismo export, esa fórmula no puede resolverse y hace fallback al valor. Los joins por clave al estilo VLOOKUP no se expresan como fórmula sino como transform de JOIN (add_transform) (así queda lineage).
Restricciones y advertencias
Sección titulada «Restricciones y advertencias»- En sandboxes en la nube (Codex, etc.), las restricciones de egress pueden exigir configurar permisos para alcanzar la API
- En agentes con timeouts de Bash cortos, el flujo en 2 pasos “upload asíncrono →
jobs wait” es más seguro queupload --wait