内容
<div align="center">
# Thoth 中间件服务器
一款面向 AI 助手的、**只读**的中间件服务器,用于安全地查询 MySQL、PostgreSQL 和 Redis。
[](https://github.com/pennxiv/thoth-mcp/actions/workflows/ci.yml)
[](LICENSE)
[](https://www.python.org/downloads/)
[](https://modelcontextprotocol.io)
**[English](README.md)** · [简体中文](README.zh-CN.md)
</div>
---
每条查询语句都会通过层层安全防护管道,然后才到达您的数据库 - 这样您就可以为 AI 助手提供数据访问能力,而不必担心安全风险。
## 目录
- [为什么使用此服务器](#为什么使用此服务器)
- [功能](#功能)
- [快速入门](#快速入门)
- [配置](#配置)
- [MCP 工具](#mcp-工具)
- [安全](#安全)
- [传输方式](#传输方式)
- [架构](#架构)
- [开发](#开发)
- [许可证](#许可证)
## 为什么使用此服务器?
- **设计为只读**。写入操作在结构上是不可能的 - 没有可以修改数据的 `execute` 路径。
- **深度防御**。SQL 查询经过三种方式验证(SELECT 强制 → 注入检测 → 自动 LIMIT)。Redis 命令仅限于明确的允许列表。
- **配置文件中不存储敏感信息**。密码从环境变量中加载,并从日志和错误消息中删除。
- **一个服务器,多个数据源**。通过单个 MCP 端点连接到所有数据库。
- **与任何 MCP 客户端兼容** - Claude Code、Cursor、Windsurf 以及其他任何支持 MCP 的客户端。
## 功能
- 通过一个服务器查询多个 MySQL、PostgreSQL 和 Redis 实例
- 三层 SQL 安全防护(SELECT 强制 + 注入检测 + 自动 LIMIT)
- Redis 命令允许列表(仅限明确的安全只读命令)
- Markdown 输出,适用于高效的 AI 上下文使用
- 支持 stdio、SSE 和 streamable-http 传输方式
- 适用于本地开发的 Docker Compose 栈,包含种子数据
## 快速入门
### 要求
- Python 3.10+
- Docker 和 Docker Compose(可选,用于容器化部署)
### 本地安装和运行
```bash
# 克隆仓库
git clone https://github.com/pennxiv/thoth-mcp.git
cd thoth-mcp
# 设置虚拟环境
python -m venv .venv
source .venv/bin/activate # 或 .venv\Scripts\activate on Windows
# 安装
pip install -e ".[dev]"
# 指向数据源并运行
export THOTH_DATASOURCES_FILE=config/datasources.yaml
python -m thoth_mcp
```
### 使用 Docker 运行
```bash
# 以 streamable-http 模式启动服务器,监听端口 8080
docker compose up -d --build
# 从网络上的任何机器连接:
# http://<服务器 IP>:8080/mcp
```
### 连接你的 MCP 客户端
**Claude Code** (`~/.claude.json` 或项目 `.mcp.json`):
```json
{
"mcpServers": {
"thoth": {
"url": "http://<服务器 IP>:8080/mcp",
"transport": "streamable-http"
}
}
}
```
**Cursor / Windsurf** (`.cursor/mcp.json`):
```json
{
"mcpServers": {
"thoth": {
"url": "http://<服务器 IP>:8080/mcp",
"transport": "streamable-http"
}
}
}
```
对于仅限本地使用的情况,请配置客户端以通过 stdio 启动服务器 - 无需暴露 HTTP。
## 配置
创建 `datasources.yaml` 文件(或设置 `THOTH_DATASOURCES_FILE` 指向一个文件):
```yaml
mysql:
prod_db:
host: mysql.example.com
port: 3306
user: readonly_user
password: ${MYSQL_PROD_PASSWORD} # 通过环境变量覆盖
database: production
min_pool_size: 1
max_pool_size: 10
redis:
cache:
host: redis.example.com
port: 6379
db: 0
min_pool_size: 1
max_pool_size: 10
```
### 提供敏感信息
密码不应存储在配置文件中。通过环境变量覆盖它们,遵循 `THOTH_<TYPE>__<NAME>__PASSWORD` 模式:
```bash
export THOTH_MYSQL__PROD_DB__PASSWORD=secret123
export THOTH_POSTGRES__WAREHOUSE__PASSWORD=another_secret
export THOTH_REDIS__CACHE__PASSWORD=redis_secret
```
参见 `config/datasources.yaml` 以获取包含所有三种数据源类型的完整示例。
## MCP 工具
| 工具 | 描述 |
|------|-------------|
| `query_mysql(datasource, sql)` | 对 MySQL 数据源执行 SELECT 查询 |
| `list_tables(datasource)` | 列出 MySQL 数据源中的所有表 |
| `describe_table(datasource, table)` | 显示 MySQL 表的列详情 |
| `query_postgres(datasource, sql)` | 对 PostgreSQL 数据源执行 SELECT 查询 |
| `list_tables_postgres(datasource)` | 列出 PostgreSQL 数据源中的所有表(公共模式) |
| `describe_table_postgres(datasource, table)` | 显示 PostgreSQL 表的列详情 |
| `query_redis(datasource, command, args?)` | 执行安全的只读 Redis 命令 |
| `list_datasources()` | 列出所有配置的 MySQL、PostgreSQL 和 Redis 数据源 |
## 安全
该服务器围绕以下假设构建:到达数据库的任何内容都必须是只读且无注入的。
### SQL 安全防护(三层防御)
1. **仅限 SELECT** - 仅允许 SELECT 语句。
2. **注入模式检测** - 阻止 UNION 注入、注释混淆和多语句攻击。
3. **自动 LIMIT 注入** - 没有 LIMIT 子句的查询会接收默认限制(100 行)以防止无边界扫描。
### Redis 安全
仅允许以下只读命令:`GET`、`HGET`、`HGETALL`、`LRANGE`、`SMEMBERS`、`TTL`、`TYPE`、`LLEN`、`SCARD`、`EXISTS`、`HEXISTS`、`SRANDMEMBER`、`ZCARD`、`ZSCORE`、`ZRANGE`。
像 `SET`、`DEL`、`KEYS` 和 `FLUSHALL` 这样的命令被明确阻止。
### 错误净化
错误消息永远不会暴露主机名、IP地址、连接字符串或凭证。即使在连接设置或查询执行失败时也是如此。
### 网络暴露
当以 `streamable-http` 或 `sse` 模式运行时,服务器默认监听 `0.0.0.0:8080`。将其放置在经过身份验证的网络边界后面 - 不要在没有额外身份验证的情况下直接将其暴露给公共互联网。参见 [SECURITY.md](SECURITY.md)。
## 传输方式
| 模式 | 用例 | 环境变量 |
|------|----------|-----|
| `stdio`(默认) | 客户端和服务器在同一台机器上 | `MCP_TRANSPORT=stdio` |
| `streamable-http` | 通过 HTTP 的远程客户端 | `MCP_TRANSPORT=streamable-http` |
| `sse` | 基于浏览器的 / 单向流媒体 | `MCP_TRANSPORT=sse` |
| 变量 | 默认值 | 描述 |
|----------|---------|-------------|
| `MCP_TRANSPORT` | `stdio` | 传输模式 |
| `MCP_HOST` | `0.0.0.0` | 监听主机(http/sse 仅限) |
| `MCP_PORT` | `8080` | 监听端口(http/sse 仅限) |
SSE 模式暴露 `/sse`(客户端连接)和 `/messages/`(POST 端点)。
## 架构
```
┌──────────────────────────────────────────────────────────────┐
│ FastMCP 服务器 │
│ ┌─────────────┐ ┌──────────────┐ ┌─────────────┐ │
│ │ MySQL 工具 │ │PostgreSQL │ │ Redis 工具 │ │
│ │ │ │工具 │ │ │ │
│ └──────┬──────┘ └──────┬───────┘ └──────┬──────┘ │
│ │ │ │ │
│ ┌──────▼──────┐ ┌──────▼───────┐ ┌──────▼──────┐ │
│ │ MySQL 连接池 │ │PostgreSQL │ │ Redis 连接池 │ │
│ │ 管理器 │ │连接池管理器 │ │ 管理器 │ │
│ └──────┬──────┘ └──────┬───────┘ └──────┬──────┘ │
│ │ │ │ ┌──────────┐ │
│ ┌──────▼──────┐ ┌──────▼───────┐ ┌──────▼──────┐ │
│ │ SQL 安全防护 │ │ SQL 安全防护 │ │Redis 安全防护 │ │
│ └──────┬──────┘ └──────┬───────┘ └──────┬──────┘ │
│ └───────────────┴────────────────┴───│ 配置 │ │
│ └──────────┘ │
└──────────────────────────────────────────────────────────────┘
│ │ │
┌────▼────┐ ┌────▼─────┐ ┌────▼────┐
│ MySQL │ │PostgreSQL│ │ Redis │
│ 数据库 │ │ 数据库 │ │ 实例 │
└─────────┘ └──────────┘ └─────────┘
```
## 开发
```bash
# 运行测试套件
pytest tests/ -v
# 运行单个测试文件
pytest tests/test_mysql_tools.py -v
# 运行覆盖率
pytest tests/ --cov=src/thoth_mcp --cov-report=html
# 代码检查
ruff check src/ tests/
```
参见 [CONTRIBUTING.md](CONTRIBUTING.md) 获取贡献指南,[CHANGELOG.md](CHANGELOG.md) 获取版本历史。
### 项目结构
```
thoth-mcp/
├── src/thoth_mcp/
│ ├── config.py # 配置加载
│ ├── server.py # FastMCP 服务器组装
│ ├── __main__.py # 入口点
│ ├── db/ # 连接池管理器(mysql、postgresql、redis)
│ ├── tools/ # MCP 工具(mysql、postgresql、redis、发现)
│ └── utils/ # 安全层、格式化程序、日志记录
├── tests/ # 测试套件
├── docker/ # Docker 种子数据
├── config/ # 示例配置
└── pyproject.toml
```
## 许可证
MIT 许可证 - 参见 [LICENSE](LICENSE)。