通过 CLI 直连 PostgreSQL,填补只读 MCP 服务的写操作能力空缺,并为危险操作提供统一的安全护栏。
> ⚠️ Agent 必读:在执行 DROP / TRUNCATE / 无 WHERE 的 DELETE·UPDATE / 大范围 DML / prod 环境写操作 时,必须遵守下文《🚨 高危 SQL 强制人类确认协议》,分三步执行,严禁一次性把 dry-run 与 --confirm 合并执行、严禁自行补齐 --confirm 直接提交。
pg_query.py 执行 SELECT / WITH / EXPLAIN,自动追加 LIMIT 100pg_execute.py 执行 INSERT / UPDATE / DELETE / DDL,默认 dry-runpg_schema.py 输出列 / 主键 / 索引 / 外键pg_list.py 列出 schema 下所有表 + 行数估算pg_init.py 生成 / 补齐凭据文件# 1. 首次使用:生成凭据模板(密码字段留空,由用户手动填入)
python3 scripts/pg_init.py
# 2. 查询数据
python3 scripts/pg_query.py --env test --sql "SELECT count(*) FROM my_table"
# 3. 查看表结构
python3 scripts/pg_schema.py --env test --table my_table
# 4. 执行写操作(先 dry-run 看看影响多少行,确认后加 --confirm 真正提交)
python3 scripts/pg_execute.py --env test --sql "UPDATE foo SET x=1 WHERE id=2"
python3 scripts/pg_execute.py --env test --sql "UPDATE foo SET x=1 WHERE id=2" --confirm
所有脚本均使用 Python 3 + psycopg2-binary,首次运行若缺少依赖会打印 pip install psycopg2-binary 提示后退出。
scripts/pg_init.py —— 凭据初始化生成或补齐 ~/.codebuddy/postgres-cli/credentials.json,自动 chmod 600。若文件已存在,不会覆写已填的密码。
参数:
--env :要补齐的环境名,默认 test(内置骨架仅 test;其它环境名可手动新增到 JSON 中)scripts/pg_query.py —— 只读查询参数:
--sql (必填):SELECT / WITH / EXPLAIN / SHOW / VALUES / TABLE 开头--env :默认 test--no-limit:关闭自动追加 LIMIT 100--format table|json|csv:默认 table,table 中 NULL 显示为 NULL--quiet:仅输出结果(不输出连接横幅与耗时)--host/--port/--database/--user/--password若 SQL 不是只读 → 报错并提示改用 pg_execute.py。
scripts/pg_execute.py —— 写操作(默认 dry-run)参数:
--sql (必填):INSERT / UPDATE / DELETE / DDL--env :默认 test--confirm:真正 COMMIT(不加则仅 dry-run + ROLLBACK,打印预估影响行数)--force:允许高危语句(DROP TABLE / TRUNCATE / DROP DATABASE / DROP SCHEMA / DROP INDEX / ALTER TABLE ... DROP)--confirm-prod:当 env 名包含 prod 时必须追加若 SQL 是 SELECT 等只读语句 → 报错并提示改用 pg_query.py。
scripts/pg_schema.py —— 表结构参数:
--table (必填)--schema :默认 public--env :默认 test--format table|json|csv:默认 table输出分 4 段:Columns / Primary Key / Indexes / Foreign Keys(json 格式则合并为单个对象)。
scripts/pg_list.py —— 列出表参数:
--schema :默认 public--pattern :按 LIKE 过滤表名(例:--pattern "my_prefix%")--env :默认 test--format table|json|csv:默认 table> 本协议是本 skill 最重要的使用规范。Agent(AI 助手)在执行高危 SQL 时,严禁一次性把所有参数凑齐后直接提交,必须分三步执行,并在 Step 2 处显式回到用户等待确认。
DROP TABLE / DROP SCHEMA / DROP DATABASE / DROP INDEX / DROP VIEW / DROP FUNCTIONALTER TABLE ... DROP COLUMN / ALTER TABLE ... DROP CONSTRAINTTRUNCATEDELETE FROM xxx;(无 WHERE) / UPDATE xxx SET ...;(无 WHERE) / WHERE 1=1 / WHERE trueprod / production 的写操作(即使是普通 UPDATE / DELETE)先执行 dry-run,了解影响面:
# 高危 DDL:仅加 --force,不加 --confirm
python3 scripts/pg_execute.py --env test --sql "DROP TABLE public.ai_test" --force
# 大范围 DML:先 dry-run 看影响行数
python3 scripts/pg_execute.py --env test --sql "UPDATE foo SET bar=1 WHERE dept='X'"
对于 DDL(如 DROP TABLE),dry-run 不会返回行数(返回 -1),Agent 必须额外执行一条 pg_query.py 来告知用户"这张表里还有多少行、占多少空间":
python3 scripts/pg_query.py --env test --sql "SELECT count(*) AS rows FROM public.ai_test"
python3 scripts/pg_query.py --env test --sql "SELECT pg_size_pretty(pg_total_relation_size('public.ai_test')) AS size"
Agent 禁止在同一轮工具调用里接着执行带 --confirm 的命令。必须在对话中输出一段结构化的确认请求,格式如下:
⚠️ 即将执行【高危 SQL】,请您人工复核后确认:
· 环境:[env=test] <YOUR_HOST>:5432 / <YOUR_DATABASE>
· 操作类型:DROP TABLE(破坏性 DDL,不可回滚)
· SQL 原文:
DROP TABLE public.ai_test;
· 影响评估:
- 目标表现有 0 行数据
- 目标表占用 16 kB
- dry-run 返回影响行数:-1(DDL 无行数概念)
❓ 请回复以下之一:
- 「确认执行」/「yes」/「go」:继续 Step 3 真实提交
- 「取消」/「no」/「stop」:中止本次操作
- 「先改一下 SQL …」:我来调整 SQL 重新走 dry-run
Agent 在此刻必须结束本轮,等待用户明确答复。 用户如果只回复"嗯"、"好"、"那就删吧"这种模糊肯定,Agent 应该再追问一次以确保语义无误(特别是 prod 环境与 DROP / TRUNCATE 场景)。
只有在用户显式回复肯定词("确认执行" / "yes" / "go" / "执行" / "确认" 等)之后,Agent 才能追加 --confirm 真正提交:
python3 scripts/pg_execute.py --env test --sql "DROP TABLE public.ai_test" --force --confirm
若目标环境是生产环境(env 名含 prod),还需额外追加 --confirm-prod。
❌ 用户只说了一句"删除 ai_test 表",Agent 就一口气跑完 dry-run + --confirm 全流程,没有回到用户确认。
❌ 用户说"把 foo 表的 status 都改成 1",Agent 直接跑带 --confirm 的 UPDATE,没有展示影响行数、没有让用户复核 SQL。
❌ dry-run 显示将影响 50000 行,Agent 未提示用户"影响面超出阈值,请确认"就继续执行。
❌ Agent 将 Step 1 / Step 2 / Step 3 合并到同一次工具调用批次里(这会让用户没有插手机会)。
✅ Step 1 跑完 dry-run → 结束工具调用 → 输出 Step 2 格式化确认文本 → 停下等用户 → 收到用户"确认执行" → Step 3 追加 --confirm 提交 → 回报执行结果。
以下安全规则务必严格遵守(程序层护栏,与上方协议配合使用):
pg_execute.py 不加 --confirm 时,所有写 SQL 都在事务中执行后 ROLLBACK,只回显预估影响行数。这是第一道护栏。--force:DROP TABLE / TRUNCATE / DROP DATABASE / DROP SCHEMA / DROP INDEX / ALTER TABLE ... DROP 不加 --force 直接拒绝执行。--confirm-prod:env 名包含 prod 或 production 时会打印醒目横幅并强制要求 --confirm-prod,否则拒绝。*。凭据文件的位置是固定且唯一的:
~/.codebuddy/postgres-cli/credentials.json
严格约束:
.codebuddy/、skills/、references/、plan/、项目代码目录等)创建、复制或粘贴含有密码的文件;.py / .md / .sql 文件里;git add / git commit 方式提交任何含密码的文件。首次使用:
python3 scripts/pg_init.py # 会自动生成骨架并 chmod 600
# 然后手动编辑文件,把 test 环境的 password 填入
凭据文件结构示例(实际密码请自行填写,不要照抄占位符):
{
"test": {
"host": "<YOUR_HOST>",
"port": 5432,
"database": "<YOUR_DATABASE>",
"user": "<YOUR_USER>",
"password": "<YOUR_PASSWORD>"
}
}
新增环境:直接在 JSON 根节点追加新 key 即可,例如:
{
"test": { ... },
"dev": {
"host": "...", "port": 5432, "database": "...", "user": "...", "password": "..."
}
}
非敏感环境元信息(用途说明、host 归属)请记录在 references/connections.md。
命令行参数 > credentials.json。例如临时换一个库:
python3 scripts/pg_query.py --env test --database another_db --sql "SELECT 1"
若遇到连接失败 / 依赖缺失 / SQL 报错等问题,请查阅 references/troubleshooting.md。
共 1 个版本