database/README.md
2025-12-28 15:54:35 +08:00

443 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# MCP Database Server
WebSocket-based PostgreSQL tooling service for AI clients using the Model Context Protocol (MCP).
## Features
- **WebSocket Transport**: Long-running daemon accessible by multiple AI clients
- **Multi-Environment Support**: Connect to multiple PostgreSQL databases with different schemas
- **Token Authentication**: Secure Bearer token authentication
- **Session Isolation**: Per-client session management with transaction binding
- **Audit Logging**: JSON Lines format with SQL sanitization
- **Health Check**: Built-in `/health` endpoint for monitoring
- **Docker Ready**: Multi-stage build with minimal image size
## Quick Start
### 1. Install Dependencies
```bash
npm install
```
### 2. Build
```bash
npm run build
```
### 3. Generate Auth Token
```bash
node scripts/generate-token.js
```
### 4. Create Configuration
```bash
cp config/database.example.json config/database.json
# Edit config/database.json with your database connections
```
### 5. Start Server
```bash
export MCP_AUTH_TOKEN="your-generated-token"
export MCP_DRWORKS_PASSWORD="your-db-password"
node dist/server.js --config config/database.json
```
### 6. Verify
```bash
curl http://localhost:7700/health
```
## Configuration
### Configuration File Format
```json
{
"server": {
"listen": {
"host": "0.0.0.0",
"port": 7700
},
"auth": {
"type": "token",
"token": "ENV:MCP_AUTH_TOKEN"
},
"maxConcurrentClients": 50,
"logLevel": "info"
},
"environments": {
"mydb": {
"type": "postgres",
"connection": {
"host": "localhost",
"port": 5432,
"database": "mydb",
"user": "postgres",
"password": "ENV:MCP_MYDB_PASSWORD"
},
"defaultSchema": "public",
"searchPath": ["public", "app"],
"pool": {
"max": 10,
"idleTimeoutMs": 30000
},
"statementTimeoutMs": 60000,
"mode": "readonly"
}
},
"audit": {
"enabled": true,
"output": "stdout",
"redactParams": true,
"maxSqlLength": 200
}
}
```
配置结构总览
{
"server": { ... }, // 服务器配置
"environments": { ... }, // 数据库环境配置(可多个)
"audit": { ... } // 审计日志配置
}
---
一、server - 服务器配置
"server": {
"listen": {
"host": "0.0.0.0", // 监听地址
// "0.0.0.0" = 所有网卡(外部可访问)
// "127.0.0.1" = 仅本机
"port": 7700 // WebSocket 端口
},
"auth": {
"type": "token", // 鉴权类型token / mtls / none
"token": "ENV:MCP_AUTH_TOKEN" // Token 值,从环境变量读取
},
"maxConcurrentClients": 50, // 最大同时连接的客户端数
"logLevel": "info" // 日志级别debug / info / warn / error
}
---
二、environments - 数据库环境
每个环境是一个独立的连接池,可配置多个:
"environments": {
"drworks": { // 环境名(调用工具时指定)
"type": "postgres", // 数据库类型(目前仅支持 postgres
"connection": { // ═══ 连接参数 ═══
"host": "47.99.124.43", // 数据库服务器 IP/域名
"port": 5432, // PostgreSQL 端口
"database": "shcis_drworks_cpoe_pg", // 数据库名
"user": "postgres", // 用户名
"password": "passw0rd!", // 密码(建议用 ENV:
"ssl": {
"require": false // SSL 连接true=强制false=不使用
}
},
"defaultSchema": "dbo", // ═══ 模式配置 ═══
// 默认模式,工具调用不传 schema 时使用
"searchPath": ["dbo", "api", "nurse"],
// 搜索路径,查询时按顺序在这些模式中查找表
// 例SELECT * FROM patient 会先找 dbo.patient
"pool": { // ═══ 连接池配置 ═══
"max": 10, // 最大连接数(并发查询上限)
"idleTimeoutMs": 30000, // 空闲连接 30 秒后释放
"connectionTimeoutMs": 10000 // 获取连接超时 10 秒
},
"statementTimeoutMs": 60000, // SQL 执行超时 60 秒(防止卡死)
"slowQueryMs": 2000, // 超过 2 秒记录慢查询告警
"mode": "ddl" // ═══ 权限模式 ═══
// readonly = 只能 SELECT
// readwrite = 可 INSERT/UPDATE/DELETE
// ddl = 可 CREATE/ALTER/DROP最高权限
},
"ipworkstation": { ... } // 第二个环境,配置类似
}
---
三、audit - 审计日志
"audit": {
"enabled": true, // 是否启用审计日志
"output": "stdout", // 输出位置:
// "stdout" = 标准输出(容器推荐)
// "/var/log/mcp/audit.log" = 文件
"format": "json", // 格式json便于日志系统解析
"redactParams": true, // 脱敏SQL 参数值替换为 [REDACTED]
"maxSqlLength": 200 // SQL 预览最大长度(超出截断)
}
---
### Environment Variable Resolution
Use `ENV:VAR_NAME` syntax to reference environment variables:
```json
{
"password": "ENV:MCP_MYDB_PASSWORD"
}
```
### Configuration Fields
#### server
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| listen.host | string | "0.0.0.0" | Listen address |
| listen.port | number | 7700 | Listen port |
| auth.type | string | "token" | Authentication type: token, mtls, none |
| auth.token | string | - | Bearer token (required if type=token) |
| maxConcurrentClients | number | 50 | Maximum WebSocket connections |
| logLevel | string | "info" | Log level: debug, info, warn, error |
#### environments
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| type | string | "postgres" | Database type (only postgres supported) |
| connection.host | string | - | PostgreSQL host |
| connection.port | number | 5432 | PostgreSQL port |
| connection.database | string | - | Database name |
| connection.user | string | - | Username |
| connection.password | string | - | Password |
| connection.ssl | object | - | SSL configuration |
| defaultSchema | string | "public" | Default schema |
| searchPath | string[] | - | Schema search path |
| pool.max | number | 10 | Max pool connections |
| pool.idleTimeoutMs | number | 30000 | Idle connection timeout |
| statementTimeoutMs | number | 60000 | Query timeout |
| mode | string | "readonly" | Permission mode: readonly, readwrite, ddl |
#### audit
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| enabled | boolean | true | Enable audit logging |
| output | string | "stdout" | Output: stdout or file path |
| redactParams | boolean | true | Redact SQL parameters |
| maxSqlLength | number | 200 | Max SQL preview length |
## Command Line Options
```bash
node dist/server.js [options]
Options:
--config <path> Configuration file path (default: ./config/database.json)
--listen <host:port> Listen address (overrides config)
--auth-token <token> Auth token (overrides config)
--log-level <level> Log level (overrides config)
```
Environment variables override configuration file:
| Variable | Description |
|----------|-------------|
| MCP_CONFIG | Configuration file path |
| MCP_LISTEN | Listen address (host:port) |
| MCP_AUTH_TOKEN | Authentication token |
| MCP_LOG_LEVEL | Log level |
| MCP_<ENV>_PASSWORD | Database password for environment |
## Authentication
### Token Authentication
Clients must provide a Bearer token in the WebSocket handshake:
```http
GET / HTTP/1.1
Upgrade: websocket
Authorization: Bearer your-token-here
```
Generate a secure token:
```bash
node scripts/generate-token.js
# Output: 64-character hex string
```
### Client Configuration (Claude Code)
```json
{
"mcpServers": {
"database": {
"transport": "websocket",
"endpoint": "ws://localhost:7700",
"headers": {
"Authorization": "Bearer your-token-here"
}
}
}
}
```
## Available Tools
The server exposes 30+ MCP tools for PostgreSQL operations:
### Metadata Tools
- `pg_list_environments` - List configured database environments
- `pg_list_schemas` - List schemas in an environment
- `pg_list_tables` - List tables in a schema
- `pg_describe_table` - Get table structure
- `pg_list_views` - List views
- `pg_list_functions` - List functions
- `pg_list_indexes` - List indexes
- `pg_list_constraints` - List constraints
- `pg_list_triggers` - List triggers
### Query Tools
- `pg_query` - Execute read-only SQL query
- `pg_explain` - Get query execution plan
### Data Tools
- `pg_insert` - Insert rows
- `pg_update` - Update rows
- `pg_delete` - Delete rows
- `pg_upsert` - Insert or update rows
- `pg_bulk_insert` - Insert multiple rows
### Transaction Tools
- `pg_begin_transaction` - Start transaction
- `pg_commit_transaction` - Commit transaction
- `pg_rollback_transaction` - Rollback transaction
### Diagnostic Tools
- `pg_analyze_query` - Analyze query performance
- `pg_check_connection` - Check database connectivity
## Docker Deployment
### Build Image
```bash
docker build -t mcp-database-server:1.0.0 .
docker build -t mcp-database-server:1.0.1.02 .
docker build -t mcp-database-server:1.0.1.03 .
docker build -t mcp-database-server:1.0.2 .
docker compose build --no-cache && docker compose up -d
```
### Run Container
```bash
docker run -d \
--name mcp-database-server \
-p 7700:7700 \
-v $(pwd)/config/database.json:/app/config/database.json:ro \
-e MCP_AUTH_TOKEN=your-token \
-e MCP_DRWORKS_PASSWORD=your-password \
mcp-database-server:1.0.0
```
### Docker Compose
```bash
cp docker-compose.example.yml docker-compose.yml
cp config/database.example.json config/database.json
# Edit configuration files
# Create .env file
echo "MCP_AUTH_TOKEN=$(node scripts/generate-token.js | head -2 | tail -1)" > .env
echo "MCP_DRWORKS_PASSWORD=your-password" >> .env
# Start
docker compose up -d
```
## Health Check
The server exposes a health check endpoint:
```bash
curl http://localhost:7700/health
```
Response:
```json
{
"status": "ok",
"uptime": 3600,
"version": "1.0.0",
"clients": 5,
"environments": [
{
"name": "drworks",
"status": "connected",
"poolSize": 10,
"activeConnections": 2
}
],
"timestamp": "2025-12-23T10:30:00.000Z"
}
```
Status values:
- `ok` - All environments connected
- `degraded` - Some environments disconnected
- `error` - Critical failures
## Security Recommendations
1. **Use Strong Tokens**: Generate 64-character random tokens
2. **Enable SSL**: Use `wss://` in production with TLS termination
3. **Restrict Network**: Use firewall rules to limit access
4. **Read-Only Mode**: Use `mode: "readonly"` for read-only access
5. **Audit Logging**: Enable audit logging for compliance
6. **Rotate Tokens**: Periodically rotate authentication tokens
7. **Non-Root User**: Docker image runs as non-root user (UID 1001)
## Graceful Shutdown
The server handles SIGTERM and SIGINT signals:
1. Stops accepting new connections
2. Rolls back active transactions
3. Closes all sessions
4. Closes database connection pools
5. Exits cleanly
```bash
# Graceful stop
docker stop mcp-database-server
# Or send signal directly
kill -TERM $(pgrep -f "node dist/server.js")
```
## Logging
Logs are output in JSON format (pino):
```json
{"level":"info","time":"2025-12-23T10:30:00.000Z","msg":"WebSocket server started","host":"0.0.0.0","port":7700}
```
Log levels: `debug`, `info`, `warn`, `error`, `fatal`
## License
MIT