内容
# 定位租户 MCP 服务器
用于跨多个 AWS RDS 区域定位和查询租户数据库的两个 MCP 服务器。每个区域支持两种隧道模式:**Cloudflare WARP** 虚拟网络和 **SSH 跳转服务器** 隧道。
## 服务器
| 服务器 | 文件 | 目的 |
|---|---|---|
| `locate-tenant` | `server.py` | 通过主机名查找租户所在的数据库服务器/模式 |
| `mysql-mcp-server` | `mysql_server.py` | 连接到租户数据库并交互式运行 SQL 查询 |
## 功能
- **租户发现**: 通过部分主机名搜索租户的数据库服务器和模式。
- **多区域支持**: 查询所有已配置的区域,跳过任何失败的区域而不会中止其余区域。
- **Cloudflare WARP**: 自动切换每个区域的 WARP 虚拟网络。如果已经在正确的网络中,则跳过切换。遇到暂时的 IPC 失败时,会进行指数退避重试。
- **SSH 跳转服务器**: 为需要 SSH 跳转服务器的区域(`devbox_required: true`)建立隧道。
- **持久连接**: `mysql_server` 通过会话密钥缓存数据库连接,因此每个会话只需进行一次隧道设置。
- **模式自省**: 列出表格并描述列,以便 LLM 可以编写正确的 SQL。
- **安全查询执行**: 破坏性语句(DELETE、TRUNCATE、UPDATE、DROP 等)在运行前需要明确确认。
## 前提条件
- [uv](https://github.com/astral-sh/uv) 已安装。
- **适用于 VPN 区域**: [Cloudflare WARP](https://one.one.one.one/) 已安装在 `/Applications/Cloudflare WARP.app`,已登录并连接,虚拟网络已按区域配置。
- **适用于 SSH 区域**: SSH 可以访问跳转服务器,拥有私有密钥和 RDS SSL 的 CA 证书。
## 设置
1. **克隆仓库:**
```bash
git clone <仓库网址>
cd locate_tenant
```
2. **安装依赖项:**
```bash
uv sync
```
3. **配置:**
```bash
cp config.yaml.example config.yaml
```
编辑 `config.yaml` 以包含您的数据库凭证和每个区域的 WARP `virtual_network_id`。省略不需要 VPN 切换的区域的 `virtual_network_id`。
## 配置
```yaml
# SSH 隧道区域所需
devbox:
ca_file: "/path/to/global-bundle.pem"
ssh_pkey: "/path/to/.ssh/id_rsa"
jumpbox: "jumpbox.example.com"
username: "your_username"
regions:
# WARP 虚拟网络区域
- name: "au-prod"
remote_bind_address: "rds20.example.ap-southeast-2.rds.amazonaws.com"
remote_bind_port: 3306
username: "db_user"
password: "db_password"
virtual_network_id: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # 如果不需要 VPN 切换,则省略
# SSH 跳转服务器区域
- name: "us-prod"
remote_bind_address: "rds10.example.us-east-1.rds.amazonaws.com"
remote_bind_port: 3306
username: "db_user"
password: "db_password"
devbox_required: true
```
使用以下命令查找 WARP 虚拟网络 ID:
```bash
/Applications/Cloudflare\ WARP.app/Contents/Resources/warp-cli vnet
```
## Claude 桌面集成
将两个服务器添加到 `~/Library/Application Support/Claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"locate-tenant": {
"command": "uv",
"args": [
"--directory", "/path/to/locate_tenant",
"run",
"server.py"
]
},
"mysql-mcp-server": {
"command": "uv",
"args": [
"--directory", "/path/to/locate_tenant",
"run",
"mysql_server.py"
]
}
}
}
```
## 用法
### 定位租户
> "查找 'acme' 的数据库"
Claude 调用 `locate_tenant("acme")` 并返回每个匹配项的 shard 主机、DB 服务器 URL、模式名称和区域。
### 查询租户数据库
> "为 acme 显示我状态为 RUNNING 的计划作业"
Claude 将:
1. 调用 `locate_tenant` 以查找 DB 服务器和模式。
2. 调用 `connect_to_database` — 切换到正确的 VNet 并返回 `session_key`。
3. 调用 `list_tables` 和 `describe_table` 以了解模式。
4. 调用 `execute_query` 以执行适当的 SQL。
对于破坏性查询(DELETE、UPDATE、TRUNCATE、DROP 等),Claude 将在执行前请求您的确认。
### mysql_server 工具
| 工具 | 描述 |
|---|---|
| `connect_to_database` | 打开持久连接;返回 `session_key` |
| `list_tables` | 列出连接模式中的所有表格 |
| `describe_table` | 显示表格的列定义 |
| `execute_query` | 运行 SQL;破坏性语句需要 `confirm=true` |
| `disconnect` | 关闭单个会话 |
| `disconnect_all` | 关闭所有打开的会话 |
## 开发
```bash
uv run python server.py # 通过 stdio 运行 locate-tenant 服务器
uv run python mysql_server.py # 通过 stdio 运行 mysql-mcp-server
uv run mcp dev server.py # 在 MCP 开发检查器中运行
```