See it as a diagram
Everything below, as a diagram you can edit. Describe yours and see it in seconds.
No account needed · Editable canvas, not a picture
manifest.json: the lineage, already computed
Every dbt command that parses the project, build, run, compile, writes target/manifest.json. Its nodes object keys every model, seed, snapshot, and test by a unique_id like model.analytics.stg_orders, and two companion maps give the graph without any SQL parsing on your side: parent_map lists what each node depends on, child_map lists what depends on it. The lineage your diagram needs is those two maps, verbatim.
This is what an MCP-connected agent reads to draw or update the diagram: no ref() spelunking, no dbt-specific parsing, one JSON file that is always exactly as fresh as the last build.
dbt build # Everything downstream of one staging model jq '.child_map["model.analytics.stg_orders"]' target/manifest.json # Declared downstream consumers jq '.exposures | keys' target/manifest.json
catalog.json and exposures fill in what the manifest cannot
The manifest knows the graph but not the warehouse. dbt docs generate queries the warehouse and writes target/catalog.json with the actual columns, types, and row counts per relation, which is the artifact to use when the diagram should show key columns on the marts. Worth knowing before you promise it to anyone: dbt's artifacts give model-level lineage, not column-level edges; catalog.json lists columns but does not trace them across models.
Exposures close the graph on the far side. An exposure is a YAML declaration that a dashboard, an ML job, or an application consumes specific models, and it lands in the manifest like any node. Declaring them is what turns the diagram's edge into an answer for the question that actually hurts: what breaks downstream if this model changes.
dbt docs already draws a DAG, so why another view
Fair question, and dbt docs deserves the credit: its lineage graph is interactive, complete, and free with the project. It is also unfiltered by design, every node at equal weight, which is the wrong altitude for a wiki page where a product manager or a new hire needs sources, layers, marts, and consumers at a glance. The curated diagram exists for that reader: staging, intermediate, and mart zones, the dozen models that matter, exposures drawn as real boxes.
Scope note to keep the pages straight: this guide covers the lineage diagram. Keeping the dbt docs site itself fresh, hosting and CI for dbt docs generate, is a different workflow, covered in keep dbt docs in sync. And the dbt lineage diagram generator owns the first-time generation, from a pasted manifest excerpt or a description.
One CI step after dbt build
The loop mirrors every other source in this series, with an unusually convenient artifact. CI already runs dbt build on merge; the fresh manifest is sitting in target/ when it finishes. Add one step: an agent connected to Datadef's MCP server (registry io.datadef/mcp) reads the manifest, diffs it against the diagram, and applies the changes, new models into their layer zones, deleted ones removed, exposure edges updated. The connection needs an API key, available on paid plans.
Datadef does not watch the repo or your warehouse; nothing regenerates by itself. But since the manifest regenerates on every build anyway, the marginal cost of the diagram step is one command, and the wiki embed does the rest: an updated diagram shows up in the Notion or Confluence page embedding it within minutes.
What manifest.json leaves out
Model-level lineage is what the artifacts give; column-level lineage is not in the manifest, and a diagram claiming it would be decorating guesses. The embed requires the Datadef project to be shared public, which for lineage diagrams naming internal tables deserves an explicit decision rather than a default. And exposures only appear if the team declares them: an undeclared dashboard is invisible to dbt and therefore to the diagram, which is an argument for declaring exposures, not against the diagram.
The manifest is always fresh
FAQ
How do I automate a dbt lineage diagram?
Where does dbt store lineage information?
Is column-level lineage in manifest.json?
What are dbt exposures and why draw them?
Does the lineage diagram update when models change?
Is the dbt docs lineage graph enough?