mcpField
M
MCP PostgreSQL Server

MCP PostgreSQL Server

本地服务
npmjs.com数据库246 周前更新

关于 MCP PostgreSQL Server

MCP PostgreSQL Server 是一个用于 PostgreSQL 数据库的 MCP 服务,支持本地、Docker、RDS、Neon 和 Supabase 等环境。默认只读,写入需要显式开启,并依靠数据库本身的只读事务进行保护。

主要功能

  1. 01通过 DATABASE_URL 或 PG_* 变量配置连接
  2. 02默认只读,PG_ALLOW_WRITE 显式开启写入
  3. 03只读事务强制执行,结果大小受限
  4. 04支持 $1 形式的预处理参数
  5. 05可选 SSH 隧道与主机密钥验证

适用场景

  1. 01让 AI 助手查询和了解数据库表结构
  2. 02通过只读账号分析生产副本或快照数据
  3. 03经由堡垒机访问内网 PostgreSQL 数据库

MCP 相关

该项目是 MCP 服务,向 MCP 客户端提供 query、list_tables、describe_table 等数据库工具,以及可选的 execute 和 connect_db 工具。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"postgres-server": {
"command": "npx",
"args": [
"-y",
"mcp-postgres-server"
],
"env": {
"DATABASE_URL": "<DATABASE_URL>",
"PG_HOST": "<PG_HOST>",
"PG_PORT": "<PG_PORT>",
"PG_USER": "<PG_USER>",
"PG_PASSWORD": "<PG_PASSWORD>",
"PG_DATABASE": "<PG_DATABASE>",
"PG_ALLOW_WRITE": "<PG_ALLOW_WRITE>",
"PG_SSLMODE": "<PG_SSLMODE>",
"PG_SSL_CA": "<PG_SSL_CA>",
"PG_ENABLE_RUNTIME_CONNECT": "<PG_ENABLE_RUNTIME_CONNECT>",
"PG_MAX_RESULT_BYTES": "<PG_MAX_RESULT_BYTES>",
"PG_STATEMENT_TIMEOUT": "<PG_STATEMENT_TIMEOUT>",
"PG_CONNECT_TIMEOUT": "<PG_CONNECT_TIMEOUT>",
"PG_SSH_HOST": "<PG_SSH_HOST>",
"PG_SSH_PORT": "<PG_SSH_PORT>",
"PG_SSH_USER": "<PG_SSH_USER>",
"PG_SSH_PRIVATE_KEY": "<PG_SSH_PRIVATE_KEY>",
"PG_SSH_PASSPHRASE": "<PG_SSH_PASSPHRASE>",
"PG_SSH_AGENT": "<PG_SSH_AGENT>",
"PG_SSH_PASSWORD": "<PG_SSH_PASSWORD>",
"PG_SSH_FINGERPRINT": "<PG_SSH_FINGERPRINT>",
"PG_SSH_KEEPALIVE_INTERVAL": "<PG_SSH_KEEPALIVE_INTERVAL>"
}
}
}
}
启动命令npx -y mcp-postgres-server
需要配置的环境变量
DATABASE_URL密钥Full connection string (preferred). Supports sslmode in the URL.
PG_HOSTDatabase host (fallback when DATABASE_URL is not set).
PG_PORTDatabase port.
PG_USERDatabase user.
PG_PASSWORD密钥Database password.
PG_DATABASEDatabase name.
PG_ALLOW_WRITEWhen true, execute performs writes and reads are sent directly. Off (default) is read-only: execute refuses writes and each read runs in a READ ONLY transaction.
PG_SSLMODETLS mode. require/allow/prefer encrypt without verifying the certificate; verify-ca/verify-full verify it (supply a CA via PG_SSL_CA). Unlike libpq, allow/prefer do not fall back to plaintext, so a server without TLS needs disable.
PG_SSL_CAPath to a CA certificate file. Setting it by itself implies verify-full.
PG_ENABLE_RUNTIME_CONNECTRegister the connect_db tool (runtime credential switching).
PG_MAX_RESULT_BYTESByte budget for a query result sent to the model. Whole rows are kept while they fit; over the budget returnedRows < rowCount and truncated is true.
PG_STATEMENT_TIMEOUTStatement timeout in milliseconds, applied to every session.
PG_CONNECT_TIMEOUTTimeout in milliseconds for a single connect attempt (raise it for slow links or SSH tunnels).
PG_SSH_HOSTSSH bastion host. Setting it enables tunneling: the server reaches the database only through an SSH tunnel to this host. Needs the ssh2 optional dependency.
PG_SSH_PORTSSH bastion port.
PG_SSH_USERSSH username.
PG_SSH_PRIVATE_KEY密钥Path to a private key file. If unset, auth falls back like ssh: a running agent (SSH_AUTH_SOCK), then a default key (~/.ssh/id_ed25519, id_rsa, id_ecdsa).
PG_SSH_PASSPHRASE密钥Passphrase for the private key, if encrypted.
PG_SSH_AGENTtrue to use the ambient agent (SSH_AUTH_SOCK), or an explicit socket path / Windows named pipe.
PG_SSH_PASSWORD密钥SSH login password. Opt-in; a key or agent takes precedence. Prefer keys, a bastion often disables password auth.
PG_SSH_FINGERPRINTPinned host-key fingerprint (SHA256:...). Host-key verification is mandatory and set only this way: without it the tunnel refuses to connect. Get it with ssh-keygen -lF host.
PG_SSH_KEEPALIVE_INTERVALSSH keepalive interval in ms; the tunnel drops after 3 unanswered keepalives, and the next call reconnects.

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmmcp-postgres-server0.3.1

工具

5

收录的工具列表 · 更新于 3 周前

参数类型必填说明
sqlstring是一条 SQL 语句。参数请使用 $1、$2、...。
paramsarray否绑定到 $1、$2、... 占位符的位置参数值。

详细介绍

MCP PostgreSQL Server

npm version CI

用于 PostgreSQL 的模型上下文协议(MCP)服务,支持本地、Docker、RDS、Neon 和 Supabase 数据库。

该服务体积小且易于审计,只有四个运行时依赖:MCP SDK、 pg、pg-connection-string 和 zod(以及 ssh2,这是仅用于 SSH 隧道的可选依赖)。

需要 Node.js 20 或更高版本。

快速开始

配置该服务的首选方式是使用单个 DATABASE_URL:

{
  "mcpServers": {
    "postgres": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "mcp-postgres-server"],
      "env": {
        "DATABASE_URL": "postgres://user:password@localhost:5432/mydb",
        "PG_ALLOW_WRITE": "false"
      }
    }
  }
}

将 PG_ALLOW_WRITE 设为 "false" 时,该服务对数据库具有只读访问权限。这是默认值;只有模型必须写入时才将其设为 "true"。

同一份 JSON 适用于任何使用 stdio 的 MCP 客户端:VS Code、Cursor、Claude Code、Codex、Windsurf。

或者,设置各个 PG_* 变量;仅当未设置 DATABASE_URL 时才会使用这些变量:

{
  "mcpServers": {
    "postgres": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "mcp-postgres-server"],
      "env": {
        "PG_HOST": "your_host",
        "PG_PORT": "5432",
        "PG_USER": "your_user",
        "PG_PASSWORD": "your_password",
        "PG_DATABASE": "your_database",
        "PG_ALLOW_WRITE": "false"
      }
    }
  }
}
手动安装
npm install mcp-postgres-server

或者直接运行:

npx mcp-postgres-server

连接到数据库

本地 Postgres:

DATABASE_URL=postgres://mcp_readonly:secret@localhost:5432/mydb

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

DATABASE_URL=postgres://mcp_readonly:[email protected]:5432/mydb

Amazon RDS:

DATABASE_URL=postgres://mcp_readonly:[email protected]:5432/mydb?sslmode=require

Neon:

DATABASE_URL=postgres://mcp_readonly:[email protected]/mydb?sslmode=require

Supabase:

DATABASE_URL=postgres://postgres.xxxxxxxx:[email protected]:5432/postgres?sslmode=require

工具

工具是否可用取决于配置:

工具可用性
query、list_schemas、list_tables、describe_table始终可用
execute始终可用(除非 PG_ALLOW_WRITE=true,否则会拒绝写入)
connect_db仅当 PG_ENABLE_RUNTIME_CONNECT=true 时可用
1. query

执行只读 SQL 语句。接受 SELECT、WITH ... SELECT、 EXPLAIN 和 SHOW。每次调用只能执行一条语句——扩展查询协议会拒绝多语句输入。在只读模式(默认)下,语句会按 BEGIN READ ONLY、查询和 ROLLBACK 的顺序执行——共三个命令,使用流水线时大约需要两次网络往返——因此数据库本身会拒绝任何写入。 设置 PG_ALLOW_WRITE=true 时,语句会直接发送,不会使用上述封装,因此通过 query 执行的写入会成功;写入请使用 execute。 支持 PostgreSQL 风格的 $1, $2 预处理语句参数;值由驱动绑定,绝不会插入 SQL 文本。

use_mcp_tool({
  server_name: "postgres",
  tool_name: "query",
  arguments: {
    sql: "SELECT * FROM users WHERE id = $1",
    params: [1]
  }
});

返回简洁的 JSON:{"rows": [...], "rowCount": n, "returnedRows": n, "truncated": false}。 当序列化后的行超过 PG_MAX_RESULT_BYTES 时,只返回可容纳的行(returnedRows < rowCount),truncated 为 true,并提示添加 LIMIT/WHERE 或选择更少的列。

2. list_schemas

列出已连接数据库中的所有模式。

use_mcp_tool({
  server_name: "postgres",
  tool_name: "list_schemas",
  arguments: {}
});
3. list_tables

列出已连接数据库中的表。接受可选的模式参数(默认为 'public')。

// List tables in the 'public' schema (default)
use_mcp_tool({
  server_name: "postgres",
  tool_name: "list_tables",
  arguments: {}
});

// List tables in a specific schema
use_mcp_tool({
  server_name: "postgres",
  tool_name: "list_tables",
  arguments: {
    schema: "my_schema"
  }
});
4. describe_table

获取特定表的结构(列、类型、是否可为空、默认值、主键)。接受可选的模式参数(默认为 'public')。

use_mcp_tool({
  server_name: "postgres",
  tool_name: "describe_table",
  arguments: {
    table: "users",
    schema: "my_schema"  // optional
  }
});
5. execute - 需要 PG_ALLOW_WRITE=true

执行 INSERT、UPDATE、DELETE 或 DDL 语句。始终会注册此工具,但在只读模式(默认)下会拒绝执行,并返回一条指出 PG_ALLOW_WRITE 的错误,且不会进行任何更改——语句不会到达数据库。设置 PG_ALLOW_WRITE=true 时则会执行:参数处理方式与 query 中的 $1, $2 相同,每次调用执行一条完整语句,且可执行的操作由连接所用的角色决定。 返回 {"rowCount": n, "command": "INSERT"}。

use_mcp_tool({
  server_name: "postgres",
  tool_name: "execute",
  arguments: {
    sql: "INSERT INTO users (name, email) VALUES ($1, $2)",
    params: ["John Doe", "[email protected]"]
  }
});
6. connect_db - 需要设置 PG_ENABLE_RUNTIME_CONNECT=true

使用提供的凭据在运行时连接到其他 PostgreSQL 数据库。默认不注册此工具——建议通过环境配置凭据,避免凭据出现在模型可见的参数中。每次重新连接后都会重新应用会话限制(statement_timeout、idle_in_transaction_session_timeout);只读查询会在各自的 BEGIN READ ONLY 事务中强制执行只读操作。

use_mcp_tool({
  server_name: "postgres",
  tool_name: "connect_db",
  arguments: {
    host: "localhost",
    port: 5432,
    user: "your_user",
    password: "your_password",
    database: "your_database"
  }
});

配置参考

变量默认值描述
DATABASE_URL-完整连接字符串(首选)。支持 URL 中的 ?sslmode=。
PG_HOST-数据库主机(未设置 DATABASE_URL 时的备用项)
PG_PORT5432数据库端口
PG_USER-数据库用户
PG_PASSWORD-数据库密码
PG_DATABASE-数据库名称
PG_ALLOW_WRITEfalse设为 true 时,execute 会执行写入,读取操作会直接发送。关闭(默认)时为只读:execute 会拒绝写入,且每次读取都会在 READ ONLY 事务中执行
PG_SSLMODE-disable | allow | prefer | require | verify-ca | verify-full。require/allow/prefer 会加密但不验证证书;verify-ca/verify-full 会验证证书(通过 PG_SSL_CA 提供 CA)。无法识别的值会导致启动失败。**限制:**与 libpq 不同,allow/prefer 不会回退到明文连接(node-postgres 不支持机会性 SSL),因此不支持 TLS 的服务器需要使用 disable。
PG_SSL_CA-CA 证书文件的路径。单独设置此项会隐含启用 verify-full
PG_ENABLE_RUNTIME_CONNECTfalse注册 connect_db 工具(运行时切换凭据)
PG_MAX_RESULT_BYTES32768发送给模型的 query 结果的字节数上限。只要完整的行能放入上限内,就会保留这些行;超出上限时,returnedRows < rowCount 且 truncated: true(如果连第一行都放不下,returnedRows 为 0,并附带提示)。约 32 KiB ≈ 8k 个 token;严格客户端可调低,客户端允许更多时可调高。
PG_STATEMENT_TIMEOUT30000语句超时时间(毫秒),应用于每个会话
PG_CONNECT_TIMEOUT10000单次连接尝试的超时时间(毫秒)(网络链路较慢或使用 SSH 隧道时可调高)

如需连接只能通过堡垒机访问的数据库,请参阅 SSH 隧道(会添加 PG_SSH_* 变量)。

功能

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

安全性

威胁模型和披露流程等完整信息,请参阅 SECURITY.md。简而言之:

  1. 最小权限数据库角色才是真正的边界。 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;                          -- adds read privileges
    ALTER ROLE mcp_readonly SET default_transaction_read_only = on;  -- read-only by default
    

    (在 PostgreSQL 13 或更早版本上,请显式授予 SELECT,而不是使用 pg_read_all_data——详见 SECURITY.md。)如果你以超级用户身份连接,服务会在 stderr 上发出警告。读取权限不会撤销现有权限,默认设置仍可更改;可用函数、所有权和继承的权限也很重要。

  2. 引擎会强制执行只读。 不会在客户端解析 SQL。在只读模式下,每次读取都会在回滚的 BEGIN READ ONLY 事务中运行,因此 PostgreSQL 本身——只有它才知道函数、视图或规则的实际行为——会使用 SQLSTATE 25006 拒绝任何写入,并撤销语句所做的任何会话更改。扩展协议会拒绝包含多条命令的字符串。

**准确地说:**只读事务是在角色之上的纵深防御,而非角色的替代方案。只读模式可以阻止被误导或遭到提示词注入的模型向数据库写入;但无法阻止查询返回的行数据中携带的提示词注入。不要将此服务指向生产环境——请使用副本、快照或严格限定权限的角色。详见 SECURITY.md。

SSH 隧道

设置 PG_SSH_HOST(以及身份验证和主机密钥验证),即可连接只能通过堡垒机(SSH 跳板主机)访问的数据库。连接字符串 / PG_* 字段描述的是从堡垒机看来的数据库:

{
  "mcpServers": {
    "postgres": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "mcp-postgres-server"],
      "env": {
        "DATABASE_URL": "postgres://mcp_readonly:[email protected]:5432/mydb?sslmode=verify-full",
        "PG_SSH_HOST": "bastion.example.com",
        "PG_SSH_USER": "jump",
        "PG_SSH_PRIVATE_KEY": "/home/me/.ssh/id_ed25519",
        "PG_SSH_FINGERPRINT": "SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
      }
    }
  }
}
变量默认值说明
PG_SSH_HOST-SSH 堡垒机主机。设置此项即可启用隧道:服务只能通过到此主机的 SSH 隧道访问数据库(见下文)。可选功能;需要可选依赖项 ssh2。
PG_SSH_PORT22SSH 堡垒机端口
PG_SSH_USER-SSH 用户名
PG_SSH_PRIVATE_KEY-私钥文件的路径。若未设置,身份验证将像 ssh 一样依次尝试:正在运行的 Agent(SSH_AUTH_SOCK),然后是默认密钥(~/.ssh/id_ed25519、id_rsa、id_ecdsa)
PG_SSH_PASSPHRASE-加密私钥的密码短语
PG_SSH_AGENT-使用当前 Agent(SSH_AUTH_SOCK)时设为 true,也可指定套接字路径 / Windows 命名管道(\\.\pipe\openssh-ssh-agent)
PG_SSH_PASSWORD-SSH 登录密码。需主动启用;优先使用密钥或 Agent。建议使用密钥——堡垒机通常会禁用密码身份验证。
PG_SSH_FINGERPRINT-固定的主机密钥指纹(SHA256:...)。必须通过此项进行主机密钥验证:若未设置,隧道将拒绝连接(故障时关闭)。可使用 ssh-keygen -lF host 获取(读取你的 known_hosts),或使用 ssh-keyscan host | ssh-keygen -lf - 获取(参见下方的信任说明)
PG_SSH_KEEPALIVE_INTERVAL15000SSH 保活间隔,单位为毫秒;连续 3 次保活无响应后隧道将断开,下次调用时重新连接
  • 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 服务器提供了提示,则使用该提示; 否则使用以下备用提示:

code含义首先检查
28P01身份验证失败PG_USER / PG_PASSWORD
3D000数据库不存在PG_DATABASE
42P01未找到关系调用 list_tables
42703未找到列调用 describe_table
57014查询已取消(超时或收到取消请求)如果是超时,添加 LIMIT / 简化查询,或提高 PG_STATEMENT_TIMEOUT
25006事务为只读来源可能是只读角色、副本、服务器默认设置,或(对于 query)只读包装器;execute 写入操作需要设置 PG_ALLOW_WRITE=true
ECONNREFUSED / ENOTFOUND无法连接到数据库主机或解析其地址PG_HOST / PG_PORT / DATABASE_URL

通过 SSH 隧道 连接时,失败会携带稳定的 code(如果原因明确,还会提供指出需修正设置的提示),因此可以明确判断失败阶段:

code含义首先检查
SSH_CONFIG_INVALIDSSH 配置无效,包括格式错误的 PG_SSH_FINGERPRINTPG_SSH_* 值
SSH_KEY_INVALID密钥不可读、无法解析、是公钥,或已加密但没有正确的密码短语(使用正确的 PG_SSH_PASSPHRASE 即可使用加密密钥)PG_SSH_PRIVATE_KEY、PG_SSH_PASSPHRASE
SSH_CONNECT_FAILED无法连接到堡垒机,或 SSH 设置因未分类原因失败PG_SSH_HOST、PG_SSH_PORT、网络可达性
SSH_TIMEOUT堡垒机未能及时响应网络/防火墙、PG_CONNECT_TIMEOUT
SSH_AUTH_FAILED堡垒机拒绝了身份验证PG_SSH_USER 以及当前使用的密钥/代理/密码
SSH_HOST_KEY_MISMATCH主机密钥与 PG_SSH_FINGERPRINT 不匹配(值已过期或遭遇中间人攻击)重新获取指纹
SSH_FORWARD_FAILED隧道已建立,但堡垒机无法连接到数据库从堡垒机视角看到的数据库主机和端口
SSH_CONNECTION_LOST已建立的隧道在会话中途断开暂时性问题;下次调用时会重新连接

通过正常工作的隧道传递的真实 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 了解确切的数据结构。

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。