dbt lineage and schema graphs: the missing MCP integration
dbt knows your data transformations. Pretensor knows your schema structure. Together, they give AI agents the full picture of how data flows from source to dashboard.
- mcp
- dbt
- lineage
- schema-graph
- data-engineering
dbt (data build tool) is the standard for data transformation. It knows every model, every dependency, every SQL transformation in your pipeline. Its manifest.json is a machine-readable map of how data flows from raw sources to analytics-ready tables.
Pretensor knows your database schema — tables, columns, foreign keys, inferred joins, table classifications, community clusters. It builds a traversable graph on disk and exposes it to AI agents through MCP.
Put them together and the agent doesn’t just see static schema. It sees lineage. It knows how fact_orders was built from stg_orders and dim_customers, which dbt model produced it, and what downstream models depend on it. This is the bridge between “what tables exist?” and “where did this data come from?”
What dbt already knows
dbt’s manifest.json — generated every time you run dbt run or dbt compile — contains:
- Models: every
.sqlfile in yourmodels/directory, with the raw SQL and compiled SQL. - Dependencies: which models
ref()other models (the DAG). - Sources: tables that feed into dbt models (raw database tables).
- Tests: schema tests (unique, not_null), data tests, and their results.
- Documentation:
.ymldescriptions, column-level docs, tags.
This is rich metadata. But it lives in a JSON file that AI agents can’t query. An agent with access to raw manifest.json would need to parse it, find the right entries, understand the DAG structure, and correlate it with the live database schema — all from context-window reasoning. That’s fragile at scale.
What the schema graph adds
Pretensor’s Kuzu graph captures the database-side reality:
- Physical tables: their actual column names, types, and row counts (from
information_schema). - Relationships: both explicit FKs and inferred joins discovered from column-name/type matching.
- Classification: is this a fact table, dimension, bridge table, or reference table?
- Clusters: which tables are related (Louvain community detection).
- Join paths: precomputed shortest paths between any two tables in the graph.
Combined, dbt provides what transformations happened and the schema graph provides what the result looks like on disk. The agent sees both:
stg_orders (dbt model) → fact_orders (physical table, Fact) ├── FK → dim_customers (physical table, Dimension) │ └── upstream: stg_customers (dbt model) → raw_customers (dbt source) └── FK → dates (physical table, Dimension) └── upstream: dim_dates (dbt model) → seed_dates (dbt seed)How Pretensor + dbt works
Pretensor has a --dbt-manifest flag on the index command. Point it at your manifest.json:
pretensor index postgresql://user:pass@host:5432/dbname \ --dbt-manifest /path/to/dbt/project/target/manifest.jsonPretensor reads the manifest, extracts model-to-table mappings, and enriches the graph:
-
Model-to-table linking: Each dbt model is linked to its corresponding physical table in the schema graph. The agent sees
dim_customersas both a node in the lineage graph (dbt model) and a node in the schema graph (PG table with columns, FKs, classification). -
Lineage edges: The graph gets new edge types:
CREATED_BY(table → model that produced it),DEPENDS_ON(model → upstream model), andSOURCED_FROM(model → source table). The agent can traverse lineage and schema in the same query. -
Documentation enrichment: Column-level documentation from dbt
.ymlfiles is attached to graph nodes. The agent’scontextcall for a table includes both structural metadata (column type, FK) and documentation (“This is the customer dimension, sourced from the CRM, refreshed daily”). -
Test results (future): dbt test results can flag stale or broken tables, giving the agent a data-quality signal alongside schema context.
What this enables for AI agents
With dbt enrichment, the agent’s questions get better answers:
| Question | Without dbt enrichment | With dbt enrichment |
|---|---|---|
| ”Where does revenue_daily come from?" | "It’s a table with these columns." | "It’s a dbt model that joins fact_orders and dim_products, refs stg_orders, stg_products. Source tables: raw_orders, raw_products." |
| "What depends on raw_customers?” | No answer (raw_customers might not even be in the graph). | “raw_customers is a dbt source. Downstream: stg_customers → dim_customers → fact_orders, customer_360_view. 4 models total." |
| "If I change dim_customers.customer_segment, what breaks?” | FK-based impact on physical tables. | FK-based impact + dbt model dependency chain. 2 downstream models would need re-running. |
| ”Is this table documented?” | No answer. | ”dim_customers: ‘Customer dimension sourced from CRM, refreshed daily. Grain: one row per customer_id.’” |
Why this is the missing integration
MCP is still new. Most MCP database tools ship with a query tool and maybe a list_tables tool. The idea of combining transformation metadata (dbt) with schema metadata (information_schema) in an agent-queryable graph hasn’t been done yet.
This is partly because dbt and MCP live in different ecosystems. dbt is for analytics engineers writing SQL transformations. MCP is for AI tool builders. But the data engineer who uses dbt is increasingly the same person using Claude or Cursor for warehouse exploration. They shouldn’t have to bridge the two worlds manually.
The schema graph + manifest.json integration means:
- One source of truth for the agent. Not “here’s the schema” and “here’s the lineage file” — one graph with both.
- No manual DDL pasting. The agent discovers schema on its own, lineage included.
- Impact analysis that spans transformations. Changing a source table → downstream dbt models affected → physical tables affected → queries/dashboards affected.
- Documentation retrieval. The agent can answer “what does this column mean?” with the dbt docs, not just the column type.
Getting started
pip install pretensor
# Index with dbt manifestpretensor index postgresql://user:pass@host:5432/dbname \ --dbt-manifest ./target/manifest.json
# Start MCP serverpretensor serve --config-onlyThe context tool will now include model lineage and documentation in its response. The impact tool will traverse both FK edges (schema graph) and model-dependency edges (dbt DAG). The cypher tool can query lineage paths directly:
MATCH (m:Model)-[:CREATED_BY]->(t:Table)WHERE t.name = 'fact_orders'RETURN m.name, m.sqlPretensor is open-source on GitHub. dbt manifest support is available in the current alpha. See the quickstart for full setup.