dbt Labs shipped an official MCP server that gives any MCP-compatible client structured access to your dbt project: models, lineage, tests, sources, the semantic layer, and the Admin API. Wired into Claude Code, the agent can answer lineage questions in seconds, find drift between dashboards and metrics, generate model YAML from a warehouse schema, and trigger jobs on dbt Platform. This article walks through a real legacy-project audit, the Local vs Remote tradeoff, the read-only pattern, and the 5 gotchas dbt Labs has not fixed yet.
In This Article
- What MCP is, in one paragraph
- A real-world job: auditing a legacy dbt project
- Two ways to deploy: Local or Remote
- What the setup actually looks like
- Read-only by default (the safety pattern)
- The manifest is a graph, not a folder
- Validation as part of the same flow
- What dbt MCP cannot do (yet)
- Debugging when things go wrong
- The bigger picture
- What I would actually recommend
- Questions data leads ask before they adopt this
It is the kind of message most data leads have seen on a Monday. An analyst pings you in Slack: the number in last night’s executive dashboard does not match the finance report, can you take a look? You open the BI tool, open the dbt repo in another window, and start the same dance you always do. Find the model behind the dashboard. Find its parents. Find the parents of the parents. Read the SQL. Cross-reference with what finance is pulling. Two hours later, you have a hypothesis.
What I actually did the last time this came up: I opened Claude Code, asked it to walk the lineage for the intermediate model behind that dashboard tile and find the most likely point of drift. About 35 seconds later it came back with the eight-model lineage graph, two candidate causes (a hardcoded timezone offset in one upstream model, a casting difference in another), and a one-line summary of which one matched finance’s logic. I checked the SQL myself, agreed with the call, and posted the hypothesis back in Slack before my coffee was cold.
The unlock was the official dbt MCP server. It is the same agent you already know, with structured access to the manifest, the semantic layer, the Discovery API, and (optionally) the dbt CLI itself. This article walks through what that workflow looks like, where it earns its keep, and the gotchas worth knowing before you wire it into your team’s setup.
If you would rather skip the context and go straight to the step-by-step setup, the free guide is here: valiotti.com/dbt-mcp-guide.
What MCP is, in one paragraph
MCP stands for Model Context Protocol. It is an open standard from Anthropic that lets Claude connect to external tools and read or write data through them. Think of it like a plugin system for AI agents. The model does not pretend to use a tool. It actually uses it. You ask Claude to walk the lineage for fct_orders, and Claude makes real calls into the dbt manifest, gets the real upstream graph back, and answers based on what it found. No hallucinated table names. No guessing what column lives where.
dbt Labs shipped an official MCP server in April 2025 and has been iterating on it hard since. By the time you are reading this it is well past v1, OpenSSF Best Practices certified, and dbt Labs themselves use it as the substrate for their new dbt Agents product. Once it is registered with Claude Code, the agent can list every model in the project, pull lineage in either direction, inspect tests, query the semantic layer for governed metric values, and (if you let it) run dbt commands and trigger Admin API jobs.
run, build, test, compile, parse, list, clone, docs generatelist_metrics, get_dimensions, query_metrics, saved queriescompile_sql, get_column_lineagedbt-fusion in the project. Everything else works in both Local and Remote modes.If you have used Claude Code before, this is the same agent. The difference is what it can see. Without MCP, your dbt project is a folder of .sql and .yml files that the agent has to grep its way through. With dbt MCP, the project becomes a structured graph the agent can query directly: ask for a model and get its description, its config, its tests, its parents, and its children, all without parsing a single file.
A real-world job: auditing a legacy dbt project
Here is the case that made me a convert.
I had been asked to take a look at a legacy dbt project. The kind of project most analytics engineers eventually inherit: a few hundred models accumulated over years, 8 out of 10 core business metrics already encoded as dbt models, and a small army of one-off dashboard queries that nobody had ever consolidated. The team needed 3 things from me, fast: a lineage map of the most important models, a list of likely drift sources between BI and finance, and a recommendation on what to refactor first.
In the old workflow, this is a week of careful spelunking. You start with dbt ls and dbt docs generate, then spend an afternoon scrolling the docs site. You grep the repo for the model behind the dashboard tile. You git-blame the SQL to figure out who wrote what and why. You read Slack history for context the comments do not capture. You write small probes against the warehouse to test hypotheses. By the end of day three you might have a defensible map.
What I actually did, with dbt MCP wired into Claude Code:
dbt ls,dbt docs serve, scrolling- Grep across hundreds of .sql files
- Git blame + Slack archaeology
- Probe queries against the warehouse
- Manually cross-reference BI screenshots
- One
get_all_modelscall, structured - Lineage for each candidate in seconds
- Semantic layer values pulled directly
- Drift candidates suggested with reasoning
- Findings written as a reviewable doc
Here is what the actual session looked like.
Step 1. Got the dbt MCP server running locally against the project. One uvx dbt-mcp command, one Claude Code config block pointing at the project path and a few environment variables. Five minutes, including reading the README.
Step 2. Asked Claude to inventory the project. It hit get_all_models and get_mart_models, came back with the full model list grouped by layer (staging, intermediate, marts), flagged the 7 marts the team had pointed me at as the high-traffic ones, and noted that one of them had no downstream consumers in the manifest, which usually means stale code.
Step 3. Picked the model behind the disputed dashboard tile. Asked Claude to pull its parents recursively. get_model_lineage_dev returned an eight-model chain back to 4 source tables. The agent rendered it as a text tree and highlighted two nodes worth a closer look: an intermediate model with a multi-hundred-line CASE WHEN block, and another with a hardcoded timezone offset.
Step 4. Asked Claude to summarize each suspect. get_model_details returned the description, config, tests, and column docs for each. The CASE WHEN model existed to compensate for an unreliable status column from the source. The author had reverse-engineered the right behavior from billing history, which was correct as far as it went, but the logic was tied to assumptions that had since shifted. The other model used a hardcoded interval of 5 hours to convert a timestamp to local time, which silently broke during daylight saving.
Step 5. Cross-checked against the semantic layer. The project had a few metrics defined, including one that was supposed to be the canonical version of the disputed number. list_metrics showed it. query_metrics pulled the value for the last 90 days. I compared it against the BI dashboard and the finance spreadsheet side by side. The semantic-layer value matched finance. The BI dashboard value did not. The drift was on the BI side, downstream of where most people had been looking.
Step 6. Asked Claude to draft a memo. It produced a four-page document: the lineage map, the two technical findings, the drift root cause, the three things I would recommend changing first (rewriting the CASE WHEN block to depend on a stable source field, fixing the timezone handling, retiring the duplicate BI logic in favor of the semantic-layer value), and a section on tests the project did not have but should.
Step 7. Spot-checked everything. The agent had been right about lineage (verified against the manifest), right about the timezone bug (verified by reading the SQL), right about which model had no consumers (verified by running get_model_children on it). The only place I overruled it was the priority on the refactor list: the timezone fix should come before the CASE WHEN rewrite because the timezone bug was actively producing wrong numbers in production, while the CASE WHEN model was working correctly, just brittle.
Total session time, including the time it took me to think about what to ask: about three hours. The equivalent work without MCP, two days, possibly three. And those two days are mostly low-leverage mechanical work. The interesting part, deciding what to recommend, takes minutes when the mechanical work is collapsed.
I want to be clear about what this is and is not. Claude did not make the architectural call. I picked the priority. I read every piece of SQL it flagged. I verified its lineage claims against the manifest. The agent surfaced patterns and saved me hours of grepping; it did not replace the judgment about what those patterns meant for the business. But the part where you read 50 SQL files to find the one with the timezone bug, or write 5 probe queries to confirm two models are computing the same thing differently: that is gone.
There is also a documentation byproduct worth flagging. After the audit was done, the memo was already a document. It described the lineage with actual model names, the bugs with actual line references, and the recommendations with actual code-change suggestions. That is a different quality of audit doc than the “we looked at things and they were complicated” memo most teams end up with. The agent forces a level of specificity that humans, especially under time pressure, tend to skip.
Want to run this on your own dbt project? The free setup guide walks through every step, including the Local vs Remote decision tree and the starter prompts that work out of the box.
Two ways to deploy: Local or Remote
dbt MCP ships in two flavors, and the choice between them is the most important decision you will make during setup. They look similar from the agent’s perspective. They are very different in terms of what is actually possible.
uvx dbt-mcp reads from a local dbt_project.ymltext_to_sql, credit exhaustion blocks everythingMy rule of thumb is simple. If the person at the keyboard is going to write SQL, refactor models, generate YAML, or run anything against the warehouse, give them Local. If they are going to ask questions about the project (“what metrics do we have for revenue?”, “which marts depend on the orders table?”), give them Remote. Most teams end up with both, on different machines, for different jobs.
The Remote server has one footgun worth flagging up front. The text_to_sql tool consumes dbt Copilot credits. If your account runs out of credits, every tool on the Remote server stops working, not just text_to_sql. The agent will get errors on lineage queries even though those should be free. This has bitten more than one team. Plan your credit limits accordingly, or stay on Local until dbt Labs decouples the two.
What the setup actually looks like
If you are thinking “this sounds great in theory but I bet it is a nightmare to install,” the actual setup is not bad. Here is the full picture.
For Local mode you need three things: a dbt project that parses cleanly (dbt parse with no errors), uv installed (the Python package manager that ships uvx), and Claude Code installed locally.
The MCP server itself runs through uvx, which means there is no virtualenv to manage. uvx dbt-mcp fetches the package, runs it, throws it away when the session ends. Cleaner than the pip-install-into-a-venv pattern most Python tools require.
Configuring Claude Code to use it is one block of JSON in your ~/.claude.json. The shape is straightforward:
// add this under "mcpServers" at user scope "dbt": { "command": "uvx", "args": ["dbt-mcp"], "env": { "DBT_PROJECT_DIR": "/absolute/path/to/your/dbt/project", "DBT_HOST": "cloud.getdbt.com", "DBT_TOKEN": "dbtu_***", // Platform service token "DBT_PROD_ENV_ID": "12345", // from deploy env URL "DBT_USER_ID": "67890" // from your profile page } }
You add an mcpServers entry with the command uvx, the argument dbt-mcp, and an env block with 5 values: DBT_PROJECT_DIR (the absolute path to your project), DBT_HOST (typically cloud.getdbt.com), DBT_TOKEN (a Platform service token), DBT_PROD_ENV_ID (the numeric ID of your production environment), and DBT_USER_ID (your user ID on dbt Platform). The last 4 are only needed for the Platform-backed tools (Discovery, Semantic Layer, Admin API). If you are running purely against a local dbt Core project, DBT_PROJECT_DIR by itself is enough to get the CLI and codegen tools working.
The credentials take a minute. Open the dbt Platform UI, generate a service token under Account Settings, note the user ID from your profile page, note the prod environment ID from the deploy settings. Copy all 4 into a password manager. If your account has multiple users, generate the token under a service account with the lowest role that grants read access to your Discovery API: Developer is usually enough.
For Remote mode the entire setup is one line. Get the Remote MCP endpoint URL from your dbt Platform admin panel (it looks like https://your-account.dbt.com/api/mcp/...), paste it into Claude Code’s MCP settings as a remote server, and let the browser OAuth flow do the rest. There are no environment variables to manage. The token lives in your Platform session.
The first time you launch Claude Code with the MCP active, verify it worked by asking Claude to list a few models. You should see a tool call land, hit the API, and return real model names from your project. If you see that, you are done with setup.
Total time for someone who has never touched MCP before: about 20 minutes for Local, about 5 minutes for Remote. For someone who has, it is closer to 10 minutes and 2 minutes. The setup is the easy part. The interesting work is figuring out what to ask the agent to do.
If something in the setup does not work, the free guide has the answer. If it is something the guide does not cover, drop me a line and I will help.
Read-only by default (the safety pattern)
The first question any sensible data lead asks about an MCP-enabled agent is: what stops it from running dbt run --full-refresh on production at 2am?
The answer with dbt MCP is layered. The Remote server does not expose any CLI tools at all, so on that path the question is moot. The Local server does expose CLI tools, but Claude Code has a per-tool permission system: you decide which tools the agent can call automatically and which require a permission prompt. The pattern that works in practice is to allow the read-only Discovery and Semantic Layer tools without confirmation, and require a prompt for anything that mutates state.
Concretely, that means letting Claude call get_all_models, get_model_details, get_model_lineage_dev, list_metrics, query_metrics, and similar without bothering you. And requiring an explicit yes before run, build, test, clone, or any Admin API tool that triggers a job. The Claude Code permissions UI makes this a one-time setup. After that you can leave the agent on a long lineage exploration without worrying that one wrong prompt will rebuild your marts.
For Admin API access on the Platform side, you can layer a second defense. Generate the service token under a Platform role that has read access to the Discovery and Semantic Layer APIs but no permission to trigger jobs. The token literally cannot fire a run, no matter what tool the agent calls. Even if you accidentally remove the per-tool permission gate, the API rejects the request. That is the same defense-in-depth pattern data teams already use for warehouse roles: the SQL workbench can read whatever it wants, but it cannot drop tables because the role does not have the privilege.
-
1Layer 01 · ClientPer-tool permissions in Claude CodeAllow discovery tools (lineage, model details, metrics) without confirmation. Require a prompt for any tool that runs code or triggers a job.
-
2Layer 02 · ServerPlatform service token, read-only roleThe token grants Discovery and Semantic Layer API access only. No job-trigger permission. Even a misconfigured agent cannot fire a production run.
-
3Layer 03 · ElevationSeparate session for writesWhen you actually need to trigger a job or run a model, switch to a Claude Code profile with the elevated token, do the one task, switch back. Same pattern as
sudo.
For team workflows, take this further. Use one service account token for the always-on read-only agent. Use a separate, higher-privilege token only when you need to trigger jobs. The MCP does not care which credentials it has; the API gate is what matters.
One more pattern worth mentioning. dbt Platform supports webhooks on job events. Wire a “every time a job is triggered or a model fails, post to #data-changelog in Slack” webhook. Your agent can do whatever you authorize it to do, but every action becomes visible to the team in real time. The combination of read-mostly defaults plus full-audit visibility on writes covers the operational risk that scares most data leads off agent workflows in the first place.
The manifest is a graph, not a folder
The single biggest mental shift dbt MCP triggers is this: your project stops being a folder of files and starts being a graph the agent can query.
Without MCP, an agent looks at a dbt project the way you look at a new codebase on day one. It is a tree of .sql and .yml files. To answer “what does fct_orders depend on?” the agent has to read the file, parse the ref() calls, then read each of those files, parse their ref() calls, and recurse. It works for small projects. It falls over on large ones, and it does not understand the difference between a ref() and a source() at the semantic level.
With MCP, that question is one tool call: get_model_lineage_dev(model="fct_orders") returns the full upstream graph as structured data. The agent does not have to parse anything. The same goes for tests (get_test_details), documentation (get_model_details returns descriptions and column docs), macros (get_macro_details), seeds, snapshots, and semantic definitions. The agent treats the manifest the way a senior analytics engineer treats it: as a queryable artifact, not a pile of YAML to be wrangled.
The practical effect: prompts that used to require half a page of context now require one sentence. “Find every model that depends on stg_payments” used to be a request to write a Python script. With dbt MCP it is a single call to get_model_lineage_dev in the reverse direction. “Find marts that have no tests” used to be a careful walk through the YAML. With dbt MCP it is one prompt and a filter on get_test_details.
This is also where the semantic layer earns its keep, separately from MCP. If your project has metrics defined, the agent can query their values through query_metrics the same way a BI tool would. The numbers are governed by your metric definitions, not by whatever SQL the agent happened to generate. That closes the loop on the “AI text-to-SQL hallucinated my revenue” problem that plagues raw SQL agents: when the metric is defined in dbt, the agent has to use the definition. It cannot invent its own.
Validation as part of the same flow
The last piece that makes this workflow click is that validation happens in the same context as exploration.
When the audit memo was drafted, I asked Claude to verify each claim. It ran get_model_children on the model I had marked as orphaned and confirmed there were no consumers. It ran query_metrics against the canonical revenue metric for two specific dates the finance team had flagged. It ran get_test_details on the candidate models and confirmed which had unique-key tests and which did not. Every claim in the memo had a tool call behind it that I could re-run if I wanted to.
This is a different quality of audit than the typical “I read the code and here is what I think” review. With an agent in the loop, every assertion is checkable. Every checked assertion gets folded into the doc. The doc becomes a thing the team can re-run in three months to see what changed, instead of a snapshot that goes stale the moment someone merges a PR.
The other byproduct: the prompts you use become a reusable library. The third time I ran “inventory the marts and flag ones with no consumers” on a different project, it was a paste from my notes. The fifth time, I had built a short prompt sequence that audits an unfamiliar dbt project in under an hour. Most data teams reinvent that work every time someone new starts. With MCP and a prompt library, you stop reinventing it.
What dbt MCP cannot do (yet)
I am not going to pretend this is a finished product. Here is what does not work as well as you would hope.
The “experimental” label is still on the box. dbt Labs ships breaking changes between versions more often than a stable product would. Read the release notes when you upgrade. Pin a version in your config if you want stability. Do not wire an experimental MCP to a production agent loop without guardrails.
Tool selection is imperfect. The agent sometimes reaches for raw SQL when querying the semantic layer would be more correct, and sometimes the other way around. In a long session it will cycle, calling lineage tools in the wrong order, or pulling model details for the wrong model and then doubling back. Most of this is recoverable in conversation. Some of it is not, and you have to start a fresh session. The shorter and more specific your prompts, the better the agent does.
SQL execution goes through dbt show. When the agent runs a query against the warehouse via the MCP, it routes through dbt show, which is fine for small results and slow for large ones. If your prompt asks for a million-row sample, you will wait. The fix is to phrase queries with aggregations and LIMITs, not raw scans. dbt Labs has said better execution paths are coming.
Remote mode has the Copilot credit gotcha I mentioned earlier. text_to_sql consumes Copilot credits, and credit exhaustion blocks the entire Remote server, not just text_to_sql. The error message does not always make this obvious. If your Remote MCP suddenly stops working across the board, check your Copilot quota first.
Local setup on Windows is the most common failure mode. The uvx path resolution, the way Claude Code reads environment variables, the encoding of paths with spaces in them: these all bite Windows users disproportionately. If you are on Windows, follow the dbt-mcp README exactly and prefer absolute paths everywhere. The same setup on macOS or Linux is essentially copy-paste.
Auth sprawl is real. Local mode wants up to 5 environment variables. The values come from different parts of the dbt Platform UI. None of them are labeled with names that match the env var names. The first time you set this up you will paste the wrong value into the wrong field at least once. The guide walks through where each one lives.
None of these are dealbreakers. They are the actual texture of working with this tool today. If you go in expecting magic, you will be disappointed. If you go in expecting a tool that gives an analytics engineer significantly more reach without changing what they do at the architectural level, you will be very happy.
Debugging when things go wrong
A few patterns I have hit and how to fix them, since they will probably bite you too.
The MCP is not visible after restart. The most common cause is registering it in the wrong config file. Claude Code reads ~/.claude.json at user scope, not ~/.claude/mcp.json (despite the name). The CLI command claude mcp add dbt -s user -- is the cleanest way to register at user scope. If the server is listed but every tool call returns “server not running,” the second most common cause is that uvx is not on the PATH that Claude Code can see. Use an absolute path to uvx in the command field if you hit this.
Tool returns “no models found.” Usually means the DBT_PROD_ENV_ID is pointing at an environment with no successful deploys, or at the wrong environment entirely. Confirm the ID by opening the deploy environment in dbt Platform and reading it out of the URL. Re-check that DBT_TOKEN belongs to a user with at least Developer access on that environment.
Lineage looks stale. Local mode reads from the project’s target/manifest.json. If you have not run dbt parse recently, the manifest is stale and the agent will see stale lineage. Re-parse before any audit session: dbt parse takes seconds and refreshes the artifact the MCP reads from.
Authentication fails on Discovery API calls. The token must be a Platform service token, not a Cloud user-level personal access token. The two look similar in the UI but only the service token works for Discovery. If you see 401 errors that go away when you regenerate the token, you generated the wrong type the first time.
Tool calls run but return surprising results. get_model_lineage_dev includes ephemeral models in the graph, which sometimes makes the chain longer than you expected. get_mart_models uses the mart_ prefix convention by default; if your project uses a different naming scheme, the tool returns fewer marts than you have. Read the tool docstrings the first time you hit a surprising result. They are usually explicit about edge cases.
These are the failure modes worth knowing about up front. None of them are blockers. They are the kind of friction you stop noticing after a week of use. The dbt community Slack channel #tools-dbt-mcp is responsive when you hit something weirder.
The bigger picture
Here is the thing I have been thinking about since I started using this.
The hardest part of analytics engineering is not writing SQL. It is keeping the mental map of a project in your head, especially across people and across time. The model behind a number, the model behind that model, the test that catches the edge case, the macro that does the timezone arithmetic, the saved query that pulled the version a stakeholder was looking at three weeks ago: all of that lives somewhere, but the cost of looking it up is high enough that most teams just do not, most of the time. They guess. They ask the person who wrote it. They write a new model alongside the old one because re-using the existing one is too expensive to figure out.
What dbt MCP does is make the cost of looking it up close to zero. The lineage is one prompt. The model details are one prompt. The metric values are one prompt. The mental-map work that used to take an afternoon for someone new to the project now takes about 10 minutes for an agent doing it on their behalf. The senior analytics engineers in your team are no longer the only people who can answer “where does this number come from.” Anyone with the MCP can.
That is a structural shift. It is not “the agent writes SQL faster than the analyst.” It is “the project becomes legible to people who would never have parsed it on their own.” Stakeholders can ask the agent questions and get correct answers. Junior analysts can onboard themselves. The fractional consultant can show up on day one and start producing value because the project is suddenly self-documenting.
This is what dbt Labs is betting on with the dbt Agents launch in December 2025. The Remote MCP is the substrate. The agents are the application layer. The pitch is that governed dbt definitions are the right context for AI agents working with data, because the definitions encode what the business actually means by “revenue” or “active customer” or “churn.” The MCP makes that context reachable by any agent, not just dbt’s own.
I am starting to use a simple heuristic when I evaluate data tooling for clients: can an MCP-enabled agent reach this? If yes, it is compatible with where the stack is going. If no, it is a candidate for replacement. dbt’s MCP is a bet on the same direction Fivetran made and Metabase made earlier this year, and the bet looks correct.
For analytics engineers worried about the job, my honest take is: nothing here threatens the people who can architect models and ask hard questions about what a number means. It threatens the role of “person who manually answers lineage questions in Slack three times a day.” Those tasks are now agent work. The rest of analytics engineering becomes more interesting, because the parts you used to skip for time reasons (proper test coverage, clear docs, refactoring brittle code) become viable when the mechanical cost of understanding the existing project collapses.
There is a related shift in how data teams should think about documentation. Your model descriptions, your column docs, your metric definitions are not just human-readable metadata. They are agent context. A well-described model is a model the agent can reason about correctly. A cryptic model with no description and no tests is a model the agent will guess wrong about. The investment in documentation that data teams have always under-prioritized starts paying off in a new way: it makes the rest of the team, and any agent they wire up, smarter.
What I would actually recommend
If you have a dbt project and you are curious, do this:
- Spend 15 minutes installing the Local MCP on your laptop, pointed at your dev project. Use a read-only Platform service token. The free guide walks through every step.
- Ask Claude to inventory the project. List the marts. Flag the ones with no consumers. Surface models that have no tests. This is the kind of audit most teams have been meaning to do for 6 months.
- Pick one lineage question that usually takes you 30 minutes. Ask the agent. See how close it gets. Verify by hand.
- If you are impressed, set up Remote MCP for the business stakeholders who keep asking your team “where does this number come from.” The Remote experience is built for them, not you.
- Build a small prompt library as you go. The fifth time you run an audit, you will want the prompts memorized.
That is the on-ramp. After a week of this, you will have a feel for what the agent does well and where it falls down, and you can decide how much further to invest.
The free setup guide is here: valiotti.com/dbt-mcp-guide. It includes the JSON configs for Claude Code, Claude Desktop and Cursor, a Local vs Remote decision tree, 12 starter prompts grouped by use case, the troubleshooting table, and a pre-flight checklist for getting your dbt project MCP-ready.
If you would rather skip the DIY and have us configure it for your team, including custom prompts, governance patterns, a Remote rollout to non-technical stakeholders, and a working session to train your data team: book a 30-minute discovery call. Most engagements like this take a single working day to ship.
Questions data leads ask before they adopt this
Q01Is dbt MCP free to use?
Yes. The server is Apache 2.0 open source. Local mode runs on your laptop with zero usage fees. Remote mode is included with any dbt Platform plan that has it enabled. The only metered surface is text_to_sql in Remote mode, which consumes dbt Copilot credits, and if those run out the rest of the Remote tools stop working until the credits refresh.
Q02Do I need a dbt Cloud (Platform) account?
Only for the cloud-side tools. The CLI tools and Codegen work against a local dbt Core project with no Platform account at all. The Discovery API, Semantic Layer, Admin API and Remote mode all require a Platform account and a service token. Most teams want both: Core for the dev loop, Platform for lineage and metrics.
Q03How do I stop the agent from running anything in production?
Two layers. Remote mode has no CLI surface, so by construction the agent cannot trigger dbt run or dbt build through it. For Local mode, use Claude Code’s per-tool permission allowlist: approve read-only tools (get_model_lineage, get_model_details, list_metrics, get_all_models) and never approve dbt run, dbt build, dbt clone against a production target. Point the Local MCP at a dev profile, never prod credentials.
Q04Does it work with Claude Desktop and Cursor too?
Yes. It is a standard MCP server, so any compliant client works: Claude Code, Claude Desktop, Cursor, Windsurf, Zed. The connection config differs per client (JSON in Claude Code and Desktop, settings UI in Cursor) but the tool surface is identical. The companion guide has copy-paste configs for all three.
Q05Does my dbt code get sent to Anthropic?
The MCP server runs locally (or inside dbt Platform for Remote). It does not ship your project files anywhere on its own. What does flow to Anthropic is whatever the model needs as context to answer your prompt: model names it inspected, SQL snippets it read, lineage edges. If that is sensitive for your org, treat MCP responses the same way you treat any code you paste into Claude, and check your org’s data handling settings on the Anthropic side.
Q06Local or Remote: which one should I install first?
Local. It is roughly 5 minutes from uvx install to your first lineage query, you get the full CLI surface, and you can run it against your dev project without involving your team. Once you have a feel for what the agent does well, set up Remote for the business stakeholders who want to ask questions of the Semantic Layer without touching a terminal.
Nick Valiotti is the founder of Valiotti Data. He has been building data teams and analytics infrastructure for over a decade, and now helps companies wire AI agents into their data stack the right way.
About the author
Nick Valiotti is the founder of Valiotti Data. 15+ years building analytics infrastructure for SaaS, marketplaces, and consumer subscription. 50+ production deployments across BigQuery, Snowflake, dbt, Metabase, and modern BI stacks. Author of two books on data strategy. LinkedIn · Discovery call.