Provider REST API

Data

Connect Claude to dbt Cloud

Inspect dbt Cloud projects, jobs, environments and runs, and trigger or cancel a run. Toolspoke puts 10 of its actions behind one MCP endpoint that Claude, Cursor, and Codex all speak.

Connection
Provider REST API
Authentication
Service token
Actions exposed
10
Cost per call (typical)
1 credit
Adapter
Maintained by Toolspoke

Connected in three steps

  1. 1

    Install dbt Cloud

    Open the marketplace in your workspace, add dbt Cloud to the project your agents work in, and it appears on the gateway immediately.

  2. 2

    Connect the credential

    Authenticate with service token. Where to get one, and what it has to be able to reach, is the next section.

  3. 3

    Point your agent at the gateway

    Give your client one address, https://toolspoke.com/mcp. Claude Code takes it as a command, Claude and Claude Desktop add it as a custom connector, and Cursor, Codex and VS Code each read it from a config file of their own.

.mcp.json
{
  "mcpServers": {
    "toolspoke": {
      "type": "http",
      "url": "https://toolspoke.com/mcp"
    }
  }
}

One block covers every tool you have installed. dbt Cloud shows up in the client as soon as your policy allows it, and so does everything else you install later.

Where the address goes, per client

Claude Code

Run it in your project, then /mcp to sign in

claude mcp add --transport http toolspoke https://toolspoke.com/mcp
Claude and Claude Desktop

Settings, then Connectors, then Add custom connector

https://toolspoke.com/mcp
Cursor

~/.cursor/mcp.json, or .cursor/mcp.json for one project

{ "mcpServers": { "toolspoke": { "url": "https://toolspoke.com/mcp" } } }
Codex

~/.codex/config.toml

[mcp_servers.toolspoke]
url = "https://toolspoke.com/mcp"
VS Code

.vscode/mcp.json, or the MCP: Add Server command

{ "servers": { "toolspoke": { "type": "http", "url": "https://toolspoke.com/mcp" } } }

What dbt Cloud asks for

Service token. You provide it once, when you install the connector. Toolspoke encrypts it at rest and decrypts it only for the length of a single call, and the gateway attaches it to the outbound request itself, so it is never part of the arguments an agent sends.

Service tokenRequired
dbt Cloud → Account settings → API tokens → Service tokens. Give it the narrowest permission set that covers what you want: Metadata Only or Job Viewer for reads, Job Admin if you intend to trigger runs. dbt accepts this on the Authorization header as either Token or Bearer; this connector sends Bearer.
dbtc_…
Account IDRequired
The number in your dbt Cloud URL after /accounts/. Every route in this connector is scoped to it.
12345
Access URL hostOptional
Host only, no scheme and no path. Leave blank for cloud.getdbt.com. Newer accounts have a per-account regional host such as ab123.us1.dbt.com, ab123.eu1.dbt.com or ab123.au1.dbt.com; single-tenant and VPC installs have their own. dbt Cloud → Account settings → Access URLs shows yours. Pointing this at the wrong host fails as an authentication error rather than as a wrong address.
cloud.getdbt.com

What Claude can do in dbt Cloud

10 actions, each one declared and named by the connector rather than discovered at runtime. A workspace policy grants a person all of them, a hand-picked selection, everything on the read side, everything on the write side, or none.

Reads
8Reads
Writes
0Writes
Destructive
2Destructive

Reads

8

Fetches data and changes nothing.

  • list_projects

    List the projects in the account, with each one's id, name, repository, connection and state. This is the natural first call and the cheapest proof that the service token, the account id and the host all agree - which is why it is the connection test. The project id it returns is what list_jobs, list_runs and list_environments filter on.

  • list_jobs

    List the jobs defined in the account, with each one's id, name, schedule, environment, dbt version and the commands it runs. Narrow by project_id or environment_id - an account with several projects returns everything otherwise. The job id here is what get_job and trigger_job_run take, and what list_runs filters on as job_definition_id. Note that a job's definition is what it is configured to do; whether it last succeeded is a question for list_runs.

  • get_job

    Fetch one job by id, with its full definition: the steps it executes, its schedule, its environment, its threads and timeout, and its triggers. Ids come from list_jobs. Pass include_related with "most_recent_run" to get the job's definition and its last run in one call, which is usually what you actually wanted.

  • list_runs

    List runs, newest last unless you order otherwise. This is where "did the nightly job work" is answered. `status` is a number, not a word: 1 queued, 2 starting, 3 running, 10 success, 20 error, 30 cancelled. Narrow with job_definition_id for one job's history, or project_id for one project's. Pass order_by "-id" with a small limit to get the most recent runs first. Note that include_related here is narrower than on get_run and does not accept run_steps.

  • get_run

    Fetch one run by id, with its status, timings, the commit it ran and what triggered it. Ids come from list_runs, or from the run trigger_job_run returned. include_related accepts trigger, job, environment, repository, run_steps, run_retries, used_repo_cache, repo_cache_restore, audit and debug_logs. For the per-command breakdown of a failure use get_run_steps, which asks for run_steps for you.

  • get_run_steps

    Fetch one run with its steps expanded: every dbt command the run executed, in order, with each one's status, timing and log output. This is the operation to reach for when a run failed and the question is which model broke. dbt has no route that lists a run's steps on their own - the only way to get them is GET on the run itself with run_steps requested, which is exactly what this does, so use it rather than trying to construct a steps URL. Its response is kept out of the audit log because dbt's step logs are raw stdout and routinely quote query text and error rows from the warehouse.

  • list_run_artifacts

    List the artifact paths a completed run produced - manifest.json, catalog.json, run_results.json and the compiled and run SQL for each model. dbt answers with an array of file paths, not the files themselves. Use it to find out what a run left behind and whether docs were generated. Only completed runs have artifacts.

  • list_environments

    List the environments in the account, with each one's id, name, type, dbt version, project and connection. Environments are where jobs run, so this is how you tell a production environment's id from a staging one before filtering jobs or runs by it. This is the v2 account-wide listing; dbt's v3 API lists environments per project instead and returns more fields, which this connector does not use because everything else here is v2.

Destructive

2

Deletes or permanently alters something. Worth granting on purpose.

  • trigger_job_run

    Start a run of a job. Classified destructive, and out of reach of a read-only or a write grant, for two reasons that both hold on every call: the run consumes billable compute from the moment dbt accepts it, and it executes the job's models against a real warehouse, which creates and replaces tables there. It is not undone by cancelling - cancel_run stops it part-way and leaves whatever it already built. `cause` is required by dbt and is written into the run's history as the reason it started, so put something a person reading the run list will understand. The overrides change what this one run does without editing the job: steps_override replaces the job's commands entirely, and schema_override sends the output somewhere other than the job's usual schema. dbt answers with the created run; watch it with get_run.

  • cancel_run

    Stop a run that is queued or in progress. Classified destructive, and refused to a read-only or a write grant, because of what it leaves behind: dbt stops between commands rather than rolling anything back, so a cancelled build can end with some models rebuilt against fresh data and others still holding the previous run's, which is a harder state to reason about than either a finished run or a failed one. The compute already spent is not returned either. Check with get_run first that the run is actually the one you mean and is actually still going; dbt answers with the run object.

What it will not do

Enforced by the gateway rather than left to convention, which is why each of these can be stated flatly.

It cannot call anything else
The 10 actions above are the whole of it. A call to any other name is refused before it reaches dbt Cloud rather than forwarded on, and connecting your account does not add to the list: it is fixed by the connector, not discovered at run time.
It reaches no further than your credential
Toolspoke holds no access to dbt Cloud of its own. Every call carries the credential you stored and nothing besides, so whatever that credential cannot reach, this connector cannot reach either.
It never hears from dbt Cloud
Nothing is pushed to it. There is no webhook, no subscription and no polling, so this connector cannot notice by itself that something changed in dbt Cloud. An agent has to ask.
It does not smooth over provider limits
Toolspoke does not retry, queue or back off around dbt Cloud's own rate limits. A call that dbt Cloud refuses comes back to the agent as a failed call.

Before you connect it

What can Claude do in dbt Cloud?

10 named actions: 8 that only read and 2 that delete or permanently alter something. They include list_projects, list_jobs and get_job. Nothing outside that list is reachable: the connector declares each operation by name rather than proxying whatever an agent asks for.

What credentials does the dbt Cloud connector need?

Service token. The connector asks for service token and account id, and optionally access url host. Values are encrypted at rest and attached to the outbound request by the gateway, so they are never part of the arguments an agent sends and never reach the audit log.

Does the dbt Cloud connector work with Cursor and Codex, or only Claude?

Any client that speaks MCP, and every one of them gets the same 10 actions. There is a single address, https://toolspoke.com/mcp. Claude Code adds it with claude mcp add --transport http, Claude and Claude Desktop take it as a custom connector in settings, Cursor reads it from .cursor/mcp.json, Codex from ~/.codex/config.toml, and VS Code from .vscode/mcp.json. Each of them signs in to the gateway itself, so there is no key to paste.

What does the dbt Cloud connector not do?

The 10 actions above are the whole of it. A call to any other name is refused before it reaches dbt Cloud rather than forwarded on, and connecting your account does not add to the list: it is fixed by the connector, not discovered at run time. Toolspoke holds no access to dbt Cloud of its own. Every call carries the credential you stored and nothing besides, so whatever that credential cannot reach, this connector cannot reach either. Nothing is pushed to it. There is no webhook, no subscription and no polling, so this connector cannot notice by itself that something changed in dbt Cloud. An agent has to ask. Toolspoke does not retry, queue or back off around dbt Cloud's own rate limits. A call that dbt Cloud refuses comes back to the agent as a failed call.

Can I limit which actions an agent can call?

Yes, in two places. The project switches dbt Cloud's actions on and off one at a time, for everyone in the project at once, and the screen groups them by read, write and destructive so turning off everything that deletes is one click. An individual agent key can then be narrowed further, to particular toolkits in a project and to particular actions in a toolkit. Whatever it was granted, a key never reaches a project its owner cannot.

What gets recorded when an agent calls dbt Cloud?

Every attempt, with the agent that made it and the person that agent belongs to, the full request payload, the response payload, the status, the duration, and the credits spent. Values whose key names a secret are masked out before the record is shown to anyone. An operation the connector marks as not retained never has its response body written at all, so the gateway keeps no second copy of what was read.