使用说明
MCP PostgreSQL服务器
一个轻量级的编译MCP(模型上下文协议)服务器,通过stdio传输将PostgreSQL数据库操作作为工具公开。内置Go,零CGO依赖,易于部署。
特性
- 5个MCP工具:
query,execute,list_tables,describe_table,list_schemas - 只读/读写模式:通过工具注册+交易级执行进行深度防御
- 灵活配置:环境变量、CLI标志或两者(具有明确的优先级)
- 连接池:基于pgx构建,具有可配置的池大小
- 静态二进制:单个文件,无运行时依赖关系,约10 MB
安装
去安装
go install github.com/andresfrei/mcp-postgresql@latest
从源代码构建
git clone https://github.com/andresfrei/mcp-postgresql.git
cd mcp-postgresql
go build -o mcp-postgresql .
优化构建
CGO_ENABLED=0 go build -ldflags="-s -w" -o mcp-postgresql .
配置
配置遵循三层优先级: 默认值→ 环境变量→ CLI标志.
在解析配置之前,服务器可以选择从dotenv文件和映射规则中引导环境值:
- 加载dotenv文件(自动
.env和.env.local,或自定义文件) - 应用
MCP_ENV_MAP映射(TARGET=SOURCE) - 从环境变量别名+命令行界面标志解析配置
环境变量
服务器按以下顺序解析env变量:
- 主要PostgreSQL风格变量(
PG*,MCP_*) - 兼容别名(
POSTGRES_*,DB_*,MCP_SERVER_*)
在每个设置中,列表中的第一个非空变量获胜。
| 变量 | 必填 | 默认 | 描述 |
|---|---|---|---|
PGHOST (POSTGRES_HOST, DB_HOST) |
没有 | localhost |
PostgreSQL服务器主机名 |
PGPORT (POSTGRES_PORT, DB_PORT) |
没有 | 5432 |
PostgreSQL服务器端口 |
PGUSER (POSTGRES_USER, DB_USER) |
没有 | postgres |
数据库用户 |
PGPASSWORD (POSTGRES_PASSWORD, DB_PASSWORD) |
是 | -- | 数据库密码 |
PGDATABASE (POSTGRES_DB, POSTGRES_DATABASE, DB_NAME) |
没有 | postgres |
目标数据库名称 |
PGSSLMODE (POSTGRES_SSLMODE, DB_SSLMODE) |
没有 | prefer |
SSL模式(disable, allow, prefer, require, verify-ca, verify-full) |
MCP_READ_ONLY (MCP_SERVER_READ_ONLY) |
没有 | true |
访问模式: true 对于只读, false 用于读写 |
MCP_POOL_MAX_CONNS (MCP_SERVER_POOL_MAX_CONNS) |
没有 | 10 |
池中的最大连接数 |
MCP_ENV_FILES (MCP_ENV_FILE) |
否 | 自动(.env,.env.local) |
可选的dotenv文件覆盖(逗号分隔的路径) |
MCP_ENV_MAP |
否 | -- | 可选变量映射 TARGET=SOURCE,TARGET2=SOURCE2 |
Dotenv加载
- 自动模式:如果当前工作目录中存在,
.env和.env.local装载。 .env.local加载后.env,因此它可以覆盖以下值.env.- 现有的操作系统环境变量永远不会被dotenv文件覆盖。
- 集
MCP_ENV_FILES(或MCP_ENV_FILE)用一个或多个自定义文件替换自动模式。
示例(.env + .env.local):
# .env
PGHOST=localhost
PGUSER=app_user
PGPASSWORD=dev_password
PGDATABASE=app_db
# .env.local
MCP_READ_ONLY=false
MCP_POOL_MAX_CONNS=20
覆盖示例:
export MCP_ENV_FILES=".env,./config/db.env"
环境变量映射(MCP_ENV_MAP)
使用 MCP_ENV_MAP 当你的应用程序使用不同的变量名时。格式:
MCP_ENV_MAP="TARGET=SOURCE,TARGET2=SOURCE2"
规则:
- 映射在配置解析之前运行。
- 映射不会覆盖已填充的
TARGET变量。 - 如果
SOURCE如果为空/未设置,则跳过该映射条目。
示例(应用程序变量到PostgreSQL变量):
export DATABASE_HOST=db.internal
export DATABASE_USER=service_user
export DATABASE_PASSWORD=secret
export DATABASE_NAME=service_db
export MCP_ENV_MAP="PGHOST=DATABASE_HOST,PGUSER=DATABASE_USER,PGPASSWORD=DATABASE_PASSWORD,PGDATABASE=DATABASE_NAME"
CLI标志
| 旗帜 | 覆盖 | 描述 |
|---|---|---|
--host |
PGHOST |
PostgreSQL服务器主机名 |
--port |
PGPORT |
PostgreSQL服务器端口 |
--user |
PGUSER |
数据库用户 |
--password |
PGPASSWORD |
数据库密码 |
--database |
PGDATABASE |
目标数据库名称 |
--sslmode |
PGSSLMODE |
SSL模式 |
--read-only |
MCP_READ_ONLY |
只读模式(true 或 false) |
--pool-max-conns |
MCP_POOL_MAX_CONNS |
最大池连接数 |
--env-file |
MCP_ENV_FILES |
首先加载的Dotenv文件(重复或逗号分隔) |
CLI标志具有最高优先级——它们覆盖默认值和环境变量。
特别是对于dotenv文件,优先级为: --env-file > MCP_ENV_FILES / MCP_ENV_FILE >汽车 .env + .env.local.
与MCP客户端一起使用
Claude桌面--CLI标志
将以下内容添加到您的Claude Desktop配置中(claude_desktop_config.json):
{
"mcpServers": {
"postgresql": {
"command": "/path/to/mcp-postgresql",
"args": [
"--host", "localhost",
"--port", "5432",
"--user", "myuser",
"--password", "mypass",
"--database", "mydb"
]
}
}
}
Claude桌面--环境变量
{
"mcpServers": {
"postgresql": {
"command": "/path/to/mcp-postgresql",
"env": {
"PGHOST": "localhost",
"PGPORT": "5432",
"PGUSER": "myuser",
"PGPASSWORD": "mypass",
"PGDATABASE": "mydb",
"MCP_READ_ONLY": "true"
}
}
}
}
兼容别名示例
如果您的环境已经使用 POSTGRES_* / DB_* 命名,您可以直接使用这些:
export POSTGRES_HOST=localhost
export POSTGRES_PORT=5432
export POSTGRES_USER=myuser
export POSTGRES_PASSWORD=mypass
export POSTGRES_DB=mydb
export MCP_SERVER_READ_ONLY=true
其他MCP客户端
任何支持stdio传输的MCP客户端都可以使用此服务器。使用适当的标志或环境变量启动二进制文件——服务器使用MCP JSON-RPC协议通过stdin/stdout进行通信。
工具参考
query
执行读取SQL查询并将结果作为JSON返回。
输入:
{ "sql": "SELECT id, name FROM users WHERE active = true" }
输出:
{
"columns": ["id", "name"],
"rows": [
{"id": 1, "name": "Alice"},
{"id": 2, "name": "Bob"}
],
"row_count": 2
}
在只读模式下,所有查询都在 READ ONLY 事务——PostgreSQL拒绝写入尝试。
execute
执行写SQL语句(INSERT、UPDATE、DELETE、DDL)并返回受影响的行数。仅在读写模式下可用。
输入:
{ "sql": "UPDATE users SET active = true WHERE last_login > '2025-01-01'" }
输出:
{ "affected_rows": 42 }
list_schemas
列出数据库中所有用户定义的架构(不包括 pg_catalog, pg_toast, information_schema).
输入:
{}
输出:
{
"schemas": [
{"schema_name": "public", "owner": "postgres"},
{"schema_name": "reporting", "owner": "app_user"}
],
"count": 2
}
list_tables
列出架构中的所有表。默认为 public 如果没有指定模式。
输入:
{ "schema": "public" }
输出:
{
"schema": "public",
"tables": [
{"table_name": "users", "table_type": "BASE TABLE"},
{"table_name": "orders", "table_type": "BASE TABLE"}
],
"count": 2
}
describe_table
描述表的列、类型、可空性、默认值和主键状态。
输入:
{ "table_name": "users", "schema": "public" }
输出:
{
"schema": "public",
"table_name": "users",
"columns": [
{
"column_name": "id",
"data_type": "integer",
"is_nullable": false,
"column_default": "nextval('users_id_seq'::regclass)",
"is_primary_key": true
},
{
"column_name": "name",
"data_type": "character varying",
"is_nullable": false,
"column_default": null,
"is_primary_key": false
}
],
"column_count": 2
}
安全
只读模式(默认)
服务器默认为只读模式,在两个独立层强制执行:
- 刀具登记层:The
execute该工具未在MCP服务器上注册,客户端无法调用它。 - 事务层:The
query该工具将所有SQL封装在一个READ ONLY事务——PostgreSQL拒绝数据库级别的任何写入操作。
这两层同时活跃,提供深度防御。
建议
- 使用 只读模式 (默认值),除非您的用例特别需要写访问权限。
- 创建一个 PostgreSQL专用用户 MCP服务器的权限很小。
- 避免在生产环境中通过CLI标志传递密码——首选环境变量或机密管理器。
- 使用
--sslmode=require或者在通过网络连接时更严格。 - 集
--pool-max-conns适合您的工作负载,以避免耗尽数据库连接。
许可证
MIT许可证。看 许可证 了解详情。