SuperAPI AI 工具集

mcp-postgres-server

mcp-postgres-server 是一个面向 PostgreSQL 的 Model Context Protocol(MCP)服务器,支持本地、Docker、RDS、Neon 和 Supabase 数据库,也可通过 SSH 跳板机访问仅内网可达的数据库。它可与 VS Code、Cursor、Claude Code、Codex、Windsurf 等支持 stdio 的 MCP 客户端配合使用。服务器默认只读,写入需显式开启;提供查询、列出 schema、列出表、描述表结构、执行写入语句以及运行时连接切换等工具,并具备结果大小限制、超时、错误提示和 SSH 隧道等能力。

访问官网

工具介绍

用途

mcp-postgres-server 是一个 Model Context Protocol(MCP)服务器,用于让 AI 编程客户端访问 PostgreSQL 数据库。它支持本地、Docker、RDS、Neon 和 Supabase 数据库,也可通过 SSH 跳板机(bastion)访问仅能经跳板机到达的数据库。该服务器可与 VS Code、Cursor、Claude Code、Codex、Windsurf 等支持 stdio 的 MCP 客户端配合使用。

主要能力

服务器体积小、可审计,运行时依赖包括 MCP SDK、pg、pg-connection-string 和 zod,另有可选依赖 ssh2 仅用于 SSH 隧道。要求 Node.js 20 或更高版本。

工具能力取决于配置:

  1. query:执行只读 SQL 语句,接受 SELECT、WITH ... SELECT、EXPLAIN 和 SHOW。每次调用只允许一条语句,多语句输入会被扩展查询协议拒绝。在只读模式(默认)下,语句以 BEGIN READ ONLY、查询、ROLLBACK 三步执行,由数据库自身拒绝任何写入。当 PG_ALLOW_WRITE=true 时,语句直接发送,不加该包装,因此通过 query 执行的写入会真正执行——写入应使用 execute。支持 PostgreSQL 风格的 $1、$2 预处理语句参数,值由驱动绑定,不会拼接进 SQL 文本。返回紧凑 JSON:{"rows": [...], "rowCount": n, "returnedRows": n, "truncated": false}。当序列化行超过 PG_MAX_RESULT_BYTES 时,只返回能容纳的行(returnedRows < rowCount),truncated 为 true,并提示添加 LIMIT / WHERE 或减少列。

  2. list_schemas:列出连接数据库中的所有 schema。

  3. list_tables:列出连接数据库中的表,可选 schema 参数(默认 'public')。

  4. describe_table:获取指定表的结构(列、类型、可空性、默认值、主键),可选 schema 参数(默认 'public')。

  5. execute:需要 PG_ALLOW_WRITE=true。执行 INSERT、UPDATE、DELETE 或 DDL 语句。该工具始终注册,但在只读模式(默认)下会拒绝并报错,提示 PG_ALLOW_WRITE,且不改变任何内容——语句不会到达数据库。当 PG_ALLOW_WRITE=true 时执行,参数处理与 query 相同,每次调用一条完整语句,连接角色决定其可执行的操作。返回 {"rowCount": n, "command": "INSERT"}。

  6. connect_db:需要 PG_ENABLE_RUNTIME_CONNECT=true。使用提供的凭据在运行时连接另一个 PostgreSQL 数据库。默认不注册——建议通过环境配置凭据,避免凭据经过模型可见的参数。每次重连后会重新应用会话限制(statement_timeout、idle_in_transaction_session_timeout);只读读取在其自己的 BEGIN READ ONLY 事务中强制只读。

使用方式

首选配置方式是单个 DATABASE_URL。当 PG_ALLOW_WRITE 设为 "false" 时,服务器对数据库具有只读访问权限,这是默认值;仅当模型必须写入时才设为 "true"。同一份 JSON 可用于任何支持 stdio 的 MCP 客户端:VS Code、Cursor、Claude Code、Codex、Windsurf。

也可以设置单独的 PG_* 变量;当未设置 DATABASE_URL 时使用它们。

支持手动安装,或直接运行。

连接数据库:

  • 本地 Postgres:直接连接。
  • Docker 中的 Postgres:如果数据库运行在已发布端口的容器中,照常连接 localhost:<published-port>。如果 MCP 服务器本身运行在容器内而数据库运行在宿主机上,使用 host.docker.internal 代替 localhost。

适用场景

适用于需要让 AI 编程助手安全查询 PostgreSQL 数据库的开发场景,包括本地开发、Docker 环境、云数据库(RDS、Neon、Supabase)以及需要通过 SSH 跳板机访问的内网数据库。默认只读设计适合让模型探索数据库结构、执行只读查询,同时避免意外写入。

限制与安全说明

  • 默认只读;写入需显式开启(PG_ALLOW_WRITE=true)。
  • 只读由引擎强制(BEGIN READ ONLY),而非客户端 SQL 解析。
  • 数据访问通过小型类型化接口,pg 驱动不会泄漏到接口之外。
  • 支持 DATABASE_URL 与 SSL(sslmode=disable|allow|prefer|require|verify-ca|verify-full,自定义 CA)。
  • 预处理语句参数:$1 风格占位符,由驱动绑定。
  • 结果大小上限(字节预算),带显式 truncated 标志,避免淹没模型上下文。
  • 会话语句超时加客户端截止时间;事务池可能不保留会话设置。
  • 错误以可读工具结果返回,带基于 SQLSTATE 的提示,便于模型自我纠正。
  • 连接断开后可恢复——惰性重连而非崩溃。
  • 可选 SSH 隧道(PG_SSH_*),强制主机密钥验证,仅在配置时加载。
  • 符合 2025-11-25 规范的 MCP 工具注解(只读/破坏性提示)。
  • 多 schema 支持。

安全方面:最小权限数据库角色才是真正的边界。MCP 使用现有凭据,无需创建或更改角色。专用角色才能真正保证写入不可能。PostgreSQL 14+ 可参考:CREATE ROLE mcp_readonly LOGIN PASSWORD 'change-me'; GRANT CONNECT ON DATABASE your_database TO mcp_readonly; GRANT pg_read_all_data TO mcp_readonly; ALTER ROLE mcp_readonly SET default_transaction_read_only = on;(PostgreSQL 13 或更早版本需显式授予 SELECT,详见 SECURITY.md。)以超级用户连接时服务器会在 stderr 发出警告。读取授权不会撤销已有权限,默认值仍可变;可用函数、所有权和继承权限也需考虑。

只读由引擎强制,没有客户端 SQL 解析。只读模式下每次读取都在回滚的 BEGIN READ ONLY 事务中运行,因此 PostgreSQL 自身会以 SQLSTATE 25006 拒绝任何写入,并回滚语句造成的任何会话更改。扩展协议拒绝多命令字符串。

诚实说明:只读事务是角色之上的纵深防御,而非替代。只读模式阻止困惑或被提示注入的模型写入数据库;它不能阻止查询返回的行数据中携带的提示注入。不要将此服务器指向生产环境——使用副本、快照或严格限定范围的角色。详见 SECURITY.md。

SSH 隧道:设置 PG_SSH_HOST(以及认证和主机密钥验证)以访问仅能通过跳板机(SSH 跳转主机)到达的数据库。连接字符串 / PG_* 字段描述从跳板机看到的数据库。SSH 只改变传输方式。只读强制、结果大小上限、超时和 connect_db 的行为与直接连接完全相同,且每次查询不发送额外 SQL。

主机密钥验证通过固定的 PG_SSH_FINGERPRINT 强制进行——没有它隧道不会连接,因此中间人跳板机会被拒绝。获取指纹的渠道(可信度从高到低):在跳板机本身或从其管理员处运行 ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub(不涉及网络);从现有 ~/.ssh/known_hosts 获取(如果已通过 ssh 到达该主机):ssh-keygen -lF bastion.example.com;从主机获取:ssh-keyscan bastion.example.com | ssh-keygen -lf -(仅在你信任的网络位置运行才可信——它接受主机返回的任何内容)。

TLS 验证真实数据库主机名。使用 verify-full 时,证书针对数据库自身主机名(如 db.internal)检查,而非隧道本地绑定的回环地址,且 rejectUnauthorized 被固定开启,因此继承的 NODE_TLS_REJECT_UNAUTHORIZED=0 无法禁用它。

ssh2 是可选依赖,仅在设置 PG_SSH_HOST 时加载,因此直接连接从不初始化它。npm 默认安装可选依赖;运行 npm install --omit=optional 可完全跳过(直接连接不需要它)。

隧道连接失败会报告稳定的 SSH_* 代码。

错误处理:SQL 和连接失败以工具结果(isError: true)返回,包含消息、SQLSTATE 代码和提示。存在 PostgreSQL 自身服务器提示时使用它;否则应用回退提示。通过 SSH 隧道时,失败携带稳定代码(在原因确定时,提示指明要修复的设置),因此失败阶段明确。通过健康隧道的真实 PostgreSQL 错误保留自己的代码(如凭据错误 28P01),而非 SSH 代码。

从 0.1.x 迁移:新安装无需迁移。自 0.1.x 起有两项行为变化:

  1. 默认只读。execute 工具始终可见,但除非 PG_ALLOW_WRITE=true,否则拒绝写入(报错提示该标志),且每次读取都在引擎强制的 READ ONLY 事务中运行。如果工作流需要写入数据库,设置 "PG_ALLOW_WRITE": "true" 以恢复 0.1.x 行为。
  2. connect_db 默认禁用。运行时连接切换(通过工具参数传递凭据)需要 PG_ENABLE_RUNTIME_CONNECT=true;否则连接详情仅来自环境。

工具名称、参数名称和 PG_* 变量未变。结果负载现在对所有工具都是结构化紧凑 JSON(例如 query 返回 {rows, rowCount, returnedRows, truncated} 而非裸行数组)——更新任何解析工具输出的代码前,请查看 CHANGELOG.md 了解确切形状。