dbt-plan
Resumen
Descripción del creador (original en inglés)
Predicts the DDL a dbt change will execute, before you run it. Reads files, not the warehouse.
Los tres pilares de PopNx MCP
Estos tres nunca se combinan en una sola puntuación: las opiniones, las mediciones y la popularidad son cosas distintas.
- Opinión de usuariosiAún no hay reseñasLas reseñas se abrirán junto con las cuentas en una etapa posterior
- Nuestras revisiones básicasi1 de 1 superadasRevisado con información pública; el código aún no se ha escaneado
- UsoiMuy nuevo↓ 271/sem · ★ –
Qué puedes hacer con él
Todavía no escribimos un resumen sencillo para este. Abajo están los datos que leímos del registro.
- Conexión: Se ejecuta en tu computadora
- Transporte: stdio
- Categoría: Bases de datos y conjuntos de datos
Instalación
Elige la app de IA que usas y copia la configuración.
Antes de instalar
- Revisiones básicas: 1 de 1 superadas
- Se ejecuta en tu computadora con los permisos de tu usuario (archivos, red, apps).
- El registro no indica ninguna clave que completar.
Necesitas
- PyPIuv de Python instalado (para el comando uvx)
¿Qué app usas?
Elige tu app arriba. La recordamos, así que la próxima vez el botón dirá “Instalar en …”.
Abre Claude Desktop → Settings → Developer → Edit Config y pega esto en claude_desktop_config.json
{
"mcpServers": {
"dbt-plan": {
"command": "uvx",
"args": [
"dbt-plan"
]
}
}
}Ejecuta esto en tu terminal
claude mcp add dbt-plan -- uvx dbt-planO copia la configuración tú
Pégalo en .cursor/mcp.json de tu proyecto, o en ~/.cursor/mcp.json
{
"mcpServers": {
"dbt-plan": {
"command": "uvx",
"args": [
"dbt-plan"
]
}
}
}Tu navegador te pide permiso para abrir la app; luego la app muestra la configuración y te pide confirmar. Los valores de las claves quedan vacíos para que los completes tú.
O copia la configuración tú
Pégalo en .vscode/mcp.json de tu proyecto
{
"servers": {
"dbt-plan": {
"type": "stdio",
"command": "uvx",
"args": [
"dbt-plan"
]
}
}
}Tu navegador te pide permiso para abrir la app; luego la app muestra la configuración y te pide confirmar. Los valores de las claves quedan vacíos para que los completes tú.
Este se ejecuta en tu computadora, y ChatGPT solo puede conectarse a servidores en internet. Elige otra app.
Tu elección se guarda en una cookie en este dispositivo; no necesitas cuenta.
Esta configuración se genera a partir de la ficha del creador en el registro. Si el README dice otra cosa, sigue el README.
Qué puede hacer
Se ejecuta en tu computadora; la lista de herramientas aparece en tu app de IA después de instalarlo.
Revisiones básicasi
Revisamos información que cualquiera puede ver; no hemos leído el código. Las revisiones que no aplican no se cuentan. · Revisado el 10 nov 2026
- ✓ Superada
El creador coincide con el repo
El nombre en el registro se verificó con la cuenta de GitHub PresentJay, dueña del repo
- … Aún sin revisar
Sigue en mantenimiento
Todavía no hemos leído este repo en GitHub
- … Aún sin revisar
Tiene licencia
Todavía no hemos leído este repo en GitHub
- – No aplica
El endpoint responde
Este se ejecuta en tu computadora; no hay endpoint en internet
- – No aplica
Inicio de sesión con OAuth
Se ejecuta en tu computadora y usa ajustes locales en su lugar
- … Aún sin revisar
Sin instrucciones ocultas en las descripciones de herramientas
Se ejecuta en tu computadora; solo podemos leer listas de herramientas de endpoints en internet
Comparado con otros en Bases de datos y conjuntos de datosi
- Más estrellas que el 0% de los otros 1159 servidores de esta categoría
- Publicado en el registro más recientemente que el 83% de los otros 1159 servidores de esta categoría
- Revisiones básicas iguales o mejores que el 100% de los otros 1159 servidores de esta categoría
Comparado con todos los servidores activos de esta categoría en el registro. Las estrellas solo cuentan cuando quien lo publica es dueño del repo.
Preguntas frecuentes
¿Es seguro dbt-plan?
Superó 1 de 1 revisiones básicas aplicables. No hemos leído el código. Antes de agregar una clave o un token, revisa qué acceso pide el servidor y usa una clave que tenga solo los permisos que necesitas.
¿Qué claves o códigos necesita?
El registro no indica ninguna clave obligatoria, aunque algunos servidores te piden iniciar sesión la primera vez que los usas.
¿Se ejecuta en mi computadora o en la nube?
Se ejecuta en tu computadora. Tu app de IA lo inicia cuando hace falta, y los datos no pasan por los servidores del creador (a menos que el propio servidor llame a un servicio en línea).
¿Sigue en mantenimiento?
El repo de GitHub cambió por última vez –, y la última versión (0.18.6) llegó al registro hace 7 días.
¿Qué apps pueden usarlo?
Las apps compatibles con MCP, como Claude Desktop, Claude Code, Cursor y VS Code. También necesitas Python (uv) en tu computadora.
¿Qué puedo usar en su lugar?
En la misma categoría: Supabase, MongoDB MCP Server, Elasticsearch MCP Server
Alternativas
Servidores de la misma categoría hechos por otros creadores, ordenados por estrellas.
Cómo leer una tarjeta:↓ Descargas por semanai★ Estrellas de GitHubiTres pilares: reseñas · revisiones · usoiActualizado = fecha en que se publicó la última versión en el registroi
README del creador
Abrir el README
Copiado tal cual del repo del creador. PopNx MCP no lo ha revisado ni lo respalda. Se quitaron HTML, imágenes y scripts. Los enlaces llevan fuera de este sitio.
dbt-plan
Static analysis tool that warns about risky DDL changes before dbt run.
Like terraform plan for dbt, and used the same way: you run it before the thing that changes your warehouse, not only in CI afterwards.
Analyzes compiled SQL files from warehouses including Snowflake, BigQuery, Redshift, Postgres and DuckDB through one code path. SQL dialect support varies; see analysis limits.
What It Looks Like
$ dbt-plan check
dbt-plan -- 4 model(s) changed dialect: snowflake (default; adapter: unknown) baseline: unknown revision, unknown snapshot time
Review required: DESTRUCTIVE (before policy; exit policy is separate) Next: Review the finding evidence and affected source files before running dbt. Next: Resolve the unreadable downstream SQL and recompile before rerunning check.
DESTRUCTIVE int_order_enriched (incremental, sync_all_columns) ADD COLUMN billing_method ADD COLUMN shipping_city DROP COLUMN billing_info DROP COLUMN shipping_info Downstream: dim_customers, fct_daily_sales (2 model(s))
> BROKEN_REF fct_daily_sales: reads dropped column(s): shipping_info
SAFE dim_customers (table) CREATE OR REPLACE TABLE
SAFE dim_publishers (table) CREATE OR REPLACE TABLE
SAFE fct_daily_sales (incremental, append_new_columns) ADD COLUMN total_sales
Causal explanations (before policy)
- DESTRUCTIVE cascade.broken_ref: source model.sample.int_order_enriched; affected model.sample.fct_daily_sales reads dropped column(s): shipping_info Source change: added billing_method, shipping_city; removed billing_info, shipping_info Affected/evidence columns: (not recorded); evidence: legacy_cascade / unknown / provenance_unavailable; raw risk: broken_ref; waiver eligible: false Review: provenance_unavailable Source config: materialized=incremental; on_schema_change=None Affected config: materialized=incremental; on_schema_change=None Step: model.sample.int_order_enriched -> model.sample.fct_daily_sales; exact direct compiled read; root attribution not established; removed shipping_info Config: materialized=incremental; on_schema_change=None
- DESTRUCTIVE ddl.drop_column: source model.sample.int_order_enriched; affected model.sample.int_order_enriched DROP COLUMN; column: billing_info Source change: added billing_method, shipping_city; removed billing_info, shipping_info Affected/evidence columns: billing_info, billing_method, customer_id, order_date, order_id, revenue, shipping_city, shipping_info; 1 columns omitted; evidence: compiled_sql / exact / column_diff_checked; raw risk: destructive; waiver eligible: true Compiled SQL (not a source/Jinja line): target/compiled/sample/models/int_order_enriched.sql Source config: materialized=incremental; on_schema_change=None Affected config: materialized=incremental; on_schema_change=None
- DESTRUCTIVE ddl.add_column: source model.sample.int_order_enriched; affected model.sample.int_order_enriched ADD COLUMN; column: billing_method Source change: added billing_method, shipping_city; removed billing_info, shipping_info Affected/evidence columns: billing_info, billing_method, customer_id, order_date, order_id, revenue, shipping_city, shipping_info; 1 columns omitted; evidence: compiled_sql / exact / column_diff_checked; raw risk: destructive; waiver eligible: true Compiled SQL (not a source/Jinja line): target/compiled/sample/models/int_order_enriched.sql Source config: materialized=incremental; on_schema_change=None Affected config: materialized=incremental; on_schema_change=None
- DESTRUCTIVE ddl.add_column: source model.sample.int_order_enriched; affected model.sample.int_order_enriched ADD COLUMN; column: shipping_city Source change: added billing_method, shipping_city; removed billing_info, shipping_info Affected/evidence columns: billing_info, billing_method, customer_id, order_date, order_id, revenue, shipping_city, shipping_info; 1 columns omitted; evidence: compiled_sql / exact / column_diff_checked; raw risk: destructive; waiver eligible: true Compiled SQL (not a source/Jinja line): target/compiled/sample/models/int_order_enriched.sql Source config: materialized=incremental; on_schema_change=None Affected config: materialized=incremental; on_schema_change=None
- DESTRUCTIVE ddl.drop_column: source model.sample.int_order_enriched; affected model.sample.int_order_enriched DROP COLUMN; column: shipping_info Source change: added billing_method, shipping_city; removed billing_info, shipping_info Affected/evidence columns: billing_info, billing_method, customer_id, order_date, order_id, revenue, shipping_city, shipping_info; 1 columns omitted; evidence: compiled_sql / exact / column_diff_checked; raw risk: destructive; waiver eligible: true Compiled SQL (not a source/Jinja line): target/compiled/sample/models/int_order_enriched.sql Source config: materialized=incremental; on_schema_change=None Affected config: materialized=incremental; on_schema_change=None
- WARNING input.refusal: source model.sample.dim_customers; affected model.sample.dim_customers Unresolved compiled SQL read from int_order_enriched while checking int_order_enriched; affected columns: billing_info, shipping_info Source change: not recorded Affected/evidence columns: (not recorded); evidence: input / unknown / read_unresolved; raw risk: warning; waiver eligible: false Review: read_unresolved Source config: materialized=table; on_schema_change=None Affected config: materialized=table; on_schema_change=None
- SAFE ddl.replace_table: source model.sample.dim_customers; affected model.sample.dim_customers CREATE OR REPLACE TABLE Source change: not recorded Affected/evidence columns: country, created_at, customer_id, customer_tier; evidence: compiled_sql / exact / column_diff_checked; raw risk: safe; waiver eligible: true Compiled SQL (not a source/Jinja line): target/compiled/sample/models/dim_customers.sql Source config: materialized=table; on_schema_change=None Affected config: materialized=table; on_schema_change=None
- SAFE ddl.replace_table: source model.sample.dim_publishers; affected model.sample.dim_publishers CREATE OR REPLACE TABLE Source change: not recorded Affected/evidence columns: end_date, publisher_id, publisher_name, start_date; evidence: compiled_sql / exact / column_diff_checked; raw risk: safe; waiver eligible: true Compiled SQL (not a source/Jinja line): target/compiled/sample/models/dim_publishers.sql Source config: materialized=table; on_schema_change=None Affected config: materialized=table; on_schema_change=None
- SAFE ddl.add_column: source model.sample.fct_daily_sales; affected model.sample.fct_daily_sales ADD COLUMN; column: total_sales Source change: added total_sales; removed (not recorded) Affected/evidence columns: order_count, order_date, shipping_info, store_id, total_sales, unique_customers; evidence: compiled_sql / exact / column_diff_checked; raw risk: safe; waiver eligible: true Compiled SQL (not a source/Jinja line): target/compiled/sample/models/fct_daily_sales.sql Source config: materialized=incremental; on_schema_change=None Affected config: materialized=incremental; on_schema_change=None
Observation: model.sample.int_order_enriched -> model.sample.dim_customers; unknown read check; not a column-flow edge; columns (not recorded); read_unresolved Explanation detail omitted: 0 associations; 0 graph edges not displayed. Full relevant graph and findings: JSON. External consumer coverage: unknown. Exposures are declared consumers only.
dbt-plan: 4 checked, 3 safe, 0 warning, 1 destructive, 1 cascade risk(s); overall review: DESTRUCTIVE (before policy)
What It Does
dbt-plan analyzes compiled SQL diffs to catch dangerous schema changes at PR time:
- Column changes: detects ADD/DROP COLUMN from SQL diff
- Risk assessment: judges safety based on materialization x on_schema_change rules
- Cascade analysis: finds downstream models broken by a dropped column — the ones that name it, resolved against the project's own schema rather than matched as text; the ones that select
*and lose it without their own file changing; and the tests whose fixtures pin it down. Names the exposures whose owners need telling - Contracts: reports a change an enforced contract will reject, in either direction
- Config changes: detects materialization or on_schema_change policy changes
- Type changes: compares explicit
CASTtypes between revisions - **
SELECT *resolution**: reads the columns from the CTEs of the same statement, and follows aref()into the referenced model's compiled SQL
The analysis reads files, compares them, and warns; it does not connect to a warehouse or simulate dbt run. The optional dbt-plan run workflow invokes your compile command, which can require credentials and execute macros.
Quick Start
See a result without a warehouse
The repository includes before/after compiled SQL and a manifest, so you can try the analysis without installing dbt or configuring warehouse credentials:
git clone --depth 1 https://github.com/PresentJay/dbt-plan
cd dbt-plan python -m pip install dbt-plan bash examples/sample-project/run-example.sh
The sample prints text, GitHub markdown and JSON output. It intentionally contains a dropped column, so the inner check reports exit code 1 (destructive); the example script itself completes successfully. See the sample scenario for the expected finding.
Use it with your dbt project
python -m pip install dbt-plan
dbt-plan run # compile baseline → compile current → check
dbt-plan run does the whole thing in one command and needs whatever credentials your dbt compile normally needs. If your project already has compiled artifacts, use dbt-plan check directly; it only reads local files and does not connect to a warehouse.
The loop it is built for
Once you have a baseline, the inner loop is a single sub-second command. Edit a model or a macro, recompile, and see what dbt run would do — *before* running it:
dbt-plan snapshot # once, on the revision you are changing from
... edit models, edit macros ...
dbt compile && dbt-plan check
dbt-plan check reads local compiled artifacts. Its latency is separate from dbt compile, which can depend on your adapter, macros, and warehouse. See the reproducible CLI benchmark for measured workloads, raw samples, and commands to measure your machine.
Working with a coding agent
An agent editing models cannot eyeball a diff and hesitate. Give it the check and the reasons behind it:
dbt-plan agent-setup # writes dbt-plan guidance into your AGENTS.md
dbt-plan check --format json
The guidance leads with what an agent most often gets wrong: adding a model to ignore_models, or downgrading on_schema_change from sync_all_columns to ignore, silences a real finding without making the change safe.
Or give it the check as an MCP tool:
pip install 'dbt-plan[mcp]'
dbt-plan-mcp # stdio MCP server exposing plan and snapshot
plan returns the verdict, the per-model operations, and — separately — a refusals list naming everything dbt-plan declined to judge. That separation is the point: a person reading "safe" may still glance at the diff, an agent reading it proceeds, so a non-empty refusals must never be collapsed into the verdict.
Both tools accept target_dir when dbt writes artifacts outside the default target/, for example plan(project_dir=".", target_dir="build").
The
Solo se muestra el principio; lee el resto en el repo