Connect Claude Code to your dbt project

Setup Guide Free ~10 min read Official dbt MCP server

Connect Claude Code to your dbt project

A no-nonsense walkthrough for getting dbt Labs’ official MCP server running in Claude Code, Claude Desktop, or Cursor. Both Local and Remote modes, with the env vars, the JSON configs, the starter prompts that work out of the box, and the gotchas dbt Labs has not fixed yet.

{ } Claude Code + dbt MCP
Local install via uvx
Remote setup via OAuth
12 starter prompts
Read-only safety pattern
00

Who this is for

You have a dbt project (Core or Cloud) and you are tired of grepping the manifest to answer lineage questions. You want Claude to read your project as a structured graph, not as a folder of files. You want to be able to ask “what depends on stg_payments” in plain English and get the right answer.

You do not need to be a dbt power user. You do need to know your way around a terminal, have admin access (or friendly admin) to your dbt setup, and have Claude Code, Claude Desktop, or Cursor installed.

If you are reading the article version of this guide and clicked through for the setup, you are in the right place. If you landed here directly, the article that frames why any of this matters is here.

01

Prerequisites

You need a few things in place before the install actually works. Skim the list. If anything is missing, fix that first.

  • A dbt project that parses cleanly. Run dbt parse in your project directory. If it errors out, fix the errors before going any further. The MCP reads from target/manifest.json and a missing or stale manifest is the most common reason setup appears to fail.
  • For Local mode: uv installed (the Python toolchain that ships uvx). uvx --help should respond. On macOS, brew install uv. On Linux, the curl install script in the docs. On Windows, follow the PowerShell installer carefully and reopen your terminal after.
  • For Remote mode: a dbt Platform account with the Remote MCP feature enabled. Check Account Settings → AI in the dbt Platform UI. If Remote MCP is not listed, contact dbt support to enable it on your account.
  • Claude Code, Claude Desktop, or Cursor installed. The MCP works the same in all three. The configs differ slightly, which is why this guide has each one separately.
  • Read access to your dbt project repo if you are running Local against a cloned project, or to your dbt Platform environment if you are using Platform-backed features (Discovery API, Semantic Layer, Admin API).
02

Local or Remote?

The dbt MCP comes in two flavors. The choice is the most important decision in this guide. Pick the wrong one and you will spend an afternoon trying to get a feature working that does not exist on that path.

Pick Local if you
Run dbt commands
  • Want the agent to run dbt run, build, test, compile
  • Need codegen tools (model YAML from schema, staging scaffold, source YAML)
  • Are an analytics engineer doing dev or audit work
  • Want to use Fusion-specific tools (column lineage, compile_sql)
  • Want the full toolset, accept some setup overhead
Pick Remote if you
Ask questions about the project
  • Want a 2-minute install with no env vars
  • Are a business user, BI partner, or stakeholder
  • Need Discovery, Semantic Layer, and Admin API access
  • Are deploying an agent for non-engineers
  • Are fine without CLI execution or codegen
Field note

Most teams end up with both, on different machines, for different jobs. There is no rule saying you have to pick one. The two modes do not conflict.

03

Local setup

The Local server runs through uvx, which fetches the dbt-mcp package on demand. No virtualenv to manage, no pip install to debug. The whole thing is one config block in your MCP client and a handful of environment variables.

Step 1: Get your dbt Platform credentials

You need four values from dbt Platform. None of them are hard to find, but they live in different places.

  • DBT_HOST: typically cloud.getdbt.com for US multi-tenant accounts, or your single-tenant URL.
  • DBT_TOKEN: a Platform service token. Account Settings → Service Tokens → Create. Give it Developer access at minimum. Copy the token immediately; it is not shown again.
  • DBT_PROD_ENV_ID: the numeric ID of your production deploy environment. Open the environment in dbt Platform; the ID is in the URL after /environments/.
  • DBT_USER_ID: your user ID. Open your profile page in dbt Platform; the ID is in the URL after /users/.

If you are only using Local against a dbt Core project (no Platform features), you can skip these and just set DBT_PROJECT_DIR.

Step 2: Add the MCP server to your client

Pick the config block that matches your client. Paste it into the right config file. Reload the client.

The JSON shape is identical for all three clients. Only the config file path differs. Pick your client:

Config file: ~/.claude.json (user scope)

json
{
  "mcpServers": {
    "dbt": {
      "command": "uvx",
      "args": ["dbt-mcp"],
      "env": {
        "DBT_PROJECT_DIR": "/absolute/path/to/your/dbt/project",
        "DBT_HOST": "cloud.getdbt.com",
        "DBT_TOKEN": "dbtu_...",
        "DBT_PROD_ENV_ID": "12345",
        "DBT_USER_ID": "67890"
      }
    }
  }
}

Or use the CLI, which writes the same block to the right file:

bash
claude mcp add dbt -s user \
  --env DBT_PROJECT_DIR=/absolute/path/to/your/dbt/project \
  --env DBT_HOST=cloud.getdbt.com \
  --env DBT_TOKEN=dbtu_... \
  --env DBT_PROD_ENV_ID=12345 \
  --env DBT_USER_ID=67890 \
  -- uvx dbt-mcp

Config file: ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) · %APPDATA%\Claude\claude_desktop_config.json (Windows)

json
{
  "mcpServers": {
    "dbt": {
      "command": "uvx",
      "args": ["dbt-mcp"],
      "env": {
        "DBT_PROJECT_DIR": "/absolute/path/to/your/dbt/project",
        "DBT_HOST": "cloud.getdbt.com",
        "DBT_TOKEN": "dbtu_...",
        "DBT_PROD_ENV_ID": "12345",
        "DBT_USER_ID": "67890"
      }
    }
  }
}

Config file: ~/.cursor/mcp.json (user scope) · .cursor/mcp.json (project scope)

json
{
  "mcpServers": {
    "dbt": {
      "command": "uvx",
      "args": ["dbt-mcp"],
      "env": {
        "DBT_PROJECT_DIR": "/absolute/path/to/your/dbt/project",
        "DBT_HOST": "cloud.getdbt.com",
        "DBT_TOKEN": "dbtu_...",
        "DBT_PROD_ENV_ID": "12345",
        "DBT_USER_ID": "67890"
      }
    }
  }
}
Windows note

On Windows, replace "command": "uvx" with the absolute path to your uvx.exe (typically C:\Users\YOU\.local\bin\uvx.exe). The PATH that Claude Code sees does not always match the PATH in your terminal. Absolute paths bypass that whole class of bug.

04

Remote setup

If you went with Remote, the setup is shorter than reading this section.

  1. In dbt Platform, open Account Settings → AI. Find the Remote MCP endpoint URL. It looks like https://your-account.dbt.com/api/mcp/v1/sse.
  2. In Claude Code, run claude mcp add --transport sse dbt-remote https://your-account.dbt.com/api/mcp/v1/sse (replace with your actual URL).
  3. Claude Code opens a browser tab for OAuth. Log into dbt Platform. Authorize.
  4. Reload Claude Code. The Remote server is now listed under available MCP servers.

Claude Desktop and Cursor support remote MCP servers the same way; the UI varies but the steps are identical (URL, OAuth, reload).

Credit Gotcha

The Remote server’s text_to_sql tool consumes dbt Copilot credits. If your account runs out of credits, every Remote MCP tool stops working, not just text_to_sql. Lineage queries that should be free will start failing too. Check your Copilot quota first whenever the Remote server “suddenly stops working.”

05

Verify the connection

Reload your MCP client. Then run this prompt in a fresh chat:

prompt
List the first 10 models in my dbt project using the dbt MCP.
Show me each model's name and its layer (staging, intermediate, mart).

If everything is wired up, what you should see is a tool call land, hit the dbt manifest, and return real model names from your project, something like this:

Claude Code · dbt-mcp connected
> List the first 10 models in my dbt project…
• calling get_all_models(limit=10) via dbt-mcp
stg_orders staging
stg_customers staging
stg_payments staging
int_order_items intermediate
int_payments_pivot intermediate
fct_orders mart
fct_payments mart
dim_customers mart
fct_subscriptions mart
fct_churn mart
✓ 10 models, 3 layers. dbt-mcp responded in 0.8s.
dbt-mcp uvx dbt-mcp | 30+ tools available | read-only profile

If nothing happens, or you see an error, jump to the troubleshooting section.

For a second smoke test:

prompt
Pick any mart model from my project. Show me its upstream lineage
and list the tests defined on it.

This exercises get_mart_models, get_model_lineage_dev, and get_test_details in a single conversation. If it works, your install is solid.

06

12 starter prompts

These are the prompts that earned the MCP its keep on the first few projects I ran it against. Copy them, run them on your project, watch what comes back. You will start adapting them within a day.

Discovery

List all mart models in my project. For each one, show me how many downstream consumers it has and flag any with zero. Those are candidates for retirement.

Discovery

Walk the lineage for fct_orders (substitute your own canonical fact model). Show me the full upstream chain back to source tables.

Discovery

Which tests cover dim_customers? List each test, what it asserts, and whether it is on a column or the whole model.

Audit

Find every mart model that has no tests defined. Rank them by number of downstream consumers, so the highest-impact untested models come first.

Audit

List every source defined in my project. For each one, tell me whether it has at least one downstream mart. Sources with no downstream marts are dead weight.

Audit

Scan my models for hardcoded date or timezone literals (anything like '2020-01-01' or - interval '5 hours'). Flag the SQL files and line numbers.

Refactor

Generate a YAML for my int_payments model. Include column descriptions inferred from the SQL, and propose not_null tests on the primary key and any non-nullable foreign keys.

Refactor

Generate a source YAML for the raw_stripe schema in my warehouse. Include all tables, with column types pulled from the actual schema.

Refactor

Propose a staging model for the customers table in source raw_app. Use our project conventions for naming, columns, and basic tests.

Semantic

List every metric defined in my project. For each one, show me the time grain, the dimensions, and a one-line description of what it measures.

Semantic

Pull the value of my revenue metric for each of the last 90 days, grouped by region. Use the semantic layer, not raw SQL.

Semantic

My BI dashboard shows monthly revenue of [X] for last month. Pull the same metric for the same period from the semantic layer. If they differ, propose a hypothesis for the drift.

07

Project hygiene before you connect

The MCP is only as good as the project it reads from. A few small things to fix first will dramatically improve what the agent can do:

  • Parse cleanly. dbt parse with zero errors. The manifest is the agent’s source of truth. A broken parse means a stale or missing manifest, which means an agent guessing instead of reading.
  • Tag primary keys. Models with explicit primary key columns (via unique tests or the new primary_key constraint) give the agent strong join inference. Without them, the agent guesses.
  • Document at least your marts. Even one-line descriptions on each mart model and its key columns shift agent behavior from “looks at the SQL and guesses what this means” to “reads the description and reasons correctly.”
  • Define sources properly. Use sources.yml. Avoid bare FROM raw.schema.table in SQL. The agent uses sources to answer “where does this data originally come from.”
  • Name consistently. Stick to a convention (stg_, int_, fct_, dim_, mart_, whatever you have agreed on). The agent uses naming to infer layer structure. Inconsistent naming makes the inference noisy.
  • Run dbt parse before any audit session. Re-parse if you have pulled new changes or switched branches. It takes seconds.

None of this is dbt MCP specific. It is good hygiene for any dbt project. The MCP just makes the cost of bad hygiene visible.

08

Read-only safety pattern

The first question any sensible data lead asks: what stops the agent from running dbt run --full-refresh on production at 2am?

The answer is layered. Use all three layers.

Layer 1: Per-tool permissions in Claude Code. Claude Code lets you decide which tools the agent can call automatically and which require a prompt. The pattern that works:

  • Always allowed: get_all_models, get_mart_models, get_model_details, get_model_parents, get_model_lineage_dev, get_test_details, get_macro_details, get_seed_details, get_snapshot_details, list_metrics, get_dimensions, query_metrics.
  • Requires prompt: any CLI tool (run, build, test, compile, clone), any codegen tool, any Admin API tool that triggers a job (trigger_job, retry_job).

Layer 2: Service token with minimum role. Generate the DBT_TOKEN under a service account with Developer role and read-only access to your production environment’s Discovery and Semantic Layer APIs. No job-trigger permission. The token literally cannot fire a run, no matter what the agent asks it to do.

Layer 3: Separate elevated session for writes. When you genuinely need to trigger a job or run a model, switch to a Claude Code profile with an elevated token, do the one task, switch back. Same pattern as sudo. The flip is intentional, which is the whole point.

Bonus: real-time audit

Wire a dbt Platform webhook on job events to post to a Slack channel like #data-changelog. Your agent can do whatever you authorize, but every action becomes visible in real time. The combo of read-mostly defaults plus full audit visibility covers most operational risk.

09

Troubleshooting

The setup failure modes are predictable. If something is not working, scan this table first.

Symptom Likely cause and fix
Server not visible after restart Wrong config file. Claude Code reads ~/.claude.json (user scope), not ~/.claude/mcp.json. Use claude mcp add dbt -s user -- to write to the right place.
“uvx: command not found” uvx is not on the PATH that Claude Code can see. Put the absolute path to uvx in the command field, or install uv system-wide.
“No models found” or empty results DBT_PROD_ENV_ID points at an environment with no successful deploys, or the wrong environment. Confirm the ID from the URL in dbt Platform.
401 / Authentication failed DBT_TOKEN is a personal access token, not a service token. Generate a Service Token specifically. Or the token’s account does not have Developer access.
Stale lineage in responses The MCP reads from target/manifest.json. Re-run dbt parse in your project directory before the session.
Tool calls hang on Windows PATH or quoting issue with uvx.exe. Use absolute path with forward slashes (C:/Users/YOU/.local/bin/uvx.exe). Some installs need administrator privileges.
Remote: all tools failing at once Copilot credit exhaustion. Check the credit balance in dbt Platform. text_to_sql consumes credits and credit failure blocks the whole Remote server.
Agent picks raw SQL when it should use metrics Your prompt is ambiguous. Say “use the semantic layer” explicitly. Or remove text_to_sql from the auto-allow list to force a planning step.
“Connection refused” on first run Outbound HTTPS to cloud.getdbt.com is blocked, or behind a corporate proxy. Set HTTPS_PROXY in the env block of your MCP config.
Lineage chain longer than expected The lineage tool includes ephemeral models. That is by design. Use get_model_parents with depth=1 if you only want immediate parents.

If you hit something that is not in this table, the dbt community Slack channel #tools-dbt-mcp is the right place to ask. dbt Labs engineers monitor it.

Get in Touch

Let's Discuss Your Project

Book a 30-minute discovery call. We'll assess your data maturity and recommend the right approach — no strings attached.

Book a Discovery Call →