# 数据库 MCP

生成 MySQL5 / Oracle 数据库 MCP 条目。执行本文件全部步骤后再回到 [SKILL.md](SKILL.md) 做合并写入。

## 1. 定位 Nacos 配置项

在项目的 `bootstrap.yml` / `bootstrap.yaml` / `application*.yml` / `*.properties` 中查找：

```properties
spring.cloud.nacos.config.ext-config[*].data-id=...database...
spring.cloud.nacos.config.ext-config[*].group=...
```

关注 data-id 含 `database` / `datasource` / `mysql` / `oracle` / `db` 的项。记录每个 `data-id`、`group`。

若无 ext-config，再搜 `spring.datasource` 相关 shared-dataids / extension-configs。

项目中常见定位方式：

```properties
spring.cloud.nacos.config.ext-config[2].data-id=zqyl-ls-oracle-database.properties
spring.cloud.nacos.config.ext-config[2].group=PUBLIC_GLOBAL_DB_GROUP
spring.cloud.nacos.config.ext-config[2].refresh=true
```

## 2. 拉取配置

以 `test1` 为例；其它环境将 URL/参数中的 `test1` 换成 `test2` / `test3` / `test4` / `test5` / `uat`。

```
GET http://www.{env}.yljr.com/nacos/v1/cs/configs?show=all&dataId={dataId}&group={group}&tenant={env}&namespaceId={env}
```

**建议用 `curl.exe` 拉取**（PowerShell 里 `curl` 常是 `Invoke-WebRequest` 别名，可能报错；不建议 WebFetch——会把 http 升级为 https 导致拿不到数据；均不可行时自行选择合适方式）：

```bash
curl.exe -s "http://www.test1.yljr.com/nacos/v1/cs/configs?show=all&dataId={dataId}&group={group}&tenant=test1&namespaceId=test1"
```

响应关键字段：`content`（properties 正文）、`dataId`、`group`、`tenant`。

示例 `content` 片段：

```properties
spring.datasource.druid.username=ZQYL_LS_TEST1
spring.datasource.druid.password=test123456
```

账号密码可能只在该文件；jdbc url 可能在其它 dataId，需继续拉取。

## 3. 解析连接信息

从 `content`（及同服务其它含 jdbc url 的 dataId）解析：

| 目标字段 | 常见 key |
|----------|----------|
| user | `spring.datasource.druid.username` / `spring.datasource.username` |
| password | `spring.datasource.druid.password` / `spring.datasource.password` |
| url | `spring.datasource.druid.url` / `spring.datasource.url` |

**同一文件无 url 时**：继续拉取同 group 下其它数据库相关 dataId，或项目内其它 nacos 配置，直到拿到 jdbc url。

判定类型：dataId/url 含 `oracle` → Oracle；含 `mysql` → MySQL。

### JDBC 解析提示

**MySQL：** `jdbc:mysql://host:port/db?...` → 先解析，再按下方 MySQL5 规则覆盖 host/port/密码/库名后缀。Nacos 中端口可能仍是 `33061`；MCP 写 **`33062`**。

**Oracle：** Nacos 可能仍含旧 jdbc url；生成 MCP 时 **不要直接用旧 IP/ORCL**。按下方覆盖规则写 `ORACLE_HOST` / `ORACLE_PORT` / `ORACLE_SERVICE`。若需从 jdbc 解析（仅 yc/dev 缺省 Service Name 时）：

- `jdbc:oracle:thin:@//host:port/service` → `host:port/service`
- `jdbc:oracle:thin:@host:port:sid` → `host:port:sid`
- `jdbc:oracle:thin:@host:port/service` → `host:port/service`

## 4. MySQL5 覆盖与默认（必遵）

### test1 ~ test5 客户端直连

| 项 | 值 |
|----|-----|
| 地址 | `10.111.20.100` |
| 文档端口（原） | `33061` |
| **MCP 使用端口** | `33062`（2025/09/01：客户端直连 = 原端口 +1） |
| 只读备选端口 | `6034`（mysql5 只读；默认仍写 `33062`） |
| 密码 | `test123456`（统一，覆盖 Nacos） |
| 用户名 / 库名 | 同名；基名以 `_test` 结尾时加环境数字，如 test1 → `xxx_test1` |

域名一律映射到 `10.111.20.100`：

- `api-mysql.yljr.native`
- `account-mysql.yljr.native`
- `pay-mysql.yljr.native`
- `company-mysql.yljr.native`
- `route-mysql.yljr.native`
- `public-mysql.yljr.native`
- `bank-mysql.yljr.native`

**生成步骤：**

1. 从 Nacos/jdbc 得到库名或用户名，归一化去掉末尾环境数字（`xxx_test1`→`xxx_test`）后对照下方库表
2. `MYSQL_HOST=10.111.20.100`，`MYSQL_PORT=33062`，`MYSQL_PASS=test123456`
3. `MYSQL_USER` / `MYSQL_DB` = 基名 + 环境数字（如 `center_user_test` + test2 → `center_user_test2`）；若 Nacos 已是带正确数字的形式则沿用
4. 未命中库表时：仍应用 host/port/密码默认，库名按 Nacos，并提示用户核对

### yc

| 项 | 值 |
|----|-----|
| IP | `172.16.44.90` |
| 端口 | `6033` |
| 用户 | `user_yc` |
| 密码 | `mysql20230818` |

### 域名 → 库名（基名，生成时加环境数字）

**public-mysql.yljr.native:33061**

`zqyl_aiops_file_test`、`zqyl_aiops_test`、`zqyl_aiops_user_test`、`zqyl_bigdata_management_test`、`zqyl_devops_artifact_test`、`zqyl_devops_base_test`、`zqyl_devops_compose_test`、`zqyl_devops_deliver_test`、`zqyl_devops_file_test`、`zqyl_devops_project_test`、`zqyl_itplat_test`、`zqyl_structure_test`、`zqyl_userprofile_test`、`zqylbank_test`、`server_push_test`

**account-mysql.yljr.native:33061**

`center_account_test`、`center_file_test`、`center_message_test`、`center_im_test`、`center_ocsp_test`、`zqyl_ai_xiaoxin_test`

**pay-mysql.yljr.native:33061**

`cloud_aggregationpay_test`、`cloud_factor_test`、`cloud_order_test`、`cloud_pay_channel_test`、`cloud_pay_members_test`、`cloud_pay_provider_test`、`clouddisk_test`、`cloudshop_test`、`contract_open_platform_test`、`draft_open_gateway_test`、`saas_user_test`、`yb_test`、`zqyl-zex_test`、`zqyl_aichat_test`、`zqyl_aigc_test`、`zqyl_channel_bocom_test`、`zqyl_channel_wx_test`、`zqyl_event_test`、`zqyl_enterprise_inquiry_test`、`zqyl_bank_pjs_xd_test`、`zqyl_cloud_finance_test`、`zqyl_dmss_test`、`zqyl_group_control_test`、`zqyl_icbc_ebuspay_test`、`zqylcnaps_test`

**api-mysql.yljr.native:33061**

`center_agreement_test`、`center_user_test`、`center_workflow_test`

**route-mysql.yljr.native:33061**

`zqyl_route_file_test`、`zqyl-route_test`、`route_mps_test`、`route-inner_test`、`zqyl_cda_test`、`draft_test`、`quick_test`、`doris_test`

**company-mysql.yljr.native:33061**

`zqyl-invoice_test`、`center_nlp_test`、`zqyl_ocr_test`、`zqyl_qcc_test`、`center_bcp_test`、`zqyl-company-route_test`、`zqyl-feedback_test`、`zqyl_clearing_channel_test`、`zqyl_clearing_config_test`、`zqyl-cms_test`、`zqyl-im-block_test`、`center_cloud_file_test`、`center_error_test`

## 5. Oracle 覆盖与默认（必遵）

Nacos 只取 **username**（`ORACLE_USER` 保持 Nacos 原值）。host / port / password / Service Name **优先按下表默认与覆盖规则**生成，不要沿用 Nacos 里的旧 `10.111.20.29` / `ORCL`。

2025/09/01 起：客户端连 Oracle **仅只读**；测试环境 IP `10.111.20.29` → `10.111.20.30`，Service Name `ORCL` → `testdg1`（用户名/密码/端口不变）。

| 环境 | IP | 端口 | Service Name |
|------|-----|------|----------------|
| test1 ~ test5 | `10.111.20.30` | `1521` | `testdg1` |
| yc | `172.16.44.59` | `1521` | 以 Nacos url 为准，缺省 `ORCL` |
| dev | `10.111.20.19` | `1521` | 以 Nacos url 为准，缺省 `ORCL` |

写入 MCP 时拆成独立字段（**不要**再用 `ORACLE_CONNECTION_STRING` + `npx`）：

| env | test1~test5 例 |
|-----|----------------|
| `ORACLE_HOST` | `10.111.20.30` |
| `ORACLE_PORT` | `1521` |
| `ORACLE_SERVICE` | `testdg1` |
| `ORACLE_USER` | Nacos 原值 |
| `ORACLE_PASSWORD` | 查表或 Nacos |

运行时拆分：Instant Client → `C:\tools\oracle-mcp`；npm 包 → `npm root -g`。详见 [oracle-setup.md](oracle-setup.md)。

**密码查找：**

1. **若环境为 test5**：`ORACLE_PASSWORD` **一律** `test123456`（无论是否命中下方用户组、无论 Nacos 原密码是什么；可跳过查表）
2. 其它环境：将 Nacos username 归一化：`XXX_TEST1`~`XXX_TEST5` → `XXX_TEST`（去掉环境序号）后查表
3. 命中则用表中对应该环境的密码，**覆盖** Nacos password
4. 未命中则回退 Nacos password，并提示用户核对

### Oracle 各环境用户组

查表时：Nacos 用户名若带环境序号（如 `ZQYL_LS_TEST1`），先归一为 `ZQYL_LS_TEST` 再匹配。

**组 A（通用业务库）**

| 环境 | 连接 IP | 端口 | 密码 |
|------|---------|------|------|
| test1 | 10.111.20.30 | 1521 | oracle20230426 |
| test2 | 10.111.20.30 | 1521 | oracle20230506 |
| test3 | 10.111.20.30 | 1521 | oracle20230506 |
| test4 | 10.111.20.30 | 1521 | oracle20230426 |
| test5 | 10.111.20.30 | 1521 | test123456 |
| yc | 172.16.44.59 | 1521 | oracle20230818 |
| dev | 10.111.20.19 | 1521 | oracle20230506 |

用户名：`CRCL_CORE_TEST`、`CRCL_OPEN_TEST`、`CRCL_PAY_TEST`、`CRCL_RC_TEST`、`DORIS_TEST`、`INCENTIVE_TEST`、`LETTER_CREDIT_TEST`、`OPENFIRE_TEST`、`YZDWH_TEST`、`ZQYL_CREDIT_TEST`、`ZQYL_IOT_TEST`、`ZQYL_TEST`、`ZQYL_YS_TEST`、`ZQYL_YUNDAN_TEST`、`ZQYT_TEST`、`ZQYZ_TEST`

**组 B（融资/贷款相关）**

| 环境 | 连接 IP | 端口 | 密码 |
|------|---------|------|------|
| test1 ~ test4 | 10.111.20.30 | 1521 | oracle20230509 |
| test5 | 10.111.20.30 | 1521 | test123456 |
| yc | 172.16.44.59 | 1521 | oracle20230818 |

用户名：`ZQYL_AUDIT_BASE_TEST`、`ZQYL_CRCL_FINANCE_TEST`、`ZQYL_FINANCE_BASE_TEST`、`ZQYL_INQUIRY_TEST`、`ZQYL_INVESTMENT_PLAN_TEST`、`ZQYL_LOAN_BASE_TEST`、`CHECKING_FORM_TEST`

**组 C**

| 环境 | 连接 IP | 端口 | 用户名 | 密码 |
|------|---------|------|--------|------|
| test1 ~ test4 | 10.111.20.30 | 1521 | ZQYL_LOAN_APPLICATION_TEST | oracle20230908 |
| test5 | 10.111.20.30 | 1521 | ZQYL_LOAN_APPLICATION_TEST | test123456 |
| yc | 172.16.44.59 | 1521 | ZQYL_LOAN_APPLICATION_TEST | oracle20230922 |

**组 D**

| 环境 | 连接 IP | 端口 | 用户名 | 密码 |
|------|---------|------|--------|------|
| test1 ~ test4 | 10.111.20.30 | 1521 | ZQYL_POST_LOAN_TEST | oracle20240508 |
| test5 | 10.111.20.30 | 1521 | ZQYL_POST_LOAN_TEST | test123456 |
| yc | 172.16.44.59 | 1521 | ZQYL_POST_LOAN_TEST | oracle20230818 |

**组 E（LS）**

| 环境 | 连接 IP | 端口 | 用户名 | 密码 |
|------|---------|------|--------|------|
| test1 ~ test5 | 10.111.20.30 | 1521 | ZQYL_LS_TEST | test123456 |
| yc | 172.16.44.59 | 1521 | ZQYL_LS_TEST | yc123456 |

test 环境统一：`ORACLE_HOST=10.111.20.30`，`ORACLE_PORT=1521`，`ORACLE_SERVICE=testdg1`。  
**test5**：任意 Oracle 用户（含未列入前述 A～E 组）`ORACLE_PASSWORD=test123456`。

## 6. 生成条目

多服务时 key 带服务名后缀，避免覆盖。写操作开关一律 `false`（Oracle 客户端也仅只读）。密码可写入 mcp.json，但勿在聊天中主动复述完整密码，除非用户要求核对。

**MySQL**（key 建议 `mcp_server_mysql` 或 `mcp_server_mysql-{db或service}`）：

```json
"mcp_server_mysql": {
  "type": "stdio",
  "command": "npx",
  "args": ["-y", "@benborla29/mcp-server-mysql"],
  "env": {
    "MYSQL_HOST": "10.111.20.100",
    "MYSQL_PORT": "33062",
    "MYSQL_USER": "center_user_test1",
    "MYSQL_PASS": "test123456",
    "MYSQL_DB": "center_user_test1",
    "ALLOW_INSERT_OPERATION": "false",
    "ALLOW_UPDATE_OPERATION": "false",
    "ALLOW_DELETE_OPERATION": "false"
  }
}
```

**Oracle（必遵 wrapper，禁止裸 npx）**

生成前按 [oracle-setup.md](oracle-setup.md) 探测并确认：

| 项 | 命令 / 路径 |
|----|-------------|
| `<NODE_EXE>` | `where node` |
| `<NPM_ROOT>` | `npm root -g` |
| Instant Client | `C:\tools\oracle-mcp\...\instantclient_11_2\oci.dll` |
| npm 包 | `<NPM_ROOT>\oracledb`、`<NPM_ROOT>\oracle-mcp-server\build\index.js` |

步骤：

1. 复制本 skill 的 [oracle-mcp-wrapper.mjs](scripts/oracle-mcp-wrapper.mjs) → `<PROJECT_ROOT>\.claude\oracle-mcp-wrapper.mjs`（无目录则创建）
2. mcp key 建议：`{ORACLE_USER}_oracle`（如 `ZQYL_LS_TEST2_oracle`）；已有同名则覆盖
3. **禁止**写入：`npx`、`@vdeserto/oracle-mcp-server`、`ORACLE_CONNECTION_STRING`、`ORACLE_MCP_HOME`
4. **禁止**在 `C:\tools\oracle-mcp` 下 `npm install`

```json
"ZQYL_LS_TEST2_oracle": {
  "type": "stdio",
  "command": "<NODE_EXE>",
  "args": [
    "<PROJECT_ROOT>\\.claude\\oracle-mcp-wrapper.mjs"
  ],
  "env": {
    "ORACLE_NPM_ROOT": "<NPM_ROOT>",
    "ORACLE_IC_HOME": "C:\\tools\\oracle-mcp",
    "ORACLE_USER": "<nacos-username>",
    "ORACLE_PASSWORD": "<table-or-nacos-password>",
    "ORACLE_HOST": "10.111.20.30",
    "ORACLE_PORT": "1521",
    "ORACLE_SERVICE": "testdg1"
  }
}
```

JSON 中路径反斜杠写成 `\\`。`<PROJECT_ROOT>` 可含中文；`<NODE_EXE>` / `<NPM_ROOT>` 应为纯 ASCII 路径。

缺 `oci.dll`：Agent 按 [oracle-setup.md](oracle-setup.md) 自动从共享拉取并解压到 `C:\tools\oracle-mcp`（勿进项目目录；已安装则跳过）。
缺 npm 包：`npm install -g oracledb@^5.5.0 oracle-mcp-server@^0.1.3 --registry http://172.16.30.100:8081/repository/npm-group/`（装到本机 npm，**不是** `C:\tools\oracle-mcp`；已安装则跳过）。
仍可先写 mcp.json，但须明确告知用户缺什么、怎么补。
