Ir al contenido

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).

  1. 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; omita account_id para la cuenta por defecto):
Ventana 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. Conectar — por MCP, Claude Code es un comando (otros hosts: Conectar por MCP):
Ventana de terminal
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.

NormaMCPCLI
Orientarse primerolist_my_data → get_schemad2b workbooks list → d2b tables list --workbook WB
Confirmar el destino por nombre antes de crearlist_my_workspaces → create_workbookd2b workspaces list → d2b workbooks create --workspace-id …
Traer archivos por referencia (nunca por el propio contexto)ingest_url / request_upload → ingest_upload / import_cloud_filed2b upload FILE --workbook WB --wait (d2b jobs wait JOB_ID for long runs)
Hojas desordenadas: revisar la estructura antes de materializaringest_file (staged) → analyze_source → update_parse_spec → materialize_sourced2b upload --mode staged → d2b sources analyze → … materialize
Derivar con transforms, no con edición de filasadd_transform / list_transformsd2b transforms add; d2b pull writes them to transforms/
Ante un 409, releer y reaplicar (nunca sobrescribir a ciegas)releer edit_version con read_tablereleer edit_version con d2b tables rows NAME --workbook WB
Cortar una versión en los hitos para poder volvercommit_snapshot / restore_snapshot / undo_opd2b versions commit / d2b versions revert
Comprobar las cifras antes de informarlasreview_table / review_workbook (modo agente: sigue el trabajo con get_job)d2b review --workbook WB [--table NAME] [--agent]
Limpiardelete_workbookd2b workbooks delete WB

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.

Ventana 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 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 }}" 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")

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.

Ventana 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?

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.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 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).

  • 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 que upload --wait