PostgreSQL MCP服
一种极快的MCP服务器, enables AI代理与多个PostgreSQL数据库进行交互,提供列出表、检查模式、执行查询和运行事务的功能。
服务介绍
FastPostgresMCP 🐘⚡️ (全功能多数据库 MCP 服务器)
该项目实现了一个极速、类型安全且全功能的 Model Context Protocol (MCP) 服务器,旨在让 AI 代理(如 Cursor、Claude Desktop)能够与多个 PostgreSQL 数据库进行交互,包括列出表和检查模式。
它使用 Bun、TypeScript、postgres 构建,并利用了 fastmcp 框架的高级特性来构建强大的 MCP 服务器。
目的:面向 AI 代理的 MCP 服务器
这不是一个要导入到你的代码中的库。它是一个独立的服务器应用程序。你将其作为进程运行,而 MCP 客户端(如 AI 代理)通过基于 JSON 的 Model Context 协议(v2.0)与其通信,通常通过客户端应用程序(例如 Cursor)管理的 stdio 连接。
故障排除和开发
使用 CLI 进行测试
该包包含一个内置的 CLI 命令,用于直接测试 MCP 服务器:
# From the project repository:
bun run cli
# This will start an interactive MCP CLI session where you can:
# - Call any of the PostgreSQL tools (query_tool, execute_tool, etc.)
# - View server capabilities
# - Test queries against your configured databases
使用内置 MCP 检查器进行测试
您还可以使用 MCP 检查器以可视化方式测试和调试:
# From the project repository:
bun run inspect
常见问题
如果您在运行 bunx postgres-mcp 时看到此错误:
FastPostgresMCP started
[warning] FastMCP could not infer client capabilities
随后是 ping 消息,这意味着:
- MCP 服务器成功启动
- 客户端成功连接
- 但客户端仅发送 ping 请求,未正确协商功能
这通常表明您需要使用一个合适的 MCP 客户端。尝试:
- 使用
bun run cli通过 MCP CLI 进行测试 - 按照安装部分描述的方法在 Cursor 或 Claude Desktop 中配置 MCP 服务器
如果您正在开发自定义的 MCP 客户端,请确保它正确实现了 MCP 协议,包括功能协商。
✨ 核心功能
- 🚀 极速: 基于 Bun 和
fastmcp构建。 - 🔒 类型安全: 从头到尾使用 TypeScript,并通过 Zod 模式验证。
- 🐘 多数据库支持: 连接到并管理在
.env文件中定义的多个 PostgreSQL 实例之间的交互。 - 🛡️ 设计安全: 通过
postgres的参数化查询防止 SQL 注入。 - 🔑 可选认证: 使用 API Key 验证 (
fastmcp的authenticate钩子) 保护基于网络的连接 (SSE/HTTP)。 - 📄 通过 MCP 资源的数据库模式:
- 列出表: 通过
db://{dbAlias}/schema/tables获取数据库中的表列表。 - 检查表模式: 通过
db://{dbAlias}/schema/{tableName}获取特定表的详细列信息。
- 列出表: 通过
- 💬 增强工具交互:
- 工具内日志记录: 工具将详细的日志发送回客户端 (
log上下文)。 - 进度报告: 长时间运行的操作报告进度 (
reportProgress上下文)。
- 工具内日志记录: 工具将详细的日志发送回客户端 (
- 🧠 会话感知: 在工具执行上下文中访问会话信息 (
session上下文)。 - 📡 事件驱动: 使用
server.on和session.on处理连接/会话事件。 - 🔧 现代开发者体验 (DX): 清晰的配置、直观的 API,使用
fastmcp工具轻松测试。
包含的内容 (利用的 fastmcp 特性)
FastMCP服务器核心server.addTool(用于query_tool,execute_tool,schema_tool和transaction_tool)server.addResourceTemplate(用于列出表和检查表模式)server.start(以stdio为重点,可适应sse/http)- 可选:
authenticate钩子 (用于 API Key 验证) - 工具执行
context(log,reportProgress,session) - Zod 用于参数模式验证
server.on(用于连接日志记录)- (可能)
session.on用于会话特定逻辑
📋 先决条件
- Bun (推荐 v1.0 或更高版本): 安装并添加到 PATH 中。
- PostgreSQL 数据库: 访问凭证和连接性。用户需要有权限查询
information_schema。
⚙️ 安装
选项 1: NPM 包
# Install globally
npm install -g postgres-mcp
# Or install locally in your project
npm install postgres-mcp
npm 包可在 https://www.npmjs.com/package/postgres-mcp 找到。
选项 2: 克隆仓库
-
克隆仓库:
# 替换为您的实际仓库 URL git clone https://github.com/llm-graph/postgres-mcp.git cd postgres-mcp -
安装依赖:
bun install
🔑 配置 (多数据库 & 可选认证)
通过环境变量进行配置,从适当的 .env 文件加载。
-
创建环境文件:
- 对于生产环境:
cp .env.example .env - 对于开发环境:
cp .env.development.example .env.development
- 对于生产环境:
-
环境文件加载顺序:
服务器按照以下优先级顺序从文件中加载环境变量:.env.<NODE_ENV>(例如,.env.development、.env.production、.env.staging).env.local(用于本地覆盖,不进行版本控制).env(默认回退)
这允许为不同的环境配置不同的设置。
-
编辑环境文件以定义数据库连接和身份验证:
DB_ALIASES- 唯一数据库别名的逗号分隔列表DEFAULT_DB_ALIAS- 如果在工具调用中省略了'dbAlias',则使用此默认别名- 每个别名的数据库连接详情(例如,
DB_MAIN_HOST,DB_REPORTING_HOST) - 可选的API密钥认证(
ENABLE_AUTH,MCP_API_KEY)
# Example .env file - Key Variables
# REQUIRED: Comma-separated list of unique DB aliases
DB_ALIASES=main,reporting
# REQUIRED: Default alias if 'dbAlias' is omitted in tool calls
DEFAULT_DB_ALIAS=main
# OPTIONAL: Enable API Key auth (primarily for network transports)
ENABLE_AUTH=false
MCP_API_KEY=your_super_secret_api_key_here # CHANGE THIS
# Define DB connection details for each alias (DB_MAIN_*, DB_REPORTING_*, etc.)
DB_MAIN_HOST=localhost
DB_MAIN_PORT=5432
DB_MAIN_NAME=app_prod_db
DB_MAIN_USER=app_user
DB_MAIN_PASSWORD=app_secret_password
DB_MAIN_SSL=disable
# Alternative: Use connection URLs
# DB_MAIN_URL=postgres://user:password@localhost:5432/database?sslmode=require
# --- Optional: Server Logging Level ---
# LOG_LEVEL=info # debug, info, warn, error (defaults to info)
🚀 运行服务器(作为进程)
直接使用Bun运行此服务器。AI客户端(如Cursor)通常会为你启动并管理这个命令。
选项1:使用全局安装的包
- 手动运行:
postgres-mcp
选项2:在你的项目中使用该包
- 从项目运行:
npx postgres-mcp - 或以编程方式导入:
// server.js import { startServer } from 'postgres-mcp'; // 启动MCP服务器 startServer();
选项3:从克隆的仓库运行
- 手动运行(用于测试):
bun run src/index.ts - 手动开发模式:
bun run --watch src/index.ts
使用fastmcp CLI工具测试
- 交互式终端:
bunx fastmcp dev src/index.ts - Web UI检查器:
bunx fastmcp inspect src/index.ts
💻 以库的形式使用程序化API
除了作为独立的MCP服务器运行外,还可以将postgres-mcp作为库以编程方式在你的Node.js/TypeScript应用程序中使用。
基本用法
import { createPostgresMcp } from 'postgres-mcp';
// Create the PostgresMcp instance
const postgresMcp = createPostgresMcp();
// Start the server
postgresMcp.start();
// Direct database operations
const results = await postgresMcp.executeQuery(
'SELECT * FROM users WHERE role = $1',
['admin'],
'main' // optional database alias
);
// When done, stop the server and close connections
await postgresMcp.stop();
直接函数导入
对于更简单的用例,你可以直接导入特定函数:
import {
initConnections,
closeConnections,
executeQuery,
executeCommand,
executeTransaction,
getTableSchema,
getAllTableSchemas
} from 'postgres-mcp';
// Configure database connections
const dbConfigs = {
main: {
host: 'localhost',
port: 5432,
database: 'my_db',
user: 'db_user',
password: 'db_password'
}
};
// Initialize connections
initConnections(dbConfigs);
// Execute a query
const results = await executeQuery(
'SELECT * FROM users WHERE role = $1',
['admin'],
'main'
);
// Get schema for a single table
const schema = await getTableSchema('users', 'main');
// Get schema for all tables in the database
const allSchemas = await getAllTableSchemas('main');
// Close connections when done
await closeConnections();
配置选项
const postgresMcp = createPostgresMcp({
// Custom database configurations (override .env)
databaseConfigs: {
main: {
host: 'localhost',
port: 5432,
database: 'app_db',
user: 'app_user',
password: 'password',
ssl: 'disable'
}
},
// Server configuration
serverConfig: {
name: 'Custom PostgresMCP',
defaultDbAlias: 'main'
},
// Transport options: 'stdio', 'sse', or 'http'
transport: 'http',
port: 3456
});
有关程序化API的完整文档,请参阅docs/programmatic-api.md。
🔌 与AI客户端(Cursor, Claude Desktop)连接
配置你的AI代理(MCP客户端)通过其命令/参数机制来执行此服务器脚本。
Cursor AI - 详细示例
-
打开光标设置/首选项 (Cmd+, 或 Ctrl+,).
-
导航到 "扩展" -> "MCP"。
-
点击 "添加 MCP 服务器" 或编辑
settings.json。 -
添加以下 JSON 配置:
// 在 Cursor 的 settings.json 或 MCP 配置 UI 中 { "mcpServers": { "postgres-mcp": { // 对于 Cursor 的唯一名称 "description": "用于 PostgreSQL 数据库的 MCP 服务器(主数据库,报告)", "command": "bunx", // 使用 'bun' 或提供绝对路径: "/Users/your_username/.bun/bin/bun" "args": [ "postgres-mcp" // 或者 // *** 服务器入口点的绝对路径 *** // "/Users/your_username/projects/postgres-mcp/src/index.ts" / ], "env": { // 项目目录中的 .env 文件将由 Bun 自动加载。 // 如果需要,此处可以添加覆盖或特定于 Cursor 的变量。 }, "enabled": true } } } -
保存 并 重启光标 或 "重新加载 MCP 服务器"。
-
在光标的 MCP 状态/日志中验证连接。
Claude Desktop
- 查找并编辑
config.json(参见之前的 README 获取路径)。 - 在
mcpServers下添加一个类似的条目,使用args中的绝对路径。 - 重启 Claude Desktop。
🛠️ 暴露的 MCP 功能
身份验证(可选)
- 通过匹配
X-API-Key标头与MCP_API_KEY来保护网络传输(HTTP/SSE),如果ENABLE_AUTH=true。 stdio连接(Cursor/Claude 默认)通常绕过此检查。
资源
1. 列出数据库表
- URI 模板:
db://{dbAlias}/schema/tables - 描述: 检索指定数据库别名内的用户表名列表(通常来自 'public' 模式)。
- 资源定义 (
addResourceTemplate):uriTemplate:"db://{dbAlias}/schema/tables"arguments:dbAlias: (字符串, 必需) - 数据库的别名(来自.env)。
load({ dbAlias }): 连接到数据库,查询information_schema.tables(过滤公共模式下的基础表,实现中可自定义),将结果格式化为 JSON 字符串数组["table1", "table2", ...],并返回{ text: "..." }。
示例用法(AI 提示): "获取资源 db://main/schema/tables 以列出主数据库中的表。"
2. 检查表结构
- URI 模板:
db://{dbAlias}/schema/{tableName} - 描述: 为特定表提供详细的模式信息(列、类型、是否可为空、默认值)。
- 资源定义 (
addResourceTemplate):uriTemplate:"db://{dbAlias}/schema/{tableName}"arguments:dbAlias: (字符串,必填) - 数据库别名。tableName: (字符串,必填) - 表的名称。
load({ dbAlias, tableName }): 连接数据库,查询information_schema.columns以获取特定表的信息,格式化为列对象的 JSON 字符串数组,返回{ text: "..." }。
示例用法 (AI 提示): "描述资源 db://reporting/schema/daily_sales。"
示例响应内容 (JSON 字符串):
"[{\"column_name\":\"session_id\",\"data_type\":\"uuid\",\"is_nullable\":\"NO\",\"column_default\":\"gen_random_uuid()\"},{\"column_name\":\"user_id\",\"data_type\":\"integer\",\"is_nullable\":\"NO\",\"column_default\":null},{\"column_name\":\"created_at\",\"data_type\":\"timestamp with time zone\",\"is_nullable\":\"YES\",\"column_default\":\"now()\"},{\"column_name\":\"expires_at\",\"data_type\":\"timestamp with time zone\",\"is_nullable\":\"YES\",\"column_default\":null}]"
工具
工具接收 context 对象 (log, reportProgress, session)。
1. query_tool
执行只读 SQL 查询。
- 描述: 安全地执行只读 SQL,获取结果,并记录执行日志/进度。
- 参数:
statement(字符串),params(数组, 可选),dbAlias(字符串, 可选)。 - 上下文使用:
log.info/debug, 可选reportProgress, 访问session。 - 返回: 行数组的 JSON 字符串。
示例请求:
{
"tool_name": "query_tool",
"arguments": {
"statement": "SELECT product_id, name, price FROM products WHERE category = $1 AND price < $2 ORDER BY name LIMIT 10",
"params": ["electronics", 500],
"dbAlias": "main"
}
}
示例响应内容 (JSON 字符串):
"[{\"product_id\":123,\"name\":\"Example Gadget\",\"price\":499.99},{\"product_id\":456,\"name\":\"Another Device\",\"price\":350.00}]"
2. execute_tool
执行数据修改的 SQL 语句。
- 描述: 安全地执行数据修改的 SQL,并记录执行日志。
- 参数:
statement(字符串),params(数组, 可选),dbAlias(字符串, 可选)。 - 上下文使用:
log.info/debug, 访问session。 - 返回: 指示受影响行数的字符串。
示例请求:
{
"tool_name": "execute_tool",
"arguments": {
"statement": "UPDATE users SET last_login = NOW() WHERE user_id = $1",
"params": [54321]
// dbAlias omitted, uses DEFAULT_DB_ALIAS
}
}
示例响应内容 (字符串):
"Rows affected: 1"
3. schema_tool
检索特定表的详细模式信息。
- 描述: 获取数据库表的列定义和详细信息。
- 参数:
tableName(字符串),dbAlias(字符串, 可选)。 - 上下文使用:
log.info, 访问session。 - 返回: 列信息对象的 JSON 字符串数组。
示例请求:
{
"tool_name": "schema_tool",
"arguments": {
"tableName": "user_sessions",
"dbAlias": "main"
}
}
示例响应内容 (JSON 字符串):
"[{\"column_name\":\"session_id\",\"data_type\":\"uuid\",\"is_nullable\":\"NO\",\"column_default\":\"gen_random_uuid()\"},{\"column_name\":\"user_id\",\"data_type\":\"integer\",\"is_nullable\":\"NO\",\"column_default\":null},{\"column_name\":\"created_at\",\"data_type\":\"timestamp with time zone\",\"is_nullable\":\"YES\",\"column_default\":\"now()\"},{\"column_name\":\"expires_at\",\"data_type\":\"timestamp with time zone\",\"is_nullable\":\"YES\",\"column_default\":null}]"
4. transaction_tool
原子性地执行多个 SQL 语句。
- 描述: 在事务中执行 SQL 序列,并记录步骤日志/进度。
- 参数:
operations(包含 {statement, params} 的数组),dbAlias(字符串, 可选)。 - 上下文使用:
log.info/debug/error,reportProgress, 访问session。 - 返回: 总结成功/失败的 JSON 字符串:
{"success": true, "results": [...]}或{"success": false, "error": ..., "failedOperationIndex": ...}。
示例请求:
{
"tool_name": "transaction_tool",
"arguments": {
"operations": [
{
"statement": "INSERT INTO orders (customer_id, order_date, status) VALUES ($1, NOW(), 'pending') RETURNING order_id",
"params": [101]
},
{
"statement": "INSERT INTO order_items (order_id, product_sku, quantity, price) VALUES ($1, $2, $3, $4)",
"params": [9999, "GADGET-X", 2, 49.99]
},
{
"statement": "UPDATE inventory SET stock_count = stock_count - $1 WHERE product_sku = $2 AND stock_count >= $1",
"params": [2, "GADGET-X"]
}
],
"dbAlias": "main"
}
}
示例成功响应内容 (JSON 字符串):
"{\"success\":true,\"results\":[{\"operation\":0,\"rowsAffected\":1},{\"operation\":1,\"rowsAffected\":1},{\"operation\":2,\"rowsAffected\":1}]}"
示例错误响应内容 (JSON 字符串):
"{\"success\":false,\"error\":\"Error executing operation 2: new row for relation \\\"inventory\\\" violates check constraint \\\"stock_count_non_negative\\\"\",\"failedOperationIndex\":2}"
服务器与会话事件
- 使用
server.on('connect'/'disconnect')来记录客户端连接。 - 如果需要更细粒度的会话事件处理,可以使用
session.on(...)。
🔒 安全注意事项
- SQL 注入: 通过参数化查询来缓解。不直接拼接输入。
- 数据库权限: 至关重要。 为每个
DB_<ALIAS>_USER分配最小权限,包括对information_schema的读取权限,以便列出模式/表资源。 - SSL/TLS: 生产环境中必不可少(
DB_<ALIAS>_SSL=require或更严格)。 - 密钥管理: 保护
.env文件(将其添加到.gitignore中)。在生产环境中使用安全的密钥管理(如 Vault、Doppler、云密钥)。 - 认证范围:
authenticate钩子主要用于保护网络传输。stdio的安全性依赖于执行环境。 - 数据敏感性: 注意通过连接和工具可访问的数据。
- 资源查询: 用于列出表 (
information_schema.tables) 和模式 (information_schema.columns) 的查询通常是安全的,但依赖于数据库权限。确保配置的用户具有适当的读取权限。如果出于安全或清晰性的考虑,可以根据需要自定义表列表查询(例如,模式过滤)。
📜 许可证
本项目采用 MIT 许可证。详情请参阅 LICENSE 文件。
📋 更新日志
1.0.0
- 初始发布
- 全功能的 PostgreSQL MCP 服务器
- 支持多个数据库连接
- 提供查询、执行、模式检查和事务的工具
- 模式内省资源
- 全面的文档和示例