MCP PostgreSQL服务器
生产准备就绪 模型上下文协议(MCP) PostgreSQL数据库操作服务器。该服务器使AI助手和应用程序能够通过具有动态模式发现、CRUD操作和安全查询执行的标准化接口与PostgreSQL数据库进行交互。
特性
🔍 自动发现
- 自动表发现:扫描并识别PostgreSQL数据库中的所有表
- 模式自省:检索列名、数据类型、约束和关系
- 动态工具生成:根据您的实际数据库结构创建工具
- 智能缓存:缓存架构元数据以提高性能
🛠️ 综合工具
list_tables:列出数据库中的所有可用表get_table_info:获取任何表的详细架构信息query_table:使用筛选、排序和分页查询表insert_record:插入具有自动验证功能的新记录update_records:使用基于筛选的目标更新记录delete_records:使用强制筛选器安全删除记录execute_sql:使用参数化输入执行自定义SQL查询get_database_stats:检索数据库统计信息和表大小
🔒 安全功能
- 参数化查询:所有查询都使用参数绑定来防止SQL注入
- 连接池:具有可配置池大小的高效连接管理
- 错误处理:全面的错误处理和详细的日志记录
- 安全删除:需要过滤器来防止意外批量删除
⚡ 演出
- 连接池:重用数据库连接以获得最佳性能
- 架构缓存:通过缓存表元数据减少数据库查询
- 高效查询:使用PostgreSQL的内置优化
- 可配置的限制:控制查询结果大小以防止内存问题
安装
先决条件
- Python 3.10或更高版本
- PostgreSQL数据库(12+版本)
- pip包管理器
步骤1:克隆存储库
git clone https://github.com/yourusername/MCP-DB-Postgres.git
cd MCP-DB-Postgres步骤2:安装依赖项
pip install -r requirements.txt或单独安装:
pip install fastmcp psycopg2-binary python-dotenv步骤3:配置环境
创建一个 .env 项目根目录中的文件:
cp .env.example .env编辑 .env 使用您的PostgreSQL连接详细信息:
# PostgreSQL Connection String
# Format: postgresql://username:password@host:port/database
POSTGRES_CONNECTION_STRING=postgresql://myuser:mypassword@localhost:5432/mydatabase
# Connection Pool Configuration
POSTGRES_MIN_CONNECTIONS=1
POSTGRES_MAX_CONNECTIONS=10替代方案:直接连接字符串
您也可以直接设置连接字符串:
export POSTGRES_CONNECTION_STRING="postgresql://user:password@localhost:5432/database"PostgreSQL连接字符串格式
服务器支持多种连接字符串格式:
标准格式
postgresql://username:password@host:port/database使用SSL
postgresql://username:password@host:port/database?sslmode=require附加参数
postgresql://username:password@host:port/database?sslmode=require&connect_timeout=10URL编码密码(用于特殊字符)
postgresql://user:p%40ssw0rd@host:5432/db示例
地方发展:
postgresql://postgres:postgres@localhost:5432/myapp云提供商(AWS RDS):
postgresql://dbuser:SecurePass123@mydb.abc123.us-east-1.rds.amazonaws.com:5432/production赫罗尔德·波斯特格雷斯:
postgresql://user:pass@ec2-1-2-3-4.compute-1.amazonaws.com:5432/dbname?sslmode=requireDocker容器:
postgresql://postgres:postgres@postgres-container:5432/mydb运行服务器
发展模式
python mcp_postgres_server.py带systemd的生产模式
创建systemd服务文件 /etc/systemd/system/mcp-postgres.service:
[Unit]
Description=MCP PostgreSQL Server
After=network.target postgresql.service
[Service]
Type=simple
User=youruser
WorkingDirectory=/path/to/MCP-DB-Postgres
Environment="POSTGRES_CONNECTION_STRING=postgresql://user:pass@localhost:5432/db"
ExecStart=/usr/bin/python3 /path/to/MCP-DB-Postgres/mcp_postgres_server.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target启用并启动:
sudo systemctl enable mcp-postgres
sudo systemctl start mcp-postgres
sudo systemctl status mcp-postgres集成指南
连接到克劳德桌面
- 找到Claude桌面配置文件:
- macOS: ~/Library/Application Support/Claude/claude_desktop_config.json - 视窗: %APPDATA%/Claude/claude_desktop_config.json - Linux: ~/.config/Claude/claude_desktop_config.json
- 添加MCP服务器配置:
{
"mcpServers": {
"postgres": {
"command": "python",
"args": [
"/absolute/path/to/MCP-DB-Postgres/mcp_postgres_server.py"
],
"env": {
"POSTGRES_CONNECTION_STRING": "postgresql://user:password@localhost:5432/database"
}
}
}
}- 重新启动克劳德桌面
- 验证连接:
- 打开克劳德桌面 - 寻找MCP指示器(通常在角落里) - 您应该看到“postgres”被列为可用服务器 - 试着问:“列出所有数据库表”
连接到n8n
n8n通过自定义集成支持MCP服务器。以下是如何连接:
选项1:使用n8n的HTTP请求节点
- 启动MCP服务器 (确保可访问)
- 创建n8n工作流:
- 添加“HTTP请求”节点 - 配置它以调用您的MCP服务器端点 - 对请求使用MCP协议格式
- 示例n8n HTTP请求配置:
{
"method": "POST",
"url": "http://localhost:8000/mcp/rpc",
"authentication": "none",
"requestFormat": "json",
"bodyParameters": {
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "list_tables",
"arguments": {}
},
"id": 1
}
}选项2:使用n8n的功能节点
创建一个功能节点以与MCP服务器交互:
// Import the MCP client library
const { Client } = require('@modelcontextprotocol/sdk/client/index.js');
// Initialize MCP client
const client = new Client({
name: "n8n-postgres-client",
version: "1.0.0"
});
// Connect to MCP server
await client.connect({
command: "python",
args: ["/path/to/mcp_postgres_server.py"],
env: {
POSTGRES_CONNECTION_STRING: "postgresql://user:pass@host:5432/db"
}
});
// Call a tool
const result = await client.callTool("list_tables", {});
return [{ json: result }];选项3:自定义n8n节点
对于生产使用,创建一个自定义n8n节点:
- 创建节点结构:
mkdir n8n-nodes-mcp-postgres
cd n8n-nodes-mcp-postgres
npm init- 安装依赖关系:
npm install @modelcontextprotocol/sdk- 创建节点代码 (有关完整节点开发,请参阅n8n文档)
- 链接到n8n:
npm link
cd ~/.n8n/custom
npm link n8n-nodes-mcp-postgres用法示例
示例1:列出所有表
# Using the MCP client
result = await client.call_tool("list_tables", {})
print(result)输出:
{
"success": true,
"tables": ["users", "products", "orders", "customers"],
"count": 4
}示例2:获取表架构
result = await client.call_tool("get_table_info", {
"table_name": "users"
})输出:
{
"success": true,
"schema": {
"table_name": "users",
"columns": [
{
"column_name": "id",
"data_type": "integer",
"is_nullable": "NO",
"column_default": "nextval('users_id_seq'::regclass)"
},
{
"column_name": "email",
"data_type": "character varying",
"character_maximum_length": 255,
"is_nullable": "NO",
"column_default": null
},
{
"column_name": "created_at",
"data_type": "timestamp without time zone",
"is_nullable": "YES",
"column_default": "CURRENT_TIMESTAMP"
}
],
"primary_keys": ["id"],
"foreign_keys": []
}
}示例3:使用过滤器进行查询
result = await client.call_tool("query_table", {
"table_name": "users",
"filters": '{"age": {"$gt": 18}, "status": "active"}',
"columns": "id, email, age",
"limit": 10,
"offset": 0,
"sort_by": "created_at DESC"
})示例4:插入记录
result = await client.call_tool("insert_record", {
"table_name": "users",
"data": '{"email": "john@example.com", "age": 30, "status": "active"}'
})示例5:更新记录
result = await client.call_tool("update_records", {
"table_name": "users",
"filters": '{"id": 1}',
"updates": '{"status": "inactive", "updated_at": "2024-01-01T00:00:00"}'
})示例6:删除记录
result = await client.call_tool("delete_records", {
"table_name": "users",
"filters": '{"status": "deleted", "created_at": {"$lt": "2023-01-01"}}'
})示例7:执行自定义SQL
result = await client.call_tool("execute_sql", {
"query": "SELECT u.email, COUNT(o.id) as order_count FROM users u LEFT JOIN orders o ON u.id = o.user_id WHERE u.status = %s GROUP BY u.email",
"params": '["active"]'
})示例8:高级过滤
服务器支持高级筛选器运算符:
filters = {
"age": {"$gte": 18, "$lte": 65}, # Age between 18 and 65
"email": {"$like": "%@gmail.com"}, # Email ends with @gmail.com
"status": {"$in": ["active", "pending"]}, # Status is active or pending
"deleted_at": None # Not deleted (IS NULL)
}
result = await client.call_tool("query_table", {
"table_name": "users",
"filters": json.dumps(filters),
"limit": 50
})过滤器操作员
服务器支持以下筛选器运算符:
| 操作员 | 描述 | 示例 |
|---|---|---|
$gt | 大于 | {"age": {"$gt": 18}} |
$gte | 大于或等于 | {"age": {"$gte": 18}} |
$lt | 小于 | {"age": {"$lt": 65}} |
$lte | 小于或等于 | {"age": {"$lte": 65}} |
$ne | 不相等 | {"status": {"$ne": "deleted"}} |
$like | SQL LIKE(区分大小写) | {"email": {"$like": "%@gmail.com"}} |
$ilike | SQL ILIKE(不区分大小写) | {"name": {"$ilike": "%john%"}} |
$in | 阵列内 | {"status": {"$in": ["active", "pending"]}} |
null | 为空 | {"deleted_at": null} |
建筑
组件
┌─────────────────────────────────────────────────────┐
│ MCP Client │
│ (Claude Desktop, n8n, etc.) │
└─────────────────────┬───────────────────────────────┘
│
│ MCP Protocol
│
┌─────────────────────▼───────────────────────────────┐
│ FastMCP Server │
│ ┌─────────────────────────────────────────────┐ │
│ │ Tool Registration │ │
│ │ - list_tables - query_table │ │
│ │ - get_table_info - insert_record │ │
│ │ - update_records - delete_records │ │
│ │ - execute_sql - get_database_stats │ │
│ └─────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────────────────────────────────────┐ │
│ │ Connection Pool Manager │ │
│ │ (psycopg2.pool.SimpleConnectionPool) │ │
│ └─────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────────────────────────────────────┐ │
│ │ Schema Cache Layer │ │
│ │ (In-memory metadata storage) │ │
│ └─────────────────────────────────────────────┘ │
└─────────────────────┬───────────────────────────────┘
│
│ PostgreSQL Protocol
│
┌─────────────────────▼───────────────────────────────┐
│ PostgreSQL Database │
│ ┌─────────────┐ ┌─────────────┐ ┌────────────┐ │
│ │ Tables │ │ Indexes │ │ Constraints│ │
│ └─────────────┘ └─────────────┘ └────────────┘ │
└─────────────────────────────────────────────────────┘数据流
- 客户端请求:MCP客户端发送工具调用请求
- 工具执行:FastMCP路由到适当的工具功能
- 连接获取:从池获取连接
- 查询构建:构造参数化SQL查询
- 执行:对PostgreSQL执行查询
- 结果处理:将结果转换为JSON可序列化格式
- 响应:向客户端返回格式化的响应
- 连接返回:返回到池的连接
安全最佳实践
1.使用强数据库凭据
# Generate strong password
openssl rand -base64 322.使用SSL/TLS进行数据库连接
POSTGRES_CONNECTION_STRING=postgresql://user:pass@host:5432/db?sslmode=require3.限制数据库用户权限
-- Create a limited user for the MCP server
CREATE USER mcp_user WITH PASSWORD 'strong_password';
-- Grant only necessary permissions
GRANT CONNECT ON DATABASE mydb TO mcp_user;
GRANT USAGE ON SCHEMA public TO mcp_user;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO mcp_user;
-- Optionally, restrict to specific tables
GRANT SELECT, INSERT, UPDATE, DELETE ON users, products, orders TO mcp_user;4.使用环境变量
切勿在代码中硬编码凭据。始终使用环境变量或秘密管理系统。
5.启用连接限制
POSTGRES_MAX_CONNECTIONS=10 # Limit concurrent connections6.监控和记录
服务器包括全面的日志记录。监控可疑活动的日志:
# Tail logs
tail -f /var/log/mcp-postgres.log
# Search for errors
grep ERROR /var/log/mcp-postgres.log故障排除
连接问题
问题:“连接池未初始化”
解决方案:确保 POSTGRES_CONNECTION_STRING 在启动服务器之前设置。
export POSTGRES_CONNECTION_STRING="postgresql://user:pass@localhost:5432/db"
python mcp_postgres_server.py______________________________________________________________________
问题:“致命:密码验证失败”
解决方案:
- 验证连接字符串中的用户名和密码
- 检查PostgreSQL
pg_hba.conf认证设置 - 确保用户具有CONNECT权限
______________________________________________________________________
问题:“无法连接到服务器:连接被拒绝”
解决方案:
- 验证PostgreSQL是否正在运行:
sudo systemctl status postgresql - 检查连接字符串中的主机和端口
- 验证防火墙规则是否允许连接
- 测试连接:
psql -h host -p port -U user -d database
性能问题
问题:查询速度慢
解决方案:
- 为频繁查询的列添加索引
- 使用
EXPLAIN ANALYZE识别瓶颈 - 增加连接池大小
- 启用查询结果缓存
______________________________________________________________________
问题:连接太多
解决方案:
- 减少
POSTGRES_MAX_CONNECTIONS - 实现连接超时
- 检查应用程序代码中的连接泄漏
架构发现问题
问题:未出现表格
解决方案:
- 确保桌子在
public模式 - 检查用户是否具有SELECT权限
information_schema - 清除架构缓存并重新启动服务器
发展
运行测试
# Install test dependencies
pip install pytest pytest-asyncio
# Run tests
pytest tests/代码的风格
# Install development dependencies
pip install black flake8 mypy
# Format code
black mcp_postgres_server.py
# Lint
flake8 mcp_postgres_server.py
# Type check
mypy mcp_postgres_server.py贡献
- 分叉存储库
- 创建要素分支:
git checkout -b feature/my-feature - 提交您的更改:
git commit -am 'Add new feature' - 推到分支:
git push origin feature/my-feature - 提交拉取请求
许可证
MIT许可证-有关详细信息,请参阅许可证文件
支持
- 问题:
- 文档: 全部文件
- 讨论:
更新日志
版本1.0.0(2024-01-15)
- 初始版本
- PostgreSQL表的自动发现
- CRUD操作(创建、读取、更新、删除)
- 自定义SQL查询执行
- 连接池
- 架构缓存
- 全面的错误处理
- 支持高级过滤器操作员
- 数据库统计工具
致谢
______________________________________________________________________
由以下材料制成❤️ 对于MCP社区
