mcpField
D
dryrun

dryrun

本地服务
boringsql.com数据库36今天更新

关于 dryrun

dryrun 是面向 AI Agent、IDE 和 CI 的 PostgreSQL 架构分析命令行工具及 MCP 服务。它基于提交到项目中的离线快照提供架构信息,使助手能够验证查询和检查安全性,而无需获得数据库凭据。

主要功能

  1. 01捕获 PostgreSQL 架构快照
  2. 02检查架构规范与结构
  3. 03分析迁移锁和表重写
  4. 04依据架构验证 SQL
  5. 05比较快照并检测偏移
  6. 06通过 MCP 工具提供分析能力

适用场景

  1. 01在部署前检查迁移风险
  2. 02依据项目架构验证生成的 SQL
  3. 03让团队成员无需凭据即可查看架构
  4. 04比较不同版本的架构快照

MCP 相关

MCP 服务读取项目的离线快照,并提供架构探索、查询验证、执行计划分析、迁移检查、规则检查等工具。支持 stdio 或 SSE;部分工具需要连接实时数据库。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"boringsql-dryrun": {
"command": "npx",
"args": [
"-y",
"@boringsql/dryrun"
]
}
}
}
启动命令npx -y @boringsql/dryrun

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@boringsql/dryrun0.20.0

工具

9

收录的工具列表 · 更新于 2 天前

参数类型必填说明
sqlstring是SQL 查询。
plan_jsonobject|array|string否你已有的 EXPLAIN 计划,由用户粘贴或 CI 捕获:EXPLAIN (FORMAT JSON) 返回的 [{"Plan": ...}] 数组,或未包装的 {"Plan": ...} 对象。也接受这两种格式的 JSON 字符串,因为客户端可能会重新编码结构化参数。按原样读取;advise 绝不会重新运行它。
include_index_suggestionsboolean否包含索引建议(默认 true)。

详细介绍

DryRun PostgreSQL MCP

一个无需连接生产环境的 PostgreSQL MCP 服务。

dryrun 为 AI Agent、IDE 和 CI 提供完整的架构信息,基于离线快照,而非实时数据库连接。你可以检查架构、验证查询、检查迁移安全性并探索外键关系图。所有这些都无需让凭据离开 DBA 的机器。

dryrun 是 boringSQL 套件的一部分,与 RegreSQL 和 Fixturize 并列。

问题所在

LLM/AI 编码助手非常擅长编写代码和 SQL 查询,但它们对数据库一无所知。它们不知道你的架构、索引或约束。它们可能会生成一个在你最繁忙的表上获取 ACCESS EXCLUSIVE 锁的迁移,让你的应用停摆。

有些 PostgreSQL MCP 服务会要求你提供数据库连接。要执行管理任务,你可能还需要 SUPERUSER 权限。但这无异于自找麻烦。

我们已经见过这会导致什么:AI Agent 擦除了生产数据库,还有本应只读的 MCP 服务中出现了 SQL 注入漏洞。

模型不需要查询你的数据库,而是需要理解你的架构:结构、约束、统计信息和特定版本的行为。这些知识是结构性的。它会在部署迁移时发生变化,而非在两次查询之间变化。

DryRun 功能

dryrun 提供两种形式:CLI 工具和 MCP 服务。CLI 提取并分析你的架构。MCP 服务将分析结果提供给 AI 助手。它们有意设计为相互独立。

CLI - 提取并分析

CLI 连接到你的 PostgreSQL 数据库,检查完整目录(表、视图、索引、约束、分区、函数、枚举、RLS 策略、触发器、扩展、GUC),并将快照写入 .dryrun/history.db。该快照是其他所有功能的事实来源。

创建快照后,CLI 可以离线运行:

  • Lint - 20 多条约定规则(命名、类型、主键、时间戳、分区)和 13 条结构审计规则(重复索引、外键覆盖、循环外键、vacuum 调优)
  • 迁移安全性 - 锁类型分析、耗时估算、表重写检测,以及每条 DDL 语句的安全替代方案
  • 查询验证 - 通过 libpg_query 解析 SQL,根据实际架构检查列引用,并检测反模式
  • 快照差异 - 比较快照之间的架构、规划器统计信息或活动;检测与实时数据库之间的偏差
  • 查询统计信息 - 按节点采集 pg_stat_statements,将 ORM 查询变体归并为查询形态,对比两次采集结果以找出新增或变慢的查询
  • 多节点统计信息 - 副本级统计信息、seq_scan 热点、路由不均衡
MCP 服务 - 为 AI 助手提供架构知识

MCP 服务读取相同的快照。它通过 stdio 或 SSE 提供 9 个工具:架构探索与搜索、查询验证、执行计划分析、迁移检查、Lint、vacuum 健康检查,以及采集到的 pg_stat_statements 热门查询。连接实时数据库后,还会增加另外 3 个工具(explain_query、check_drift、columnar_report)。AI 助手可以在编写 SQL 时理解你的数据库。

无需数据库连接。助手永远不会看到凭据。

为什么选择离线

Schema 上下文应该放在文件中,而不是实时连接中。 列类型、行数估算、索引定义、FK 关系和 PostgreSQL 版本都可以一次性导出并提交到代码库。由一位有数据库访问权限的人导出 schema。其他所有人,无论是人类还是 AI Agent,都能在无需凭据的情况下获取完整的 schema 信息。

凭据不应该离开 DBA 的机器。 如果 MCP 服务需要 DATABASE_URL 才能发挥作用,那么每位使用它的开发者都需要生产环境凭据。这是一个与 AI 毫无关系的安全问题。

服务应该负责分析,而不是单纯转发。 返回原始的 \d+ 输出,只比自己把它粘贴到聊天中好一点点。真正的价值在于解读这些数据:检查迁移对你的 PostgreSQL 版本是否安全、标记缺少 FK 索引的情况,并根据实际 schema 验证列引用。

安装

需要 PostgreSQL 14 或更高版本。 不会拒绝较旧的服务端——dryrun 会发出警告并尽可能采集信息——但这些版本未经测试,某些数据流(尤其是规划器统计信息)将不可用。最低版本与上游仍受支持的最早版本保持一致。

Homebrew:

Homebrew 6.0 要求先信任第三方 tap,才能加载其中的 formula:

brew trust --tap boringsql/boringsql
brew install boringsql/boringsql/dryrun

在 Homebrew 5.x 及更早版本中,跳过 brew trust 步骤。如果你不想信任整个 tap,可以只信任该 formula:brew trust --formula boringsql/boringsql/dryrun。

npm / npx:

如果你已经安装了 Node,无需安装任何内容即可运行 dryrun:

npx @boringsql/dryrun --version

这会为你的平台(darwin-arm64、linux-x64、linux-arm64)获取预构建二进制文件、将其缓存并打印版本号。要将 dryrun 永久添加到 PATH:

npm install -g @boringsql/dryrun
dryrun --version

npm 包封装了相同的 Go 二进制文件;所有 CLI 命令的行为都完全相同。lint 等命令需要先有 schema 快照——请参阅快速入门。预构建二进制文件支持 macOS(Apple Silicon + Intel)、Linux(x64 + arm64)和 Windows x64。在其他平台(Alpine/musl、Windows arm64)上,请使用 Homebrew 或从源代码构建。

从源代码构建:

需要 Go 1.26+。如果尚未安装,请通过 go.dev/dl 安装。

git clone https://github.com/boringsql/dryrun.git
cd dryrun
go build -o bin/dryrun ./cmd/dryrun

二进制文件位于 bin/dryrun。

30 秒演示

安装 dryrun 后,无需数据库或任何设置,即可对克隆的本仓库中的现成 schema 快照运行 lint:

git clone https://github.com/boringsql/dryrun.git
cd dryrun/examples/demo
dryrun lint

(通过 npm 或 Homebrew 安装,但没有克隆仓库?你将没有 examples/demo——请跳转到快速入门,让 dryrun 使用你自己的 schema。下面的示例输出就是 lint 的结果。)

[ERROR] public.audit_log: table has no primary key
       fix: add a primary key (bigint GENERATED ALWAYS AS IDENTITY recommended)
[WARN ] public.audit_log: gap in range partitions: ends at '2024-07-01' but next starts at '2024-10-01'
       fix: inserts into the gap will fail unless a DEFAULT partition exists
[ERROR] public.task_comments: table has no primary key
       fix: add a primary key (bigint GENERATED ALWAYS AS IDENTITY recommended)
[WARN ] public.projects.created_at: timestamp column uses timestamp without time zone instead of timestamptz
       fix: use timestamptz for timestamp columns
[ERROR] public.tasks.project_id: FK 'tasks_project_id_fkey' on column(s) (project_id) has no covering index
       fix: add an index on FK columns to avoid sequential scans on DELETE/UPDATE
[WARN ] public.users.email: column 'email' uses character varying(255), prefer text
       fix: VARCHAR(n) adds a hidden CHECK constraint with no performance benefit
[WARN ] public.user_notifications: table is missing 'created_at' column
       fix: add: created_at timestamptz NOT NULL DEFAULT now()

26 finding(s): 6 error, 20 warning, 0 info (13 tables checked)

无需数据库。完全基于离线快照运行。

同一个演示也可以通过 MCP 使用。在 examples/demo 目录中,将服务注册到你的助手:

claude mcp add dryrun -- npx -y @boringsql/dryrun mcp-serve

然后在该目录中提问:“我有哪些表,它们有什么问题?”

MCP 服务

只需一条命令,即可将服务接入 AI Agent。setup 会检测 Claude Code、Cursor、Codex 和 Zed,写入 Agent 的 MCP 配置,并在 AGENTS.md/CLAUDE.md 中添加指令,让 Agent 在编写 SQL 前先检查架构:

dryrun setup

要自行选择 Agent,或在非交互式 Shell 中使用,请传入 --agents:

dryrun setup --agents=claude,cursor   # or: all

要手动注册服务:

# for claude code
claude mcp add dryrun -- dryrun mcp-serve

# for codex
codex mcp add dryrun -- dryrun mcp-serve

如果从源代码构建,请使用二进制文件的完整路径:

claude mcp add dryrun -- /path/to/dryrun mcp-serve

或者,无需安装,直接将客户端指向 npx:

claude mcp add dryrun -- npx -y @boringsql/dryrun mcp-serve

这种形式的原始客户端配置如下:

{
  "mcpServers": {
    "dryrun": {
      "command": "npx",
      "args": ["-y", "@boringsql/dryrun", "mcp-serve"]
    }
  }
}

服务会从当前项目的 .dryrun/history.db 中读取最新快照。无需数据库凭据;助手可通过离线快照获取完整的架构信息。

如果没有快照,服务仍会启动,其工具会提示尚未加载架构。使用 dryrun init --db "$DATABASE_URL" 捕获快照,或拉取队友推送的快照(dryrun snapshot pull --from-path ./snapshots,参见快速入门);服务会在下一次工具调用时加载快照,无需重启。

对于有多个数据库的项目,请针对每个数据库运行一次 dryrun mcp-serve,并在客户端配置中为每个服务添加一条配置。在单个 MCP 进程中原生支持多个数据库的功能正在 #7 中跟踪。

有关实时数据库设置、SSE 传输和 Claude Desktop 配置,请参阅教程。

快速入门

有两种入门方式,请选择适合你设置的方式。

选项 A:你可以访问数据库

如果你能连接到 PostgreSQL 实例(本地、开发或生产环境),只需一条命令即可完成所有操作:

dryrun init --db "$DATABASE_URL"

此命令会创建 dryrun.toml(包含 [project] id 和默认配置文件)、.dryrun/ 数据目录,并将数据库快照保存到 .dryrun/history.db。快照以 (project_id, database_id) 为键;如果项目有多个数据库(例如 auth、billing),请在每个配置文件中设置 database_id。完整配置参考请参阅 docs/dryrun-toml.md。

选项 B:其他人可以访问数据库

有凭据的人只需捕获一次快照并推送到共享目录——该目录可以位于仓库中,也可以放在双方都能访问的任意位置:

dryrun init --db "$DATABASE_URL"
dryrun snapshot push --to-path ./snapshots

他们需要同时提交 dryrun.toml 和 ./snapshots。其他人拉取快照:

dryrun snapshot pull --from-path ./snapshots

snapshot pull 会将快照加载到 .dryrun/history.db。他们的机器无需连接数据库。

提交 dryrun.toml 并非可选:快照以 (project_id, database_id) 为键,而 dryrun init 会根据实时数据库名称生成 database_id。队友如果在未使用 --db 的情况下运行 dryrun init,就会得到不同的 database_id;随后 pull 会报告 0 copied,因为它在源端不存在的键下查找快照。

推送的快照除了架构,还包含规划器和活动统计数据,因此依赖大小估算和清理数据的离线工具也能正常工作——普通 JSON 导出则无法做到这一点。如果需要使用注册表而非目录,请参阅 dryrun remote add 和 snapshot push --remote。如需向人工用户或 Agent 提供可读的 JSON,dryrun dump-schema 仍可生成该文件;它是导出文件,不是输入文件。

然后使用
dryrun lint

所有命令都从 .dryrun/history.db 离线运行。每个项目都有自己的 dryrun.toml 和 .dryrun/,没有全局状态。将 .dryrun/ 添加到 .gitignore。

快照存储在 .dryrun/history.db 中,以 (project_id, database_id) 为键。它是唯一的架构来源:MCP 服务、lint 和 drift 都从中读取数据。旧版 dryrun 留下的 .dryrun/schema.json 会被忽略。

数据库以 SQLite 的 WAL 模式运行,因此定时执行的 snapshot capture 可以与长时间运行的 mcp-serve 共用数据库:即使服务正在查询,捕获操作也可以提交,不必等待查询完成。WAL 会在旁边生成 history.db-wal 和 history.db-shm 辅助文件;最后一个进程正常退出时,这些文件会被删除,进程崩溃时则会残留,因此也要将它们与 .dryrun/ 一起忽略。需要注意两点:WAL 模式下的 history.db 即使在执行 lint 这类只读命令时,也需要对 .dryrun/ 有写入权限;WAL 需要共享内存,而网络文件系统不提供共享内存——位于 NFS 或 SMB 上的 .dryrun/ 会自动使用回滚日志(功能正确,但发生争用时速度较慢)。

多节点:从副本捕获活动数据

在主节点上执行 snapshot capture 会写入架构和规划器统计信息。活动计数器(idx_scan、n_dead_tup、最近一次 vacuum)位于各个副本上,因此也要捕获这些数据:

dryrun --profile primary snapshot capture --label primary
dryrun snapshot capture --from "$REPLICA1_URL" --label replica1
dryrun snapshot capture --from "$REPLICA2_URL" --label replica2

在 dryrun.toml 中配置 [[node]] 块后,dryrun snapshot capture --all 就能一次性完成所有捕获。

MCP 的 describe_table(节点明细)和 detect kind=anomalies 工具随后会展示各节点的 idx_scan,方便你发现路由不均衡问题。请参阅 docs/multi-node-stats.md。

每个项目使用多个数据库

dryrun snapshot capture 按 (project_id, database_id) 为快照建立索引。默认值即可使用——project_id 是你的文件夹名称,database_id 是 current_database() 返回的实际数据库名称:

dryrun init --db "$AUTH_DB"            # captures auth
dryrun snapshot capture --db "$BILLING_DB" --label primary # billing gets its own stream
dryrun snapshot list --db "$AUTH_DB"    # only auth snapshots

如需使用稳定的引用(并让 list / diff 无需重新输入 URL 即可运行),请在 dryrun.toml 中声明配置:

[project]
id = "myapp"

[profiles.auth]
db_url = "${AUTH_DATABASE_URL}"
database_id = "auth"

[profiles.billing]
db_url = "${BILLING_DATABASE_URL}"
database_id = "billing"

然后:

dryrun --profile billing snapshot list
dryrun --profile billing snapshot diff --latest

所有配置选项请参阅 docs/dryrun-toml.md。

所有与数据库相关的命令(init、probe、dump-schema、drift、stats apply、所有 snapshot 子命令)都接受 --profile;如果未提供 --db,则使用解析出的配置中的 db_url。lint 是离线命令:它读取 .dryrun/history.db,只有在显式传入 --db 时才会连接实时数据库。

注意: MCP 服务目前仅支持单个数据库。使用默认配置即可。或者,为每个数据库运行一个 dryrun mcp-serve 进程。单个 MCP 进程内原生支持多个数据库的功能正在 #7 中跟踪。

在团队中共享快照

DryRun 在团队协作中的价值更高。多名开发者可以从任何符合 POSIX 标准的目录拉取快照。

要发布快照,你需要

cd project_name

# capture from the live DB (use cwd name for project name)
dryrun init --db "$DATABASE_URL"
dryrun snapshot capture --db "$DATABASE_URL" --label primary
dryrun snapshot push --to-path ./snapshots --all

开发者随后可以将快照导入本地历史记录

dryrun snapshot pull --from-path ./shared/snapshots --all

快照采用内容寻址方式({project}/{database}/{ts}-{hash}.json.zst),并且具有幂等性:重复推送同一个快照不会造成变化。

最简单的部署方式是使用专用的 git 仓库。创建快照仓库,并将 *.json.zst binary 添加到 .gitattributes,以免 git 尝试对比这些数据包。

拉取后,离线工具(lint、check_migration、drift)即可立即使用。

无需服务端,无需凭据。承诺依旧。

将快照推送到 OCI 注册表

任何 OCI 注册表都可以存储快照:GitHub Container Registry、Google Artifact Registry、Amazon ECR、Docker Hub、Harbor 或可自托管的注册表。注册表负责处理身份验证、保留策略和访问控制,因此无需运行服务。

按照使用 docker push 时的方式进行身份验证,注册远程端,然后推送:

docker login ghcr.io
dryrun remote add ghcr --ref ghcr.io/myorg/dryrun --default
dryrun snapshot capture --label primary --push

snapshot capture --push 可一步完成捕获和发布。使用方拉取:

dryrun snapshot pull --remote ghcr

默认情况下,push 和 pull 都只传输最新的一次记录,因此冷拉取(全新的 CI、空的 history.db)和共享存储的成本都很低,无论任一端保留了多少历史记录。使用 --full 同步整个历史记录,或使用 --since 7d(也可使用 2w、24h 或类似 2026-01-01 的 UTC 日期)指定时间范围。无论哪种方式,复制都按内容哈希增量进行,因此按固定周期推送的所有者每次只会上传新的观测数据。

--ref 是注册表基础地址。每个数据库都会在其下拥有自己的仓库:<ref>/<project_id>/<database_id>,因此 myapp 的 auth 数据库会存放在 ghcr.io/myorg/dryrun/myapp/auth。快照会映射为按内容哈希寻址的 OCI 工件,因此重复推送同一个快照不会产生任何变化,注册表中的共享 Blob 也会去重。对于 Google Artifact Registry,请使用 gcloud auth configure-docker us-docker.pkg.dev 代替 docker login;其余步骤完全相同。

身份验证。 默认情况下,dryrun 会复用你的 Docker 凭据(~/.docker/config.json 和凭据助手),因此任何可以通过 docker login 登录的注册表都无需额外配置即可使用。remote add 上的两个覆盖选项可满足其他情况:

  • --token-env VAR 从环境变量读取静态 bearer 令牌,适用于签发短期令牌的注册表(例如,通过 gcloud auth print-access-token 提供给 --token-env GAR_TOKEN)。
  • --auth gcp 直接使用 Google Application Default Credentials,因此在运行 gcloud auth login 后(或通过 GOOGLE_APPLICATION_CREDENTIALS 指定服务账号密钥),即可使用 Google Artifact Registry / Container Registry,而无需运行 configure-docker。ADC 令牌会自动刷新。

有关按配置文件设置远程端以及跨项目共享同一数据流的信息,请参阅 docs/dryrun-toml.md。

更多

  • 教程:了解离线、在线和多节点工作流,并查阅完整的工具参考
  • 多节点统计信息:了解集群范围的统计信息收集、聚合规则和副本失衡检测
  • 查询统计信息:了解 pg_stat_statements 捕获、形状分组和差异比较
  • 匿名化快照:了解如何生成可交给他人的快照,包括 PII 映射、掩码捕获,以及发送前应检查的内容
  • 配置参考:了解 dryrun.toml 配置文件、约定、远程端和 lint 规则
  • CLI 稳定性:了解哪些命令稳定、哪些仍处于实验阶段
  • 安全概览:了解 CLI/MCP 的划分和掩码处理
  • boringSQL:博客和项目主页
  • dryrun 项目页面:概览和文档
  • 别让 AI 接触你的生产数据库:了解大多数 Postgres MCP 为何不安全,以及 dryrun 有何不同
  • RegreSQL:SQL 回归测试工具,也是 dryrun 的配套工具
  • Fixturize:为开发和测试对生产数据进行子集提取和掩码处理

许可证

BSD 2-Clause License

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。