← Back to all work

dbt-llm-analytics

A free hands-on course teaching dbt on real National Park Service biodiversity data, plus a read-only MCP server for querying the finished warehouse in plain English.

dbt · DuckDB · Python · MCP · Killercoda

The problem

Most dbt tutorials run on jaffle_shop — a handful of tidy rows invented to make the example work. You finish having typed the commands without meeting the thing dbt exists for: real data with inconsistent categories and missing values. The tests pass first try, so you never learn why tests are there.

The second gap is the ending. Tutorials stop at a built model, which is where the interesting question starts: who queries it, and how?

Scope

DataNPS biodiversity — 5,824 species, ~23,000 observations, four parks
dbt project4 staging models, 3 marts, schema tests and column docs in YAML
Written tutorial6 parts, dbt init through testing and documentation
Interactive lab6-step Killercoda scenario with per-step verify scripts, nothing to install
MCP server3 tools over DuckDB; run_query is SELECT-only

Three decisions

Real public data instead of a synthetic example. Synthetic data makes a tutorial easier to write and worse to learn from, because every edge case was removed in advance. The NPS dataset has inconsistent conservation-status values and sparse columns, so the staging layer has real work to do and a schema test can genuinely fail.

DuckDB rather than a cloud warehouse. A cloud warehouse is more realistic and adds a signup, credentials and a free-tier clock to step zero — which is where tutorials lose people. DuckDB runs in-process from a file, so dbt build works offline in seconds. What’s lost is warehouse-specific SQL and permissions, which is right to defer past someone’s first dbt project.

SELECT-only, enforced in the server rather than the prompt. The MCP server hands a model a SQL execution tool, so the question is what happens when it writes a DROP. Telling it not to in the tool description is not a control. The restriction lives in run_query before execution — same principle as the prerequisite gate in learning-mcp.

Verification

The dbt project’s own schema tests are the verification, which is the point of the exercise — not_null, unique and accepted-values tests across staging and marts, run by dbt build. The Killercoda scenario adds a per-step verify script so a reader who mistypes a model doesn’t discover it three steps later.

Constraints

Next

Links

github.com/ryantthomas/dbt-llm-analytics
Tutorial landing page