内容
# MCP-DB
MCP(模型上下文协议)服务器,允许 AI 助手在 MySQL 和 PostgreSQL 上执行数据库查询,具有粒度访问控制和可选的模式上下文知识库。
## 功能
- 支持 **MySQL** 和 **PostgreSQL**
- 粒度访问控制(READ, CREATE, UPDATE, DELETE, DDL)
- **知识库** — 提供模式定义、表关系和业务上下文,以便 AI 了解您的数据库结构
- 通过 STDIO(标准 MCP 传输)通信
- 以 JSON 返回查询结果
- 基于配置的自动查询类型验证
- 默认情况下,DDL 被阻止以确保安全(可配置)
## 安装
### 先决条件
- Go 1.21 或更高版本
- 运行中的 MySQL 或 PostgreSQL 实例
### 安装
```bash
go install github.com/tss182/mcp-db@latest
```
二进制文件将在 `$GOPATH/bin/mcp-db` 处可用。
## 配置
服务器完全通过环境变量配置:
| 变量 | 描述 | 是否必需 |
| --- | --- | --- |
| `DB_DRIVER` | 数据库驱动程序(`mysql` 或 `postgres`) | 是 |
| `DB_DSN` | 数据源名称/连接字符串 | 是 |
| `ACTION_READ` | 允许 SELECT/SHOW/DESCRIBE/EXPLAIN (`true`/`false`) | 否(默认:`false`) |
| `ACTION_CREATE` | 允许 INSERT (`true`/`false`) | 否(默认:`false`) |
| `ACTION_UPDATE` | 允许 UPDATE (`true`/`false`) | 否(默认:`false`) |
| `ACTION_DELETE` | 允许 DELETE (`true`/`false`) | 否(默认:`false`) |
| `ACTION_DDL` | 允许 DDL — CREATE TABLE, ALTER, DROP, TRUNCATE, RENAME (`true`/`false`) | 否(默认:`false`) |
| `KB_PATH` | 知识库目录路径(包含 `.md`/`.txt` 文件) | 否 |
### DSN 格式
**MySQL:**
```
user:password@tcp(host:port)/dbname
```
**PostgreSQL:**
```
host=localhost port=5432 user=myuser password=mypass dbname=mydb sslmode=disable
```
## 使用示例
### MySQL 配置
`mcp.json`:
```json
{
"mcpServers": {
"mysql-db": {
"command": "/path/to/mcp-db",
"env": {
"DB_DRIVER": "mysql",
"DB_DSN": "root:password@tcp(127.0.0.1:3306)/myapp",
"ACTION_READ": "true",
"ACTION_CREATE": "true",
"ACTION_UPDATE": "true",
"ACTION_DELETE": "false"
}
}
}
}
```
### PostgreSQL 配置
`mcp.json`:
```json
{
"mcpServers": {
"postgres-db": {
"command": "/path/to/mcp-db",
"env": {
"DB_DRIVER": "postgres",
"DB_DSN": "host=localhost port=5432 user=postgres password=secret dbname=myapp sslmode=disable",
"ACTION_READ": "true",
"ACTION_CREATE": "true",
"ACTION_UPDATE": "false",
"ACTION_DELETE": "false"
}
}
}
}
```
### 只读访问(适用于生产环境)
```json
{
"mcpServers": {
"prod-db": {
"command": "/path/to/mcp-db",
"env": {
"DB_DRIVER": "postgres",
"DB_DSN": "host=prod-server port=5432 user=readonly password=secret dbname=app sslmode=require",
"ACTION_READ": "true",
"ACTION_CREATE": "false",
"ACTION_UPDATE": "false",
"ACTION_DELETE": "false"
}
}
}
}
```
### 完全访问权限,启用 DDL(适用于开发环境)
```json
{
"mcpServers": {
"dev-db": {
"command": "/path/to/mcp-db",
"env": {
"DB_DRIVER": "mysql",
"DB_DSN": "root:root@tcp(localhost:3306)/dev_db",
"ACTION_READ": "true",
"ACTION_CREATE": "true",
"ACTION_UPDATE": "true",
"ACTION_DELETE": "true",
"ACTION_DDL": "true"
}
}
}
}
```
### 启用知识库
```json
{
"mcpServers": {
"my-db": {
"command": "/path/to/mcp-db",
"env": {
"DB_DRIVER": "mysql",
"DB_DSN": "root:password@tcp(127.0.0.1:3306)/myapp",
"ACTION_READ": "true",
"ACTION_CREATE": "true",
"ACTION_UPDATE": "true",
"ACTION_DELETE": "false",
"KB_PATH": "/path/to/knowledge-base"
}
}
}
}
```
## 可用工具
### `execute_db_query`
对连接的数据库执行 SQL 查询。
**参数:**
| 名称 | 类型 | 是否必需 | 描述 |
| --- | --- | --- | --- |
| `query` | 字符串 | 是 | 要执行的 SQL 查询 |
**示例:**
```sql
SELECT * FROM users WHERE active = 1
```
```sql
INSERT INTO logs (message, created_at) VALUES ('test', NOW())
```
### `get_knowledge`
从知识库中检索信息,以了解数据库结构。
**参数:**
| 名称 | 类型 | 是否必需 | 描述 |
| --- | --- | --- | --- |
| `search` | 字符串 | 否 | 搜索关键词。如果为空,则列出所有可用主题 |
**示例:**
- `get_knowledge({})` — 列出所有主题
- `get_knowledge({"search": "pdr"})` — 搜索与 PDR 相关的信息
- `get_knowledge({"search": "users"})` — 搜索用户表信息
## 查询类别
| 类别 | SQL 命令 | 环境变量 |
| --- | --- | --- |
| READ | SELECT, SHOW, DESCRIBE, EXPLAIN | `ACTION_READ` |
| CREATE | INSERT | `ACTION_CREATE` |
| UPDATE | UPDATE | `ACTION_UPDATE` |
| DELETE | DELETE | `ACTION_DELETE` |
| DDL | CREATE TABLE, ALTER, DROP, TRUNCATE, RENAME | `ACTION_DDL` |
## DDL(数据定义语言)
DDL 查询(如 `CREATE TABLE`、`ALTER TABLE`、`DROP TABLE`、`TRUNCATE TABLE` 和 `RENAME TABLE`)由 `ACTION_DDL` 控制。
- **默认值:`false`(阻止)** — 除非显式启用,否则不允许 DDL。
- 如果需要 DDL,请设置 `ACTION_DDL=true`,例如在开发或数据库迁移期间。
**警告:** 启用 DDL 意味着 AI 可以修改您的数据库结构(创建/删除表、更改列等)。请谨慎使用,仅在开发环境中启用。
## 知识库
知识库允许您向 AI 提供有关数据库模式、表关系和业务逻辑的额外上下文。这使得 AI 在编写查询时更加准确,因为它了解您的数据库特定上下文。
### 设置
1. 为您的知识库文件创建一个目录:
```bash
mkdir kb
```
2. 添加描述您的数据库模式的 `.md` 或 `.txt` 文件:
```
kb/
├── pdr.md
├── users.md
└── inventory.md
```
3. 将 `KB_PATH` 环境变量设置为指向此目录。
### 知识库文件格式
以任何格式(推荐 Markdown)编写您的描述。重要的文档内容是:
- 表结构(列、数据类型)
- 表关系(外键、连接)
- 业务上下文(数据含义)
- 常见查询示例
### 示例文件:`kb/pdr.md`
```markdown
# PDR(采购交付凭证)
## 表
### prdr_list
PDR 记录的主表。
| 列 | 类型 | 描述 |
| --- | --- | --- |
| id | INT(PK) | 唯一 PDR ID |
| form_id | INT(FK) | 引用 `form` 表 |
| pdr_number | VARCHAR | PDR 编号 |
| supplier_id | INT | 供应商 ID |
| 状态 | VARCHAR | 状态:draft, approved, received |
| created_at | DATETIME | 创建日期 |
### form
表单/文档的主表。
| 列 | 类型 | 描述 |
| --- | --- | --- |
| id | INT(PK) | 唯一表单 ID |
| form_name | VARCHAR | 表单名称 |
| form_type | VARCHAR | 表单类型 |
| department | VARCHAR | 所属部门 |
## 关系
- `prdr_list.form_id` → `form.id` (多对一)
- 一个表单可以有多个 PDR
## 示例查询
```sql
-- 获取所有具有表单名称的 PDR
SELECT p.pdr_number, p.status, f.form_name, f.department
FROM prdr_list p
JOIN form f ON p.form_id = f.id
WHERE p.status = 'approved';
```
```
### 工作原理
当 AI 使用 `get_knowledge` 工具时,服务器将:
1. 如果没有 `search` 参数,则列出所有可用的知识库文件
2. 如果有 `search` 参数,则按文件名和内容中的关键词搜索(不区分大小写)
AI 将在编写查询之前自动利用知识库,从而产生更准确的、上下文相关的输出。
## 重要注意事项
- **安全:** 始终使用所需的最低访问权限。对于生产环境,仅启用 `ACTION_READ`。
- **DDL:** 默认情况下被阻止。仅在开发环境中启用。
- **PostgreSQL 和 LastInsertId:** PostgreSQL 不支持 `LastInsertId()`。在 INSERT 查询中使用 `RETURNING id` 获取最后插入的 ID。
- **查询验证:** 服务器根据 SQL 语句的第一个关键字验证查询类型。未识别的查询将被拒绝。
## 更新日志
### v0.1.1
- 添加了知识库支持(`KB_PATH`、`get_knowledge` 工具)
- 添加了可配置的 DDL 访问控制(`ACTION_DDL`)
- 所有消息和文档均为英文
- 服务器添加了版本常量
### v0.1.0
- 初始发布
- MySQL 和 PostgreSQL 支持
- 粒度访问控制(READ, CREATE, UPDATE, DELETE)
- 查询结果的 JSON 输出
- STDIO 传输
## 许可证
MIT 许可证
版权 (c) 2024 Triyana Suryapraja Sukmana
特此授予任何人免费获取和处理本软件和相关文档文件(“软件”)的权限,以便使用、复制、修改、合并、发布、分发、再许可和/或出售软件副本,并允许任何获得软件的人这样做,但须遵守以下条件:
上述版权声明和此许可声明应包含在所有副本或软件的重要部分中。
软件按“原样”提供,不附带任何形式的保证,无论是明示还是暗示,包括但不限于适销性、特定用途适用性和非侵权保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任,无论通过合同、侵权或其他方式产生,均承担任何责任,无论是因使用软件还是因其他原因。