dbt-agent-layer
Make your dbt metrics queryable by AI agents via MCP.
pip install dbt-agent-layer
cd my_dbt_project
dbt-agent serve
# → MCP server running, connect Claude Desktop, ask questions grounded in real data
Quick start
# 1. Install
pip install "dbt-agent-layer[duckdb]" # or [postgres], [bigquery], [snowflake]
# 2. Initialise (inside your dbt project)
cd my_dbt_project
dbt-agent init
# 3. Build tool registry
dbt-agent build
# 4. Start the MCP server
dbt-agent serve
How it works
dbt project on disk
↓
[Parser] reads manifest.json + schema.yml + metrics.yml
↓
[Generator] produces async Python tool functions per metric
↓
[MCP Server] registers tools, starts server
↓
MCP client (Claude Desktop, any agent) calls tool
↓
[Executor] runs SQL against your warehouse
↓
[Delta + Narrative] enriches raw number with context
↓
MetricResult returned to agent (value + delta + narrative + anomaly flag)
Supported warehouses
| Adapter | Install extra | dbt adapter |
|---|---|---|
| DuckDB | [duckdb] |
dbt-duckdb |
| PostgreSQL | [postgres] |
dbt-postgres |
| BigQuery | [bigquery] |
dbt-bigquery |
| Snowflake | [snowflake] |
dbt-snowflake |
dbt version compatibility
| dbt version | Metric format | Support |
|---|---|---|
| < 1.0 | None | Warns, skips gracefully |
| 1.0 – 1.5 | Legacy metrics: |
Full support |
| 1.6+ | Semantic layer | Full support |
| dbt Cloud | Artifact API | Roadmap (v0.2) |
Claude Desktop setup
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"dbt-metrics": {
"command": "dbt-agent",
"args": ["serve", "--project-dir", "/path/to/your/dbt/project"],
"env": {}
}
}
}
Restart Claude Desktop. You can now ask:
- "What's our MRR this month vs last month?"
- "Show me revenue broken down by channel for Q1 2024."
- "Is churn rate anomalous this month?"
Configuration reference (dbt-agent.yml)
version: 1
project:
dir: "." # path to dbt project
profiles_dir: "~/.dbt" # path to profiles.yml
target: "dev" # dbt target to use
adapter:
type: postgres # postgres | bigquery | snowflake | duckdb
# Connection details pulled from profiles.yml automatically.
# Override individual fields here if needed.
server:
host: "0.0.0.0"
port: 8000
transport: "stdio" # stdio (Claude Desktop) | http (web clients)
metrics:
include: [] # empty = all metrics
exclude: [] # metric names to hide from agents
default_period: "current_month"
compare_to: "prior_period" # prior_period | prior_year
narratives:
enabled: true
style: "concise" # concise | detailed
Environment variable overrides
| Variable | Description |
|---|---|
DBT_AGENT_ADAPTER_TYPE |
Override adapter type |
DBT_AGENT_PORT |
Override server port |
DBT_AGENT_TRANSPORT |
Override transport (stdio/http) |
DBT_AGENT_TARGET |
Override dbt target |
DBT_AGENT_PROFILES_DIR |
Override profiles directory |
CLI reference
dbt-agent init
Detect your dbt project, auto-detect the warehouse adapter, and create dbt-agent.yml.
dbt-agent init [--project-dir PATH] [--adapter postgres|bigquery|snowflake|duckdb]
dbt-agent build
Parse manifest.json, extract all metric definitions, write dbt_agent_tools/manifest_cache.json.
dbt-agent build [--project-dir PATH] [--skip-compile] [--dry-run] [--verbose]
dbt-agent serve
Start the MCP server with all metrics registered as callable tools.
dbt-agent serve [--project-dir PATH] [--port INT] [--transport stdio|http] [--skip-build] [--reload]
Built-in MCP tools (always available)
| Tool | Description |
|---|---|
list_metrics |
List all available metrics with dimensions |
describe_metric |
Full metadata for a named metric |
query_metric |
Generic query when metric name is dynamic |
get_<name> |
Auto-generated per-metric tool (e.g. get_monthly_revenue) |
Each auto-generated tool returns a MetricResult containing:
value+formatted_value(e.g."$142,500")delta— period-over-period comparisonnarrative— factual one-sentence summaryanomaly— statistical anomaly flag (>2σ from baseline)breakdown— dimension breakdown rows (ifbreakdown_byused)sql_executed— exact SQL run (for debugging)
Adding a new adapter
- Create
dbt_agent_layer/executor/mydb_exec.pyimplementingBaseExecutor:from .base import BaseExecutor class MyDBExecutor(BaseExecutor): async def execute(self, sql: str) -> list[dict]: ... async def test_connection(self) -> bool: ... def get_adapter_type(self) -> str: return "mydb"
- Add a case to
executor/factory.py:get_executor(). - Add optional dependency to
pyproject.toml. - Open a PR — contributions welcome!
Development
git clone https://github.com/dbt-agent-layer/dbt-agent-layer
cd dbt-agent-layer
pip install -e ".[dev,duckdb]"
pytest
ruff check .
mypy dbt_agent_layer/
License
Apache 2.0 — see LICENSE.
Roadmap
- v0.2: Result caching, dbt Cloud artifact API, web UI
- Cloud tier: Team collaboration, audit logs, SSO
Metadata
Release files for dbt-agent-layer 0.1.15
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| dbt_agent_layer-0.1.15.tar.gz | 63.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dbt_agent_layer-0.1.15-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 126.4 kB
Release files / dbt_agent_layer-0.1.15.tar.gz
| Download URL | dbt_agent_layer-0.1.15.tar.gz |
|---|---|
| Size | 63.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dcfbc083859c382dc3b4ac599fbceab3665e139c82c7cfe070917cc316d2d611
|
|
BLAKE2b-256 checksum How to use checksums |
c050d20e7f0c098574d0af13dcb7cb633c7b143f54f9d0a202149402380532d7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.9
|
Release files / dbt_agent_layer-0.1.15-py3-none-any.whl
| Download URL | dbt_agent_layer-0.1.15-py3-none-any.whl |
|---|---|
| Size | 62.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0db2fb0e903420b242f0ebba670dca1b79153a809f9d53bce0e4d8fd74f8cfe6
|
|
BLAKE2b-256 checksum How to use checksums |
aaece00407b4ccb8da6b9b747d698e03b88ac447db8c776c857040e76a377a0f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.9
|