Skip to main content
Glama

pgmcp

Go Reference GitHub go.mod Go version Go Report Card GitHub Workflow Status (with branch) GitHub GitHub code size in bytes

pgmcp 是一个用于模型上下文协议的只读 PostgreSQL 运维/DBA 服务器,基于官方的 modelcontextprotocol/go-sdk 构建。它回答 DBA 在事故期间会提出的问题——哪些语句很慢,为什么这个计划很慢,哪些索引是多余的,哪些表的 autovacuum 落后了,谁在阻塞谁,备库落后了多少——并且它是通过构造而非约定来实现只读的:一个没有写权限的专用数据库角色,一个 BEGIN READ ONLY 事务,每条语句都带有语句超时,以及一个 SQL 解析器守卫,拒绝任何不是单个 SELECT/EXPLAIN/SHOW 的内容,以及所有可能在只读事务内改变状态的函数。已在 PostgreSQL 16 上测试;需要 13 或更高版本。

安装

Claude Desktop,一键安装: 从 Releases 下载 pgmcp_<version>.mcpb 并打开它。Claude Desktop 会要求提供 Postgres 连接字符串,将其保存在操作系统钥匙串中,并自行启动捆绑的二进制文件——无需 PATH 上的任何内容,也无需编辑配置文件。一个捆绑包涵盖 macOS(通用)和 Windows(x64)。

否则,从 Releases 下载适合您平台的二进制文件——darwin、linux 和 windows,amd64 和 arm64,并带有校验和。

或者使用 Go CLI 工具 go 从源码构建:

go install github.com/pascalallen/pgmcp/cmd/pgmcp@latest

或者运行已发布的镜像,该镜像是 distroless、非 root 且多架构的:

docker run --rm -i -e PGMCP_DATABASE_URL='postgres://…' ghcr.io/pascalallen/pgmcp

pgmcp 在 MCP 注册表中列为 io.github.pascalallen/pgmcp。

在将其指向任何内容之前,请创建只读角色——请参阅 数据库角色。即使其他两层有 bug,它仍然是保持安全的那一层。

Related MCP server: PostgreSQL MCP Server

用法

一个 MCP 表面,两种传输方式。运行哪一种只是配置问题,而不是不同的构建。

Claude Code,stdio —— 客户端启动二进制文件并通过 stdin/stdout 通信:

claude mcp add pgmcp --transport stdio \
  --env PGMCP_DATABASE_URL='postgres://pgmcp:…@db.internal:5432/app?sslmode=require' \
  -- pgmcp

Claude Desktop,stdio —— 从 Releases 安装 .mcpb 捆绑包(请参阅 安装),或者手动将相同内容写入 claude_desktop_config.json:

{
  "mcpServers": {
    "pgmcp": {
      "command": "pgmcp",
      "env": {
        "PGMCP_DATABASE_URL": "postgres://pgmcp:…@db.internal:5432/app?sslmode=require"
      }
    }
  }
}

HTTP —— 在静态 bearer 密钥后面使用 Streamable HTTP,用于共享部署。pgmcp 只讲纯 HTTP,从不自行终止 TLS;请在反向代理后面的 loopback 上运行它。

PGMCP_DATABASE_URL='postgres://pgmcp:…@db.internal:5432/app?sslmode=require' \
PGMCP_AUTH_MODE=static \
PGMCP_API_KEYS="$(openssl rand -hex 32)" \
  pgmcp --transport http --listen 127.0.0.1:8080
claude mcp add pgmcp --transport http https://pgmcp.example.com/mcp \
  --header "Authorization: Bearer <key>"

TLS 终止、流式传输所需的代理设置、针对身份提供者的 JWT 认证,以及将 pgmcp 作为 claude.ai 自定义连接器接入,所有这些都在 docs/DEPLOYING.md 中。

工具

工具

它回答的问题

top_queries

哪些语句在整个服务器上很慢或开销很大?按总时间、平均时间、调用次数、读取的行数或块数对 pg_stat_statements 进行排名。

explain

为什么这个语句很慢?计划树、消耗最多自身时间的节点、计划警告,以及一个稳定的 plan_hash,用于与后续运行进行对比。

index_health

哪些索引可以删除,哪些索引没有发挥其作用?从未扫描的、重复的、无效的和膨胀的索引。

table_health

autovacuum 在哪里落后了?每个表的死元组比例、上次 vacuum/analyze 时间、顺序扫描与索引扫描的对比以及估计的膨胀。

lock_waits

为什么这个查询挂起了?当前的锁等待图——谁被阻塞,谁阻塞了它们,以及任何构成死锁的循环。

connections

服务器现在在做什么,离 max_connections 还有多远?按状态、等待事件、应用程序、用户或数据库分组的后端,包括空闲事务中的会话。

replication

备库落后了多少,哪个槽位在保留 WAL?主/备角色、每个备库的字节和毫秒延迟、槽位以及当前的 WAL 速率。

config_check

这个服务器调优得合理吗?pg_settings 与内存、autovacuum、WAL 和连接启发式规则对比,每个设置给出 ok/review/warn 判定和说明。

query

其他八个工具未涵盖的所有内容。在 READ ONLY 事务中执行一个只读的 SELECT/EXPLAIN/SHOW,受行数上限和语句超时限制,并支持 $1..$n 绑定参数。

每个工具都标注了 readOnlyHint: true、destructiveHint: false、idempotentHint: true、openWorldHint: false,并返回类型化的输出模式。

query 是唯一携带自由格式 SQL 的工具,而且它是可选的。--disable-query 会将其从目录中完全移除——只需要八个诊断工具的部署可以完全没有任何临时 SQL 表面。--query-schemas=public,app 将其限制为指定的模式——并且同时限制了 explain,因为 analyze=true 会执行语句;请阅读 docs/SECURITY.md 中它阻止了什么和没有阻止什么。

资源与提示

资源

内容

pgmcp://overview

起始的服务器快照:版本、运行时间、恢复状态、已安装的扩展、每个数据库的大小、缓存命中率,以及相对于 max_connections 的连接数。可缓存 30 秒。

pgmcp://settings

原始的 pg_settings 行。可缓存 5 分钟。

提示

参数

目的

diagnose_slow_query

sql(必需)

一个四步调查:对语句执行 explain,检查计划热节点中每个模式的 index_health/table_health,在 top_queries 中查找它,然后总结根本原因、证据以及推荐的索引或重写——仅以文本形式写出,绝不执行。

配置

每个设置都有一个 --flag 和一个 PGMCP_<KEY> 环境变量。标志优先于环境变量,环境变量优先于默认值。配置错误以退出码 2 退出,并在一条消息中列出所有违规键;运行时故障以退出码 1 退出。

标志

环境变量

默认值

含义

--database-url

PGMCP_DATABASE_URL

—(必需)

Postgres 连接字符串

--transport

PGMCP_TRANSPORT

stdio

stdio 或 http

--listen

PGMCP_LISTEN

127.0.0.1:8080

HTTP 监听地址

--resource-url

PGMCP_RESOURCE_URL

—

此服务器可访问的公共源,用于 OAuth 资源元数据

--auth-mode

PGMCP_AUTH_MODE

none

none、static 或 jwt(仅 HTTP)

--api-keys

PGMCP_API_KEYS

—

逗号分隔的静态 API 密钥,static 模式必需

--jwks-url

PGMCP_JWKS_URL

—

JWK 集合 URL,jwt 模式必需

--jwt-issuer

PGMCP_JWT_ISSUER

—

必需的 iss 声明,jwt 模式必需

--jwt-audience

PGMCP_JWT_AUDIENCE

—

必需的 aud 声明,jwt 模式必需

--auth-servers

PGMCP_AUTH_SERVERS

—

逗号分隔的 OAuth 授权服务器,通过 RFC 9728 进行通告

--disable-query

PGMCP_DISABLE_QUERY

false

完全移除临时 query 工具

--query-schemas

PGMCP_QUERY_SCHEMAS

—

query 和 explain 工具可以读取的逗号分隔模式;未设置则禁用允许列表

--max-conns

PGMCP_MAX_CONNS

4

最大 Postgres 连接数

--call-timeout

PGMCP_CALL_TIMEOUT

60s

每次工具调用的超时时间

--rate-limit

PGMCP_RATE_LIMIT

60

每个主体每分钟的工具调用次数(仅 HTTP)

--max-output-bytes

PGMCP_MAX_OUTPUT_BYTES

1048576

工具调用结构化内容的上限

--log-level

PGMCP_LOG_LEVEL

info

debug、info、warn 或 error

--log-format

PGMCP_LOG_FORMAT

text

text 或 json

--insecure-no-auth

PGMCP_INSECURE_NO_AUTH

false

允许在非 loopback 监听地址上使用 auth-mode=none

--version

—

—

打印版本并退出

认证块仅适用于 HTTP 传输。在 stdio 上,由操作系统决定调用者是谁:启动该二进制文件的父进程,别无他人。

安全模型

  • 只读,三种相互独立的方式。 一个没有写权限的专用角色(pg_monitor 加 SELECT,并特意不用 pg_signal_backend);围绕适配器运行的每一条语句执行 BEGIN READ ONLY 和 SET LOCAL statement_timeout、lock_timeout = '2s',并且总是回滚;以及一层解析器级防护,因为仅靠只读事务并不能阻止 pg_terminate_backend、pg_read_file、pg_sleep 或 setval。

  • SQL 防护以允许列表为先。 只能有一个顶层语句,且必须是 SELECT、EXPLAIN 或 SHOW;整个语句树中不得有嵌套写语句;不得有 FOR UPDATE/FOR SHARE 锁定子句;不得有 SELECT INTO;也不得调用被禁止的函数——文件访问、备份和 WAL 控制、复制槽、advisory locks、dblink、序列变更、统计信息重置。

  • Schema 允许列表是护栏,而非边界。 --query-schemas 不区分大小写地匹配解析后语句中限定表引用的 schema,并约束 query 和 explain 这两个携带调用者所提供 SQL 的工具,因此带 analyze=true 的 explain 不能针对你排除的 schema 执行。允许的 schema 中的视图、集合返回函数或 SECURITY DEFINER 函数仍然可以读取 schema 之外的数据。数据库权限才是边界;允许列表只是收窄了那条明显的路径。

  • 通过 HTTP 进行认证,失败即关闭。 静态密钥与每个存储的哈希在常数时间内比较,没有提前退出;JWT 只使用非对称算法针对 JWK 集合验证(无 alg=none,无 HMAC 混淆),并且要求 iss、aud、exp 存在;验证器在 JWKS 到达前不持有任何密钥,因此它是以关闭状态而非开放状态启动。RFC 9728 受保护资源元数据会公告去哪里获取令牌。服务器在关闭认证时拒绝在非回环地址上启动。

  • 受限有界。 按主体进行速率限制、逐调用超时、事务内的语句超时和锁超时、query 工具的行数上限、结果中结构化内容的上限,以及 1 MiB 的请求体大小限制。

  • 不记录敏感信息。 工具调用记录其名称、时长、结果和调用者的用户 ID,而绝不记录参数、SQL 文本、结果行或错误文本。解析失败返回一个固定短语而不是回显语句,并且 DSN 会从连接错误中被红acted。

威胁模型、各层级的完整清单以及每一层并不覆盖的限制,请参见 docs/SECURITY.md。

测试

使用竞态检测器和覆盖率运行测试套件:

go test -race -cover ./...

集成测试需要一个 Postgres 数据库,并在未设置 PGMCP_TEST_DSN 时被跳过。要针对预加载了 pg_stat_statements 的临时 Postgres 运行它们:

docker run -d --rm --name pg -e POSTGRES_PASSWORD=postgres -p 5544:5432 postgres:16 \
  -c shared_preload_libraries=pg_stat_statements -c pg_stat_statements.track=all
docker exec pg psql -U postgres -c "CREATE EXTENSION IF NOT EXISTS pg_stat_statements"
PGMCP_TEST_DSN="postgres://postgres:postgres@localhost:5544/postgres?sslmode=disable" go test -race -cover ./...

创建并查看覆盖率报告:

go test -covermode=count -coverprofile=coverage.out ./...
go tool cover -html=coverage.out

通过官方 MCP 一致性套件驱动正在运行的服务器,或使用 Inspector 对服务器做冒烟测试:

npx -y @modelcontextprotocol/conformance server --url http://127.0.0.1:8080/mcp \
  --expected-failures .github/conformance-expected-failures.yaml
npx @modelcontextprotocol/inspector --cli http://127.0.0.1:8080/mcp --transport http --method tools/list

贡献

欢迎提交拉取请求。对于重大更改,请先打开一个问题来讨论你想要改动的内容。

请确保相应更新测试。

许可证

MIT

Related MCP Connectors

Related MCP Servers

  • -
    license
    Not graded
    quality
    A
    maintenance
    A Model Context Protocol server that provides read-only access to PostgreSQL databases. This server enables LLMs to inspect database schemas and execute read-only queries.
    97,848 npm
    91,120
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A Model Context Protocol server that provides AI assistants with secure, read-only access to PostgreSQL databases while offering comprehensive tools for schema exploration, query validation, and performance optimization.
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A Model Context Protocol server providing read-only access to PostgreSQL databases, enabling LLMs to inspect database schemas and execute read-only SQL queries.
    97,848 npm
    MIT