内容
# 材料与合金数据库
一个关于冶金技术规格数据库(合金、牌号、化学元素、标准、机械性能)的个人项目。该项目探索了关系模型(MySQL)及其通过三个不同访问点的暴露。项目为本地探索性和技术演示。
该项目由三个互补的仓库组成:
- **mysql-materials-server** — 后端 Node.js / MySQL。管理数据库并暴露 REST API(CRUD)。
- **mysql-materials-front** — 前端 React / React Admin。CRUD 技术规格管理界面。
- **mysql-materials-mcp** — MCP 服务器(Node.js)。通过 LLM 访问数据库。
## mysql-materials-mcp
MCP(模型上下文协议)服务器,将项目的 MySQL 数据库暴露给 LLM(Claude Desktop)。Claude 可以用自然语言查询数据库:列出合金类型、按类型筛选牌号、获取牌号的完整详细信息及其所有关系。
服务器通过 **stdio** 与 Claude Desktop 通信(无 HTTP API,无网络端口)。目前仅支持读取。
## 技术栈
- **Node.js** (ESM, `"type": "module"`)
- **@modelcontextprotocol/sdk** — 官方 MCP SDK
- **mysql2** — 访问 MySQL 数据库(连接池)
- **zod** — 工具参数验证
## 前提条件
- **Node.js** (推荐最新版本)
- **Claude Desktop** 已安装
- **MySQL** 数据库 `materials_db` 必须存在且可访问。它由 `mysql-materials-server` 仓库创建和填充(参见其 README);此 MCP 服务器仅读取。
## 安装
```bash
npm install
```
## 配置
与典型的 Node 项目不同,MCP 服务器由 Claude Desktop 作为子进程启动,从一个不是项目目录的工作目录启动。因此,本地 `.env` 文件不可靠。环境变量直接由 Claude Desktop 通过其配置块 `env` 注入。
提供了一个模板:`claude_desktop_config.example.json`。
必须将内容复制到 Claude Desktop 的配置文件中,位于:
- **Windows** : `%APPDATA%\Claude\claude_desktop_config.json`
- **macOS** : `~/Library/Application Support/Claude/claude_desktop_config.json`
配置示例,需调整:
```json
{
"mcpServers": {
"mysql-materials-mcp": {
"command": "node",
"args": ["ABSOLUTE_PATH/mysql-materials-mcp/server.js"],
"env": {
"DB_HOST": "localhost",
"DB_PORT": "...",
"DB_USER": "USER_READ_ONLY",
"DB_PASSWORD": "...",
"DB_NAME": "materials_db"
}
}
}
}
```
重要点:
- **`args`** : `server.js` 的绝对路径。在 Windows 上,双反斜杠 (`C:\\...`)。
- 任何修改后,**完全重启 Claude Desktop** (实际退出,而不仅仅关闭窗口),使其重新启动服务器并应用新变量。
- `claude_desktop_config.json` 文件中包含 **明文凭证** ;它位于仓库之外,永远不应提交。只有模型 `claude_desktop_config.example.json` (虚构值)被版本控制。
### 只读 MySQL 用户(推荐)
由于服务器只读,推荐为其分配一个仅具有 `SELECT` 权限的 MySQL 用户。
## 启动
服务器由 Claude Desktop 在启动时自动启动(通过上述配置)。一旦 Claude Desktop 重新启动,三个工具就会出现并可在对话中使用。
在 Claude Desktop 之外进行手动测试:
```bash
npm start
# 或在开发模式下自动重新加载:
npm run dev
```
## 项目结构
```
.
├── server.js # MCP 入口点:服务器创建、工具注册、stdio 传输
├── db/
│ └── configDb.js # MySQL 连接池(只读)
├── tools/ # 暴露给 Claude 的每个工具的文件
│ ├── getAlloyTypes.tool.js # 合金类型列表
│ ├── getAlloyNuances.tool.js # 按合金类型筛选的牌号
│ └── getAlloyNuanceById.tool.js # 牌号的完整详细信息
└── claude_desktop_config.example.json # Claude Desktop 配置模板
```
## 暴露的工具
服务器暴露三个工具,适用于渐进式导航:首先是类型,然后是类型的牌号,最后是牌号的详细信息。
| 工具 | 参数 | 角色 |
| ------------------------ | ------------------------ | -------------------------------------------------------------------------------------------------------- |
| `get_alloy_types` | 无 | 列出所有合金类型(id、名称、描述)。 |
| `get_alloy_nuances` | `id_alloy_type` (数字) | 列出给定类型的牌号(id、名称、描述)。 |
| `get_alloy_nuance_by_id` | `id` (数字) | 牌号的完整详细信息:类型、测量、化学成分、冶金状态、用途、标准。 |
详细信息工具执行 **JOIN** 以返回可读名称(例如“Carbon”)而不是原始 ID,以便 LLM 直接利用数据。
参数由 **Zod** 验证:Claude 必须提供正确类型(ID 为数字),否则调用将被拒绝,请求甚至不会到达数据库。
## 技术选择
- **ESM** :MCP SDK 以 ESM 分发,因此整个项目使用 `import`/`export` (`package.json` 中的 `"type": "module"` )。
- **`console.error` 而非 `console.log`** :在 stdio 传输中,标准输出 (`stdout`) 保留用于 MCP 协议。所有日志消息必须通过 `stderr`,否则会破坏与 Claude Desktop 的通信。
- **低限制连接池** (`connectionLimit: 3`) :连接到 Claude Desktop 的 MCP 服务单个用户,而非 Web 流量。
- **`multipleStatements: false`** :每个调用仅有一条查询,更安全地防范暴露给 LLM 的服务器。
- **预备语句** (`?` + 参数) :防范 SQL 注入。
## 安全
- **只读** :服务器仅暴露 `SELECT` 操作。推荐使用专属 MySQL 用户,仅具有 `SELECT` 权限,以在数据库级别保证此限制。
- **凭证在仓库外** :它们位于 Claude Desktop 的本地配置中,从不存储在代码或版本控制文件内。
- **MCP 服务器作为子进程运行,用户权限与父进程相同** :仅暴露必要功能。
## 已知限制 / 改进方向
- 目前仅支持读取;通过 MCP 进行写入是正在探索的改进方向。
- 三个查询工具;可以添加其他工具(按名称搜索、交叉过滤等)。
- 目前为本地项目,未部署。