dst
Officialdata serve tool (dst)
dst 把你的数据仓库服务给 AI,并为这件事的整个生命周期带来工程最佳实践。 AI 用自然语言提问;dst 根据你的团队写下的定义来回答,并附上产出答案的 SQL、一个置信度评级,以及一张收据。
问题
把 AI 指向一个数据仓库,它就什么都会回答。它从不拒绝回答,而这正是失败模式:一个错误的答案比没有答案更糟。
它去猜测“revenue”是什么意思,然后返回一个数字,看上去和正确答案别无二致。
仅靠上下文无法解决这个问题的。AI 是不确定的,而其他团队、另一个模型,或另一个季度下有效的做法,在你这里未必有效。
唯一知道答案的方法是:在你的数据上,持续地测试它。
解决方案
声明:以版本控制中的文件形式声明你的数据如何被服务。
测试:验证那些对你真正有效的做法。每一个被批准的答案都是一条回归测试,而管线中的每一个开关都可以翻转并重新测量。
部署:只部署通过的内容,经过会大声失败的闸门。
审计:审计所有已经被服务过的内容:谁问了、跑了什么、花了多少。每一个错误都会作为一个新测试自动回流。
由实践者构建,为实践者服务:文件、pull requests、CI 和退出码,而不是一套新工作流。
测试:引擎
生成过程的核心总是不确定的,因此 dst 把测试当成产品本身,而不是后补的环节。
每一条被批准的答案,都是一条回归测试。 一条已认证的答案,就是一个被人担保的问题→SQL 配对。
dst test通过真实生成管线重新提出这个问题,然后把存储的 SQL 和生成的 SQL 都放到你的数据仓库中执行,并对结果。行为也被固定了。
evals/cases.yaml里的用例断言响应的 形态:expect: clarify | refuse | answer。如果一个 lens 开始拒绝明明可回答的问题,或者干脆用猜测代替澄清,它的套件就会失败。每个结果都会被记录。 测试运行都会落入数据库,所以准确率是一个你能看着它在变化的数字,并且每个发布都以它作为门闸:任何比上次发布分数还低的变更,都被拒绝。
管线可以按 lens 调整(答案严格度、自我修复、逐条判断、门控硬度),而每次翻转都可测量:改一处,跑一次 dst test,结果立刻可知。而如果你想知道在你自己的问题集上,哪些部分真正值得保留,内置的试验场会把你的问题集整套跑过管线,每次只剥离掉一个 feature:
python -m services.benchmark --data -./data --strip <feature>。完整的可调面见配置参考。
Related MCP server: RunContext
部署:经过关卡
一个 lens 就是文件。改变一个答案的 diffuse;这就是一次部署,而不是一次编辑:
edit files → dst plan (dry run) → dst apply (gated, atomic)dst plan 会显示一次变更会造成什么,如果 apply 会拒绝它,就以退出码 1 退出:plan 预测 apply 的结局。dst apply 就是一个单一事务:连接会被探测,每个过期的已认证答案都会重新对 live generation 运行,任何失败都意味着 什么都不用发布;之前的那个版本继续对外服务。
版本:每次发布都会为一个 lens 版本做快照;
dst lens log会显示谁在什么时候改了什么(human:ana@corp/token:ci)。回滚就是git revert+dst apply。环境是用来出错的。 每种环境都是一套独立的 dst:你的笔记本、共享查沙盒、生产。让沙盒指向不同的模型、不同的 temperature、不同的数据表,或一套重新撰写定义的解释,跑
dst rotate test,然后比较得分——沙盒只需要在你已有的服务器上dst bootstrap一次。上线就是往生产里应用同一个 git commit;环境之间不会复制任何东西,文件中也没有需要逐环境同步的条款。CI 只用你自己用的那组命令。 exit code 就是接口:PR 任务跑
dst plan;merge 脚本跑dst apply --require-gates;定时任务跑dst test --all和dst drift。一份可直接使用的 GitHub Actions 示例在 环境与 CI 指南。
审计:每条答案都有价格和签名
回执。 每条数据答案都携带一份可移植、HMAC 签名的回执:请求 id、lens、certification、确切 SQL 的哈希。可在之后通过这些 API 在
verify_receiptMCP 工具中验证。拒绝里不带回执:因为拒绝声明明确不做任何数据主张。台账。
dst observe的回答是“谁一直在用它,用它干什么”:每一个调用的题目、SQL、结果、在云计算的两种计价表(AI 和数据仓库)上的成本。已答复、已拒绝、出错分开计数;一次受管控的拒绝是一种结果,把一个错误。访问是被拒绝的。 每一个 allow * 和每一个 deny 都会落入 append-only 审计日志,包含调用者、lens 和原因。
数据仓库的每个角落都在被监视。
dst drift把现在的实况 schema 和已提交的基线做对比,而且把每次变更与读取被改表的全部定义、全体实体相互关联。之后是 exit code:0干净、2无变化,1变更破坏已声明、4还没有基线。的怀疑是一等输入。 Anyone 可以发一个问题来 review;低置信度的答案可以自己用
auto_review标记。AI 法官会先做 triage 三角分类,人再裁判;repair 修复就变成一个文件加一个新测试,把整个闭环完成:
---
config:
theme: base
themeVariables:
fontFamily: "ui-monospace, Menlo, monospace"
fontSize: "14px"
primaryColor: "#faf6ee"
primaryBorderColor: "#b45309"
primaryTextColor: "#292524"
lineColor: "#b45309"
edgeLabelBackground: "#faf6ee"
---
flowchart TD
serve(["an answer is served,<br/>with its receipt"])
doubt["someone doubts it"]
test["it becomes a test:<br/>an approved answer + its check"]
gate["it gates every deploy"]
serve -- "flagged by the asker,<br/>or by dst itself" --> doubt
doubt -- "AI drafts the fix,<br/>a person approves it" --> test
test -- "commit + dst apply" --> gate
gate -- "the corrected answer serves<br/>from then on, and the AI learns from it" --> serve一次被修正的错误,就永远被修正,而且你能证明这一点:被纠正的问题从那个时刻起就被已被认证的 SQL 提供,并且它的测试在 release 每次都会被重跑。注意重点任务请看修正环。
模型
Lens——服务的最小单位。一个使用场景(如流失、销售提成、董事会指标模式)会被描述成你共享的语义资产上的 selects,以及访问规则和自己的时钟。一个 agent 用 natural language 向一个 lens 提问,然后得到一份 grounded 且可引用的答复。
语义文件——实体 and 定义,是一次性写的文件,,每个选择它的 lens 共享。一个指标,一个定义;agent 使用的词是可以变化的,而含义从来不非遗。
在丰富上下文——“在上下文中”被 review 过的回答句就会被每个 lens 传播。entry 条目是刻意的、可追溯的,并且随 lens 一起版本化。
认证的回答——经 review 的 question-to-SQL 对,在匹配时逐句地原样,再由 dst test 当作回归测试重跑,并在每次 dst apply 中重跑。一次被修正确的错误就会成为到这样一个词,这样它就一直是 fixed 的。
治理——访问控制完全用你选择的方式:逐 lens 的 person/group 白名单、逐 caller 的 API key(dst_…)、rate limit、以及在数据库层面强制执行的 tenant 隔离(PostgreSQL RLS)。存储的 warehouse 凭据在 rest 时会被加密。
观测——每次调用都会自上而下被 trace。那个 lens,那个 caller,那个 question,那个 SQL,AI 一致性 + 直接的 warehouse 还分,并又被answered / declined / errored 分开数。答案还能被送去 review:AI 法官审查 reasoning trace,并在需要时快速汇报给人类。
Agents 才是 interface
没有 query UI。真正用你喂的是“agent”:把你的任意 MCP client(Claude
Desktop、Claude Code、Cursor,或者你自己产品里面内置的 agent)连到指向 /mcp 的 guard 上的 /mcp,只需要一个 URL 和一个作用域受限的 dst_… key(见services/mcp/README.md)。每个问题都走同一条受治理的管线,所以无论哪个 agent 问,它得到答案都一样:
agent (Claude Desktop · Claude Code · Cursor · your product's agent)
│ MCP — one scoped dst_… key per person
▼
dst ── lens: semantic model + context + access
│ ground → SQL guard → execute → compose (cited)
▼
your warehouse (BigQuery · Snowflake · Postgres · MySQL · DuckDB)
│
trace + cost + review → Observe人类留在站守,而不是 query 处理路径里:dashboard 才是治理和观察那些 file 所“服务”的驾驶座:review queue,drift 审计、访问、成本。Lens 就是 files 写出来的(dst init → 编辑 → plan/apply),绝不会在 UI 里写。(如果想接 rest API 到 dst 里,也有 REST 门:API reference。)
项目长什么样
项目是这样一组文件:版本化、在 PR 里 review,像 infrastructure 一样地 apply。以下内容是从 dst init 真正生成的 scaffold 里精简略的(scaffold 会把演示语义资源放到 examples/ 下面,所以你可以整体删掉、整那个文件夹也别担忧;那个演示的 lens 本身在 lenses/customer_value/):
name: orders
description: One row per order.
source:
connection: jaffle
table: orders
default_time_field: order_date
primary_key: [order_id]
fields:
- {name: order_id, type: integer}
- {name: customer_id, type: integer}
- {name: order_date, type: date}
- {name: status, type: string}
- {name: amount, type: number, description: Order total (USD).}
metrics:
- {name: revenue, agg: sum, expr: orders.amount, format: currency}
- {name: order_count, agg: count, expr: orders.order_id}
- name: average_order_value
type: ratio
numerator: revenue
denominator: order_count
format: currency
joins:
- {right: customers, on: customers.customer_id = orders.customer_id,
type: left, relationship: many_to_one}一次定义把业务术语绑定给 SQL:
---
metric: repeat_customer
sql: customers.number_of_orders > 1
---
A repeat customer has number_of_orders > 1.而一个 模糊 的定义则会让 dst 去澄清,而不是猜测:
---
metric: value
status: ambiguous
possible_mappings:
- lifetime value — customers.customer_lifetime_value
- order amount — orders.amount
---一下这些 mapping 就足够了:dst 在生成任何东西之前,会在代码里把它们直接长出的澄清,不需要更多配置。
name: customer_value
description: Customer lifetime value and order activity.
connections: [jaffle]
select:
entities:
- name: customers
- name: orders
definitions: [lifetime_value, repeat_customer, value]
model:
temperature: 0.0
answer_mode: balanced
instructions: Select explicit columns.
access:
allow:
- caller: alex # deny-by-default; or `- group: everyone`
eval_gate: block # a failing eval suite blocks the apply
auto_review: unverified # low-confidence answers open review tickets# Served VERBATIM on a match — and each one is a regression test:
# `dst test` re-asks the question and compares against this SQL's result.
- question: How many customers are repeat customers?
sql: SELECT count(*) AS n FROM customers WHERE number_of_orders > 1
- question: What was total revenue?
sql: SELECT sum(amount) AS revenue FROM ordersname: analytics
providers:
anthropic:
type: anthropic
api_key_env: DST_API_KEY_ANTHROPIC
# any openai-compatible endpoint works: deepseek, ollama, vllm, groq …
connections:
jaffle:
type: duckdb
config: {path: fixtures/jaffle_shop.duckdb}
wh:
type: bigquery # or snowflake, postgres, mysql
config: {project: my-gcp-project}
secret_env: DST_API_KEY_WH # an inline key is a parse error$ dst query customer_value "How many customers are repeat customers?"
19 of the 100 customers are repeat customers.
sql: SELECT count(*) AS n FROM customers WHERE number_of_orders > 1
basis: A repeat customer has number_of_orders > 1.
confidence: verified · definition: repeat_customer
$ dst query customer_value "What is the average value of a customer?"
clarify: 'value' is ambiguous in this dataset — lifetime value (total
historical revenue per customer) or order amount (a single order's total)?
- lifetime value — customers.customer_lifetime_value
- order amount — orders.amount拒绝和澄清都算是一种 result 而非 error:dst 更多是要发问,而不是猜。
快速开始
安装包。先决条件:Python 3.12+、Docker(dst 用它自己的 PostgreSQL 运行),以及至少一个 model provider 的 API key:Anthropic 或任何支持 openai 兼容端点的供应商(DeepSeek、Ollama、vLLM、Groq,以及大部分网关)。
pip install dst-core # the CLI is `dst`
dst init analytics --warehouse demo --yes
cd analytics # put your provider key in the generated .env
dst dev # Postgres up + migrate + serve, one command
# in a second terminal, same directory
dst bootstrap --org me --email you@example.com
dst apply
dst query customer_value "How many customers are repeat customers?"dst init 会在一个捆绑的 jaffle DuckDB warehouse 上搭建一整个项目,并且同时保留( apply 和 query 都可以在你连接真实仓库之前就能工作。这个 release wheel 已经带着 migrations 和 dashboard,所以你可以自己 run dst dev,两个都不动,都挂着后端 http://localhost:8000。quickstart 是主路线,并会把这同一套路线引申到您自己的 warehouse。
从源码运行
贡献者的路径:一份源码检出(checkout)、仓库自带的 Makefile,以及由 Vite 构建(而非打包)的仪表盘。前提条件:以上内容,外加 uv、Node 22+ 和 pnpm。
# 1. Backend deps
make install # uv sync
# 2. Configure — create .env in the repo root (see "Configuration" below)
echo 'DST_PROVIDERS={"anthropic": {"type": "anthropic", "api_key": "sk-ant-..."}}' > .env
# openai-compatible works the same:
# {"ollama": {"type": "openai-compatible", "base_url": "http://localhost:11434/v1", "api_key": "unused"}}
# 3. Start Postgres (pgvector), run migrations, seed an org + admin token
make up
make migrate
make seed # prints a dstadm_… admin token — copy it
# 4. Run the API (http://localhost:8000)
make dev然后是仪表盘:
cd apps/web
pnpm install
pnpm dev # http://localhost:5173打开仪表盘,将右上角的 dstadm_… 管理员令牌粘贴进去,即可治理该组织:审核队列、漂移审计、调用方、成本。Lens 本身以文件形式编写:uv run dst init 会在随附的 jaffle DuckDB 数据仓库上生成一个 Lens,因此在连接真实数据仓库之前,uv run dst apply 和 uv run dst query 就能正常工作。源码检出不会把 dst 放到你的 PATH 上——每条命令都以 uv run dst … 的形式运行,Makefile 目标正是这样实现的。
如果要让某个 agent 查询某个 Lens:在 Settings 中签发一个 caller key,把它加入 lens.yaml 中该 Lens 的 allow-list,然后运行 uv run dst apply,最后通过 MCP 连接该 agent。
配置
设置从 .env 加载(见 services/config.py)。常用键:
变量 | 是否必填 | 用途 |
| 是,至少一个条目 | 模型提供方,按名称组织 JSON(BYOK;不要使用以厂商命名的键变量)。类型: |
embedding provider | 上下文功能需要 |
|
| 可选 |
|
| 需要存储凭据时 | 用于加密已存储的数据仓库/上下文凭据的 |
| 本地默认即可 | 应用(强制 RLS、非超级用户)和管理(迁移/种子)连接。 |
| 可选 | 托管仪表盘的身份认证;没有它也不影响本地登录和管理员令牌。 |
数据仓库和检索源凭据不是环境变量:请在 dst.yaml 中用 secret_env 引用声明连接(见 quickstart)。.env.example 由 services/config.py 生成:它是一份完整、永不过时的配置表面。
项目布局
services/ FastAPI app (services.app:app)
api/ control plane (/mgmt/*) + data plane (/v1/*)
contracts/ lens config, semantic model, protocols
connectors/ warehouse connectors
context/ embedding providers + the serving error surface
runtime/ the query pipeline (ground → guard → execute → compose)
reviews/ AI-judge + human review queue
governance/ access policy, credentials, rate limits, audit
mcp/ remote + stdio MCP server (see its README)
apps/web/ React + Vite dashboard
migrations/ Alembic migrations
fixtures/ built-in jaffle DuckDB warehouse开发
命令 | 作用 |
| 启动 / 停止本地 Postgres(pgvector) |
| 应用数据库迁移( |
| 填充一个开发组织和管理员令牌 |
| 在 :8000 上热重载运行 API |
|
|
| 自动格式化 + 修复 |
| 后端测试( |
| 在 :5173 上运行仪表盘 |
架构:FastAPI 后端(lens 配置、context 向量存储、请求 trace、审核)架构基于 Postgres + pgvector,并从你的数据仓库读取数据;结果集本身不会被持久化。trace 保留的是问题、SQL、组合后的答案及其引用;只有 lens 通过 logging.log_samples 开启时,才会保存前几行结果。数据仓库 profiling 同样会存储每列的统计信息和低值列表;exclude_columns 中提到的列只读取其结构,值不会被收集。dst 不会自动分类或脱敏个人数据:不要暴露你不希望值离开你网络的列。仪表盘是一个同源或拆分的 React SPA。
用户文档位于 docs/(quickstart、概念、指南、参考),并发布在 https://www.dataservetool.com;贡献者子系统地图请见 ARCHITECTURE.md。
许可证
Apache-2.0。贡献:CONTRIBUTING.md · 安全漏洞:SECURITY.md · 问题与反馈:github.com/get-dst/dst/issues。
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseNot gradedqualityNot gradedmaintenanceEnables natural language querying of Microsoft Fabric Data Warehouses with intelligent SQL generation, metadata exploration, and business-friendly result summarization. Features two-layer architecture with MCP-compliant server and agentic AI reasoning for production-ready enterprise data access.
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to understand and query your database safely by providing a semantic layer of metadata, with tools to search, explain, validate, and generate safe SQL.2MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to search, explore data lineage, understand business context, and generate SQL queries across an organization's data ecosystem.Apache 2.0
- AlicenseAqualityFmaintenanceA governed SQL gateway that exposes typed tools to AI agents, compiling safe read-only queries from a semantic layer while blocking PII before execution, supporting SQL Server, Postgres, and SQLite.9MIT
Related MCP Connectors
The grounded data layer for any LLM: governed SQL, metrics, lineage and catalog over your data.
Shared, permission-aware company context for AI agents, with provenance, approvals and audit.
Query PostgreSQL databases in plain English — LLM-generated, safety-validated SQL.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/get-dst/dst'
If you have feedback or need assistance with the MCP directory API, please join our Discord server