关于 Multigres
Multigres 是用于诊断 Postgres 和运维 Multigres 集群的 MCP 服务。默认提供只读数据库与集群工具,只有在 unrestricted 模式下才开放写入操作。
主要功能
- 01查看架构和数据库对象
- 02执行只读 SQL 并查看查询计划
- 03检查查询统计和索引建议
- 04检查数据库与集群健康状态
- 05在 unrestricted 模式下管理备份和节点
适用场景
- 01诊断慢查询和数据库健康状况
- 02查看索引建议而不创建索引
- 03检查集群状态、日志和备份
- 04在 unrestricted 模式下执行获准的写入或主节点切换
MCP 相关
该服务向 MCP 客户端提供 Postgres 诊断和 Multigres 集群运维工具,并通过 stdio 通信。只有在 unrestricted 模式下才会注册写入工具。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
multigres-mcp
面向 Multigres 集群的 MCP 服务。它向 MCP 客户端提供两组工具:
- 通过 Multigres 网关进行 Postgres 诊断:架构和对象、只读 SQL、带假设索引的查询计划、热门查询、索引建议和健康检查。这些工具遵循 postgres-mcp 的工具。
- 通过 multiadmin 提供集群工具:集群状态、备份、节点日志;在不受限模式下,还可以切换主节点以及启动或过期备份。
该服务默认只读。只有在不受限模式下才会注册写入工具。
已在 Linux 和 Docker Engine 上针对本地 Multigres Docker 集群进行测试。该集群基于提交 49e7a2f7d4fe 构建(2026-11-02,PostgreSQL 17.7,两个 cell)。其他配置尚未测试。
安装
每个发行版本都包含一个 multigres-mcp-<version>.mcpb 文件。它是一个 MCP Bundle:安装 Bundle 的客户端会要求填写“Configuration”下的设置,然后运行该服务。它同时也是一个 zip 文件,其 server/ 目录中包含适用于 Linux 和 macOS(amd64 和 arm64)以及 Windows(amd64)的二进制文件,其他客户端可直接运行这些文件。
构建
需要 Go 1.26 或更高版本。
git clone https://github.com/JoongHyuk-Shin/multigres-mcp
cd multigres-mcp
go build -o multigres-mcp ./cmd/multigres-mcp
该服务通过标准输入和输出进行 MCP 通信。运行 ./multigres-mcp --help 可查看选项。
packaging/build-mcpb.sh 会将发行 Bundle 构建到 dist/。此外还需要 jq、Node.js 和 openssl。
配置
每个选项都可以通过标志或环境变量设置。标志的优先级高于环境变量。
| 标志 | 变量 | 默认值 | 含义 |
|---|---|---|---|
--database-url | DATABASE_URI | 无,必填 | Multigres 网关的连接字符串。 |
--admin-url | MULTIGRES_ADMIN_URL | 无 | multiadmin HTTP 地址。仅在设置此项时才会注册集群工具。 |
--admin-token | MULTIGRES_ADMIN_TOKEN | 无 | 以 --enable-auth 启动的 multiadmin 的 Bearer 令牌。 |
--node-host-map | MULTIGRES_NODE_HOST_MAP | 无 | 用于 read_node_log 的直接节点连接以及 diagnose 和 get_top_queries 的 node 选项的 reported=reachable 主机对,以逗号分隔。multiadmin 报告的每个节点主机名都是集群所见的主机名;此选项会替换服务无法访问的主机名。端口不会更改。 |
--access-mode | MULTIGRES_MCP_ACCESS_MODE | restricted | restricted(只读)或 unrestricted(添加写入工具)。 |
--sql-timeout | MULTIGRES_MCP_SQL_TIMEOUT | 25s | 每个工具发送的 SQL 语句超时。参见“注意事项”。 |
直接节点连接会沿用 --database-url 中的用户名、密码和数据库,并从 multiadmin 获取主机和端口。
在本地 Docker 集群中,两个节点报告的主机都是 localhost,但其 Postgres 端口只能通过容器地址访问。在 Multigres 检出目录中运行以下命令查找该地址:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$(docker compose ps -q multigres)"
并将其作为 --node-host-map localhost=<address> 传入。
添加到 MCP 客户端
使用 Claude Code 连接本地 Docker 集群时(将 172.18.0.2 替换为上文找到的地址):
claude mcp add multigres -e DATABASE_URI=postgres://postgres:postgres@localhost:15432/postgres -- /path/to/multigres-mcp --admin-url http://localhost:15000 --node-host-map localhost=172.18.0.2
其他客户端可在其服务配置中使用相同的命令、参数和环境变量,例如:
{
"mcpServers": {
"multigres": {
"type": "stdio",
"command": "/path/to/multigres-mcp",
"args": ["--admin-url", "http://localhost:15000", "--node-host-map", "localhost=172.18.0.2"],
"env": {
"DATABASE_URI": "postgres://postgres:postgres@localhost:15432/postgres"
}
}
}
}
工具
| 工具 | 模式 | 功能 |
|---|---|---|
list_schemas | 两种模式 | 列出架构。multigres 架构是 Multigres 内部使用的。 |
list_objects | 两种模式 | 列出架构中的表、视图、序列或扩展。 |
get_object_details | 两种模式 | 获取表或视图的列、约束和索引,或序列、扩展的详细信息。 |
execute_sql | 两种模式 | 运行一条只读语句(SELECT、SELECT 的 EXPLAIN 或 SHOW)。两种模式下都只读取数据。 |
explain_query | 两种模式 | 获取查询计划,可选是否使用 ANALYZE 或假设索引。对于带有 $1 占位符的查询(如查询统计信息中存储的查询),会生成通用计划。 |
get_top_queries | 两种模式 | 分别显示来自 pg_stat_statements 和各网关所保留查询统计信息中的最慢或开销最高的查询。 |
analyze_workload_indexes | 两种模式 | 通过比较规划器成本与假设索引的成本,为 pg_stat_statements 中的工作负载提供索引建议。不会创建任何内容。 |
analyze_query_indexes | 两种模式 | 对最多 10 条指定查询执行相同的分析。 |
diagnose | 两种模式 | 健康检查:膨胀、清理、锁、活动、等待、慢查询、缺失索引、缓存、日志、索引健康状况、序列、复制和约束。检查结果会先显示应答节点的统计信息周期。 |
cluster_status | 两种模式,需提供 --admin-url | 单元、数据库、每个分片的主节点和副本(含 LSN 和延迟)、网关、协调器、近期主节点变更,以及已连接用户是否为超级用户。 |
list_backups | 两种模式,需提供 --admin-url | 列出分片的备份。 |
verify_backups | 两种模式,需提供 --admin-url | 对分片的备份运行 pgBackRest verify,检查存储库中的备份和归档 WAL 是否有效。不会执行恢复。 |
get_backup_job_status | 两种模式,需提供 --admin-url | 获取备份作业状态。 |
read_node_log | 两种模式,需提供 --admin-url | 通过与节点的直接连接读取该节点 Postgres 日志的末尾内容。 |
execute_write_sql | 不受限 | 运行一条可能更改数据或架构的语句;成功时提交。 |
switch_primary | 不受限,需提供 --admin-url | 请求 Multigres 切换分片的主节点,然后报告旧主节点、新主节点和任期。Multigres 可能会再次选举同一节点;工具会说明这一点,且不会重试。 |
create_backup | 不受限,需提供 --admin-url | 启动备份并返回其作业 ID。 |
expire_backups | 不受限,需提供 --admin-url | 根据集群中配置的保留规则使备份过期。 |
set_postgres_restarts | 不受限,需提供 --admin-url | 开启或关闭节点上的 Postgres 自动重启。 |
受限模式下共有 14 个工具,不受限模式下共有 19 个;不提供 --admin-url 时,分别有 9 个和 10 个。diagnose 和 get_top_queries 可选接收一个 node,以直接读取单个节点,而不是通过网关读取;例如,在故障转移后读取旧主节点。
安全性
受限模式不会注册任何可写入的工具。编写 SQL 本身就是一个独立工具 execute_write_sql,因此,即使服务器以无限制模式重启,授予客户端使用 execute_sql 的权限也绝不会涵盖写入操作。
execute_sql、explain_query 和 analyze_query_indexes 收到的每条语句都会通过以下检查。这些检查彼此独立:检查 1、3 和 4 均可单独阻止写入。
- 使用 Multigres 解析器解析语句。语句必须且只能包含一条语句,顶层语句必须是
SELECT、针对SELECT的EXPLAIN或SHOW,语法树中不得包含更改数据的语句、SELECT INTO或锁定子句。函数必须在允许列表中(postgres-mcp 列表中已移除具有副作用的函数),并且带模式限定的函数必须位于pg_catalog中。 - 通过扩展查询协议发送,该协议每次只传递一条语句。
- 使用
default_transaction_read_only=on打开只读连接。 - 在
BEGIN TRANSACTION READ ONLY中运行,并始终回滚。 - 固定
search_path,且不会发送调用未限定函数的语句,只要该函数名也存在于pg_catalog之外。 - 设置语句超时。
这些检查涵盖模型发送的语句及其直接调用的函数。数据库中已有对象(视图、函数、运算符、策略)的函数体会被信任,不会检查。连接生产数据库时,也请使用只读角色。cluster_status 会显示已连接用户是否为超级用户。
Multigres 会将池中的 Postgres 连接从一个客户端交给下一个客户端使用。在同一事务中,服务器会移除工具调用可能留在连接上的假设索引和会话级 advisory 锁。如果清理失败,服务器会结束自己的 Postgres 会话,而不是将状态交给下一个客户端。execute_write_sql 会拒绝事务控制、会话级 SET 和 RESET、multigres.* 设置、hypopg 函数,以及会留下会话状态的语句(临时对象、PREPARE、LISTEN、DECLARE ... WITH HOLD、LOAD、DISCARD、DO)。在函数或触发器主体中更改的会话设置(set_config(..., false))和随机种子(setseed)不会被移除,可能会传递给使用该连接的下一个客户端;与其他对象主体一样,它们会被信任。
直接节点连接只运行固定查询,绝不会运行模型提供的 SQL。
工具结果和错误消息中会移除 multiadmin 地址(完整地址及 host:port 格式)、管理员令牌和数据库密码。移除操作会替换文本,因此,如果密码是常见词,该词无论出现在哪里都会被屏蔽。如果密码与用户名或数据库名称相同,则不会被屏蔽,因为结果会显示这些名称;服务器启动时会打印警告。
注意事项
--sql-timeout的默认值为 25s,因为 multipooler 会在某条语句的运行时间超过--connpool-user-reserved-inactivity-timeout(默认值为 30s)时结束事务的连接。若要使用更长的超时时间,也需要调高该连接池设置。execute_sql和execute_write_sql的结果末尾会有一行,列出服务器仅针对本次调用设置的选项(statement_timeout、lock_timeout,以及读取时的search_path),以及该会话原先的statement_timeout。网关会自行强制执行statement_timeout,而不会在节点上设置它,因此节点的pg_settings会显示其值为 0,而通过网关执行SHOW则会返回网关设置的值。- 累积统计信息按节点保存。发生故障转移后,新主节点的统计信息不包含旧主节点上的记录。使用统计信息的工具会在开头说明所涵盖的时间段;
diagnose和get_top_queries的node选项可读取其他节点。 - 建议中的索引大小是 hypopg 估算值,未考虑 btree 去重。对于重复值很多的列,估算值可能是真实大小的数倍(在 200,000 行、1,000 个不同值的情况下:估算为 4,644,864 字节,实际为 1,384,448 字节)。
- 网关会将其保留的查询文本截断至
--query-metrics-sql-max-bytes(默认值为 4096),且不会添加标记。执行计划和索引建议使用pg_stat_statements中的文本或你提供的完整语句。 pg_stat_statements中的语句文本会完整显示。一条很长的语句可能会占满 50,000 个字符的结果:此时diagnose会省略其余的慢查询检查及之后的检查,而get_top_queries会省略网关部分。结果中会说明内容已被截断。若要获取后续检查,请按名称向diagnose查询;若要获取网关部分,请将source: gateway传给get_top_queries。VACUUM和CREATE INDEX CONCURRENTLY不能在事务中运行,因此execute_write_sql无法运行它们。- 对 multiadmin 的调用会在 30 秒后超时;
verify_backups会在 10 分钟后超时。 - 如果
execute_write_sql未收到COMMIT的回复,它会说明无法确定语句是否已提交。再次发送前请检查数据。
测试
go test ./...
运行单元测试。集成测试和端到端测试带有构建标签 cluster,需要本地 Multigres Docker 集群,并预加载 pg_stat_statements、安装 hypopg。这些测试会切换主节点、删除并重新创建两个扩展,还会结束会话,因此不要对你在意的集群运行它们。无法连接集群时,测试会失败而不是跳过。
从 Multigres 检出目录启动集群:
git clone https://github.com/multigres/multigres
cd multigres
git checkout 49e7a2f7d4fe
MULTIGRES_PG_EXTRA_CONF="shared_preload_libraries = 'pg_stat_statements'" docker compose up -d --build
等到 docker compose ps 显示容器状态为 healthy,然后安装 hypopg 并创建这两个扩展:
docker compose exec -u root multigres sh -c 'apt-get update -q && apt-get install -y -q --no-install-recommends postgresql-17-hypopg'
docker compose exec -e PGPASSWORD=postgres multigres psql -h localhost -p 15432 -U postgres -d postgres -c 'CREATE EXTENSION pg_stat_statements' -c 'CREATE EXTENSION hypopg'
然后,在此仓库中,将 MULTIGRES_MCP_TEST_NODE_HOST 设置为上方 docker inspect 命令返回的容器地址:
MULTIGRES_MCP_TEST_NODE_HOST=<address> go test -tags cluster -p 1 -count=1 -timeout 25m ./...
-p 1 会一次运行一个包,因为这些包共用集群的主节点、扩展和连接池。测试使用 Docker 集群的网关 localhost:15432、multiadmin localhost:15000 以及节点端口 25432 和 25433;MULTIGRES_MCP_TEST_GATEWAY_URL 和 MULTIGRES_MCP_TEST_ADMIN_URL 可更改前两个地址。test/facts-map.md 将设计所依赖的 Multigres 行为映射到验证该行为的测试。
许可证
Apache License 2.0,详见 LICENSE。改编自 postgres-mcp 的部分采用 MIT License,详见 THIRD_PARTY_NOTICES.md。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。