深入解析 MCP Toolbox 的 postgres-list-triggers 工具:PostgreSQL 触发器清单查询实战
【免费下载链接】mcp-toolboxMCP Toolbox for Databases is an open source MCP server for databases.项目地址: https://gitcode.com/GitHub_Trending/ge/mcp-toolbox
导读
postgres-list-triggers是 MCP Toolbox for Databases(Google 开源的 MCP Server)中面向 PostgreSQL 系列数据源的内置只读工具,用于以 JSON 形式列出数据库中所有非内部触发器及其完整元数据。本文将基于官方文档并结合仓库源码,完整讲解该工具的参数语义、YAML 配置方式、输出字段含义,以及底层基于pg_trigger系统目录的 SQL 实现原理,帮助你快速将其接入自己的 MCP 配置并在 Agent 工作流中高效使用。
工具概述:它能做什么
postgres-list-triggers的核心职责是列出数据库中所有可用的非内部触发器(non-internal triggers),并以结构化 JSON 返回详细元数据。所谓"非内部触发器",即排除了 PostgreSQL 内部为约束、外键等机制自动创建的系统触发器(源码中通过WHERE NOT t.tgisinternal过滤,见 postgreslisttriggers.go)。
通过一次调用,你可以同时获得触发器的以下信息:
- 触发器名称、所属 schema、绑定的表名;
- 触发器当前启用状态(
ENABLED/DISABLED/REPLICA/ALWAYS); - 触发时机(
BEFORE/AFTER/INSTEAD OF); - 触发事件(
INSERT/UPDATE/DELETE/TRUNCATE); - 激活粒度(按
ROW还是按STATEMENT); - 触发执行的处理器函数名;
- 触发器的完整 SQL 定义(
pg_get_triggerdef输出)。
这使它可以作为数据库巡检、变更审计和 schema 文档生成场景中的便捷只读工具,且不会对数据库产生任何写操作(其注解为只读权限,见源码tools.NewReadOnlyAnnotations)。
输入参数说明
工具接收 4 个可选输入参数,均通过 LIKE 模糊匹配或数量限制来控制返回结果:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
trigger_name | string | "" | 按触发器名称过滤,输入作为LIKE '%<input>%'模式使用 |
schema_name | string | "" | 按 schema 名称过滤,输入作为LIKE '%<input>%'模式使用 |
table_name | string | "" | 按表名过滤,输入作为LIKE '%<input>%'模式使用 |
limit | int | 50 | 返回触发器的最大数量 |
这组参数的默认值在源码中被显式定义(postgreslisttriggers.go):三个字符串参数默认空串,limit默认 50。所有参数均为可选,留空时不参与过滤,即默认返回全库最多 50 条触发器记录。
从源码看,参数采用parameters.NewStringParameter/parameters.NewIntParameter构造,并注册为工具 Manifest 中的声明(allParameters.Manifest()),这意味着它们会作为 MCP 工具入参暴露给 Agent,Agent 可以在调用时按需填入过滤条件。
YAML 配置示例
在 MCP Toolbox 的配置体系中,工具通过 YAML 片段声明(kind: tool)注册。以下配置来自官方文档示例:
kind: tool name: list_triggers type: postgres-list-triggers source: postgres-source description: | Lists all non-internal triggers in a database. Returns trigger name, schema name, table name, wether its enabled or disabled, timing (e.g BEFORE/AFTER of the event), the events that cause the trigger to fire such as INSERT, UPDATE, or DELETE, whether the trigger activates per ROW or per STATEMENT, the handler function executed by the trigger and full definition.其中:
name:工具在当前 MCP 服务中的标识名(可自定义,例如上面命名为list_triggers);type:必须为postgres-list-triggers,用于告诉 MCP Toolbox 加载哪个工具实现;source:必须指向一个已声明且与该工具兼容的 PostgreSQL 系数据源(如postgres-source);description(可选):传递给 Agent 的工具描述,若省略,源码会自动填充一段默认描述(postgreslisttriggers.go)。
source字段的解析逻辑在 Config 中为required校验项,type同样必填;源码通过tools.Register("postgres-list-triggers", newConfig)完成工具类型的注册(见 postgreslisttriggers.go)。
该配置的正确性在单元测试中得到验证:测试用例解析包含kind: tool / name / type / source / description / authRequired的 YAML,并与期望的postgreslisttriggers.Config结构逐字段比对(postgreslisttriggers_test.go),其中也验证了未提供authRequired时默认解析为空列表的行为。
输出结构:JSON 返回字段
工具调用成功后会返回一个 JSON 数组,每个元素对应一条触发器记录,字段如下:
{ "trigger_name": "trigger name", "schema_name": "schema name", "table_name": "table name", "status": "Whether the trigger is currently active (ENABLED, DISABLED, REPLICA, ALWAYS).", "timing": "When it runs relative to the event (BEFORE, AFTER, INSTEAD OF).", "events": "The specific operations that fire it (INSERT, UPDATE, DELETE, TRUNCATE)", "activation_level": "Granularity of execution (ROW vs STATEMENT).", "function_name": "The function it executes", "definition": "Full SQL definition of the trigger" }各字段语义:
trigger_name:触发器名称(pg_trigger.tgname);schema_name:触发器所在 schema(所属表的命名空间);table_name:触发器绑定的表名;status:当前激活状态,对应 PostgreSQLtgenabled枚举(O=ENABLED、D=DISABLED、R=REPLICA、A=ALWAYS);timing:相对事件的执行时机(BEFORE / AFTER / INSTEAD OF);events:触发触发器的事件列表,多个事件以,分隔;activation_level:执行粒度,ROW表示行级触发器,STATEMENT表示语句级触发器;function_name:触发器执行的处理器函数名(pg_proc.proname);definition:通过pg_get_triggerdef()生成的触发器完整 SQL 定义,可直接用于重建该触发器。
源码级原理:底层 SQL 实现
postgres-list-triggers的实现非常直观——它本质上是将一段固定的、经过参数化的查询语句交给数据源执行,再原样返回查询结果(source.RunSQL(ctx, listTriggersStatement, sliceParams),见 postgreslisttriggers.go)。核心 SQL 定义在 postgreslisttriggers.go。
查询基于 PostgreSQL 系统目录pg_trigger(触发器)、pg_class(表)、pg_namespace(schema)和pg_proc(函数)完成:
WITH trigger_list AS ( SELECT t.tgname AS trigger_name, n.nspname AS schema_name, c.relname AS table_name, CASE t.tgenabled WHEN 'O' THEN 'ENABLED' WHEN 'D' THEN 'DISABLED' WHEN 'R' THEN 'REPLICA' WHEN 'A' THEN 'ALWAYS' END AS status, ... p.proname AS function_name, pg_get_triggerdef(t.oid) AS definition FROM pg_trigger t JOIN pg_class c ON t.tgrelid = c.oid JOIN pg_namespace n ON c.relnamespace = n.oid LEFT JOIN pg_proc p ON t.tgfoid = p.oid WHERE NOT t.tgisinternal ) SELECT * FROM trigger_list WHERE ($1::text IS NULL OR trigger_name LIKE '%' || $1::text || '%') AND ($2::text IS NULL OR schema_name LIKE '%' || $2::text || '%') AND ($3::text IS NULL OR table_name LIKE '%' || $3::text || '%') ORDER BY schema_name, table_name, trigger_name LIMIT COALESCE($4::int, 50);几个值得注意的实现细节:
- 位掩码解码
tgtype:PostgreSQL 用单个整数tgtype编码触发器的时机、事件和粒度。源码通过位运算解析——& 2判定 BEFORE、& 64判定 INSTEAD OF、其余为 AFTER;& 4/& 16/& 8/& 32分别对应 INSERT / UPDATE / DELETE / TRUNCATE 事件;& 1区分 ROW 与 STATEMENT。concat_ws将命中的事件拼接为逗号分隔列表。 - 参数化与 NULL 语义:三个过滤条件使用
$1/$2/$3占位符,且采用$n::text IS NULL OR ...写法——当对应参数为空串时,参数值实际上以 NULL 语义处理,从而跳过该过滤条件。结合parameters.GetParams的标准参数提取流程(postgreslisttriggers.go),工具对 SQL 注入有参数化防护。 - 稳定排序与上限:结果按
schema_name, table_name, trigger_name排序,保证输出确定性;LIMIT COALESCE($4::int, 50)保证即使传入非法 limit 也有兜底 50 条。 - 排除内部触发器:
WHERE NOT t.tgisinternal确保只返回用户自定义触发器,避免约束触发器、外键触发器造成噪音。
兼容的数据源
该工具并非只适用于自建 PostgreSQL。根据官方文档,它兼容以下数据源类型:
- alloydb:AlloyDB for PostgreSQL,参见 docs/en/integrations/alloydb;
- cloud-sql-pg:Cloud SQL for PostgreSQL,参见 docs/en/integrations/cloud-sql-pg。
从源码结构看,这一兼容性由接口约束保证:工具定义了compatibleSource接口,要求数据源实现PostgresPool() *pgxpool.Pool和RunSQL(context.Context, string, []any)两个方法(postgreslisttriggers.go)。在 internal/sources 下,alloydbpg/alloydb_pg.go 与 cloudsqlpg/cloud_sql_pg.go 均实现了这两个方法(后者通过pgxpool连接池执行Query)。如果source指向不兼容类型,Invoke会返回"source used is not compatible with the tool"错误,ValidateSource也会在启动校验阶段报错(postgreslisttriggers.go)。
预置配置中的使用方式
仓库在 internal/prebuiltconfigs/tools/postgres.yaml 中内置了该工具的现成配置:
kind: tool name: list_triggers type: postgres-list-triggers source: postgresql-source它被挂载在名为data的预置 toolset 中(见 postgres.yaml),与execute_sql、list_tables、list_views、list_schemas、list_indexes、list_sequences、list_stored_procedure等工具共同构成数据浏览能力集合。这意味着你只需启用对应的预置配置(如 PostgreSQL 预置配置),即可直接获得list_triggers工具,无需手写 YAML。同样地,alloydb 与 Cloud SQL for PostgreSQL 的预置配置(alloydb-postgres.yaml、cloud-sql-postgres.yaml)也包含该工具。
在集成测试侧,tests/common.go 将"postgres-list-triggers"声明为可用的工具类型常量,供端到端测试引用。
配置字段参考
工具自身在 MCP Toolbox 配置文件中的字段汇总如下:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
type | string | 是 | 必须为"postgres-list-triggers" |
source | string | 是 | 执行查询的数据源名称,须为兼容的 PostgreSQL 系数据源 |
description | string | 否 | 传递给 Agent 的工具描述,省略时使用源码内置默认描述 |
小结
postgres-list-triggers是一个设计简洁、开箱即用的只读诊断工具:四个可选参数完成模糊过滤与数量限制,一次调用即可拿到触发器的完整画像(状态、时机、事件、粒度、处理函数与完整定义),底层以参数化 SQL 查询 PostgreSQL 系统目录保证安全与稳定。无论你是通过预置配置(postgres.yaml中的datatoolset)直接使用,还是手写kind: tool片段接入 AlloyDB / Cloud SQL for PostgreSQL 数据源,都能让 Agent 快速掌握数据库触发器全貌,为运维巡检、变更审计与文档生成提供可靠数据支撑。
【免费下载链接】mcp-toolboxMCP Toolbox for Databases is an open source MCP server for databases.项目地址: https://gitcode.com/GitHub_Trending/ge/mcp-toolbox
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考