@harneon-ai/db 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +338 -338
- package/config/datasource.example.yaml +68 -62
- package/dist/config/config-manager.d.ts +110 -0
- package/dist/config/config-manager.js +275 -0
- package/dist/config/parser.d.ts +35 -21
- package/dist/config/parser.js +84 -36
- package/dist/config/types.d.ts +349 -1
- package/dist/config/types.js +19 -1
- package/dist/config/writer.d.ts +35 -1
- package/dist/config/writer.js +83 -0
- package/dist/db/connection-manager.d.ts +52 -18
- package/dist/db/connection-manager.js +93 -35
- package/dist/db/driver-registry.d.ts +51 -0
- package/dist/db/driver-registry.js +89 -0
- package/dist/db/driver.d.ts +63 -0
- package/dist/db/driver.js +15 -0
- package/dist/db/drivers/mysql.d.ts +89 -0
- package/dist/db/drivers/mysql.js +268 -0
- package/dist/db/drivers/postgresql.d.ts +95 -0
- package/dist/db/drivers/postgresql.js +252 -0
- package/dist/db/metadata-queries.js +53 -53
- package/dist/db/types.d.ts +95 -0
- package/dist/db/types.js +14 -0
- package/dist/index.d.ts +9 -8
- package/dist/index.js +33 -28
- package/dist/tools/delete-datasource-config.d.ts +12 -0
- package/dist/tools/delete-datasource-config.js +75 -0
- package/dist/tools/describe-indexes.d.ts +1 -1
- package/dist/tools/describe-indexes.js +7 -5
- package/dist/tools/describe-table.d.ts +1 -0
- package/dist/tools/describe-table.js +9 -6
- package/dist/tools/list-datasources.d.ts +3 -2
- package/dist/tools/list-datasources.js +19 -8
- package/dist/tools/list-tables.d.ts +1 -1
- package/dist/tools/list-tables.js +7 -5
- package/dist/tools/query-metadata.d.ts +2 -7
- package/dist/tools/query-metadata.js +18 -51
- package/dist/tools/save-datasource-config.d.ts +5 -4
- package/dist/tools/save-datasource-config.js +25 -28
- package/dist/tools/test-connection.d.ts +4 -2
- package/dist/tools/test-connection.js +47 -40
- package/dist/tools/update-datasource-config.d.ts +14 -0
- package/dist/tools/update-datasource-config.js +243 -0
- package/package.json +58 -42
package/README.md
CHANGED
|
@@ -1,338 +1,338 @@
|
|
|
1
|
-
# Harneon DB MCP Server
|
|
2
|
-
|
|
3
|
-
一个 MCP (Model Context Protocol) Server,为 AI 助手提供只读的 PostgreSQL 数据库元数据查询能力,支持 ShardingSphere 风格的多数据源分片拓扑解析。
|
|
4
|
-
|
|
5
|
-
## 功能概览
|
|
6
|
-
|
|
7
|
-
- 查看多数据源配置信息
|
|
8
|
-
- 查询任意数据源的表列表、表结构、索引信息
|
|
9
|
-
- 解析 ShardingSphere 分片拓扑(逻辑表 → 实际数据节点映射)
|
|
10
|
-
- 执行自定义元数据查询(仅允许 information_schema / pg_catalog)
|
|
11
|
-
- 多层安全防护,严禁任何数据写入和业务数据读取
|
|
12
|
-
|
|
13
|
-
## 快速开始
|
|
14
|
-
|
|
15
|
-
### 1. 全局安装
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
npm install -g @harneon-ai/db
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
### 2. 在 Claude Desktop 中使用
|
|
22
|
-
|
|
23
|
-
编辑 Claude Desktop 配置文件(`claude_desktop_config.json`):
|
|
24
|
-
|
|
25
|
-
```json
|
|
26
|
-
{
|
|
27
|
-
"mcpServers": {
|
|
28
|
-
"harneon-db": {
|
|
29
|
-
"command": "harneon-db"
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
### 3. 在 Claude Code 中使用
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
claude mcp add harneon-db -- harneon-db
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
### 4. 配置数据源
|
|
42
|
-
|
|
43
|
-
配置文件默认保存在 `~/.harneon-ai/db/datasource.yaml`。
|
|
44
|
-
|
|
45
|
-
你可以手动创建该文件,也可以启动后通过 `save_datasource_config` 工具添加数据源(目录会自动创建)。
|
|
46
|
-
|
|
47
|
-
如需使用自定义配置路径:
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
harneon-db /path/to/datasource.yaml
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
或通过环境变量:
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
DB_CONFIG_PATH=/path/to/datasource.yaml harneon-db
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### 5. 开发模式运行
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
npm run dev
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
## 配置文件格式
|
|
66
|
-
|
|
67
|
-
配置文件采用 YAML 格式,兼容 ShardingSphere 配置:
|
|
68
|
-
|
|
69
|
-
```yaml
|
|
70
|
-
dataSources:
|
|
71
|
-
ds_0:
|
|
72
|
-
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
|
|
73
|
-
driverClassName: org.postgresql.Driver
|
|
74
|
-
jdbcUrl: jdbc:postgresql://localhost:5432/shop_db_0
|
|
75
|
-
username: postgres
|
|
76
|
-
password: your_password
|
|
77
|
-
ds_1:
|
|
78
|
-
jdbcUrl: jdbc:postgresql://localhost:5432/shop_db_1
|
|
79
|
-
username: postgres
|
|
80
|
-
password: your_password
|
|
81
|
-
|
|
82
|
-
rules:
|
|
83
|
-
- !SHARDING
|
|
84
|
-
tables:
|
|
85
|
-
tbl_order:
|
|
86
|
-
actualDataNodes: ds_$->{0..1}.tbl_order_$->{0..3}
|
|
87
|
-
tableStrategy:
|
|
88
|
-
standard:
|
|
89
|
-
shardingColumn: order_id
|
|
90
|
-
shardingAlgorithmName: tbl_order_inline
|
|
91
|
-
defaultShardingColumn: corporation_id
|
|
92
|
-
defaultDatabaseStrategy:
|
|
93
|
-
standard:
|
|
94
|
-
shardingColumn: corporation_id
|
|
95
|
-
shardingAlgorithmName: database_inline
|
|
96
|
-
shardingAlgorithms:
|
|
97
|
-
database_inline:
|
|
98
|
-
type: INLINE
|
|
99
|
-
props:
|
|
100
|
-
algorithm-expression: ds_$->{corporation_id % 2}
|
|
101
|
-
tbl_order_inline:
|
|
102
|
-
type: INLINE
|
|
103
|
-
props:
|
|
104
|
-
algorithm-expression: tbl_order_$->{order_id % 4}
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
配置路径优先级:命令行参数 > `DB_CONFIG_PATH` 环境变量 > `~/.harneon-ai/db/datasource.yaml`
|
|
108
|
-
|
|
109
|
-
## MCP Tools 说明
|
|
110
|
-
|
|
111
|
-
### list_datasources
|
|
112
|
-
|
|
113
|
-
列出所有已配置的数据源信息。密码字段显示为 `***`。
|
|
114
|
-
|
|
115
|
-
| 参数 | 类型 | 必填 | 说明 |
|
|
116
|
-
|------|------|------|------|
|
|
117
|
-
| (无参数) | | | |
|
|
118
|
-
|
|
119
|
-
返回示例:
|
|
120
|
-
|
|
121
|
-
```json
|
|
122
|
-
[
|
|
123
|
-
{
|
|
124
|
-
"name": "ds_0",
|
|
125
|
-
"host": "localhost",
|
|
126
|
-
"port": 5432,
|
|
127
|
-
"database": "shop_db_0",
|
|
128
|
-
"username": "postgres",
|
|
129
|
-
"password": "***"
|
|
130
|
-
}
|
|
131
|
-
]
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### list_tables
|
|
135
|
-
|
|
136
|
-
列出指定数据源中的所有用户表和视图。
|
|
137
|
-
|
|
138
|
-
| 参数 | 类型 | 必填 | 说明 |
|
|
139
|
-
|------|------|------|------|
|
|
140
|
-
| datasource | string | 是 | 数据源名称,如 `ds_0` |
|
|
141
|
-
| schema | string | 否 | Schema 名称,默认 `public` |
|
|
142
|
-
|
|
143
|
-
返回示例:
|
|
144
|
-
|
|
145
|
-
```json
|
|
146
|
-
[
|
|
147
|
-
{ "table_name": "tbl_order_0", "table_type": "BASE TABLE" },
|
|
148
|
-
{ "table_name": "tbl_order_1", "table_type": "BASE TABLE" }
|
|
149
|
-
]
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
### describe_table
|
|
153
|
-
|
|
154
|
-
查询指定表的详细结构,包含列信息、约束和统计数据。
|
|
155
|
-
|
|
156
|
-
| 参数 | 类型 | 必填 | 说明 |
|
|
157
|
-
|------|------|------|------|
|
|
158
|
-
| datasource | string | 是 | 数据源名称 |
|
|
159
|
-
| table | string | 是 | 表名 |
|
|
160
|
-
| schema | string | 否 | Schema 名称,默认 `public` |
|
|
161
|
-
|
|
162
|
-
返回示例:
|
|
163
|
-
|
|
164
|
-
```json
|
|
165
|
-
{
|
|
166
|
-
"columns": [
|
|
167
|
-
{
|
|
168
|
-
"column_name": "id",
|
|
169
|
-
"data_type": "bigint",
|
|
170
|
-
"is_nullable": "NO",
|
|
171
|
-
"column_default": "nextval('tbl_order_0_id_seq'::regclass)",
|
|
172
|
-
"character_maximum_length": null,
|
|
173
|
-
"ordinal_position": 1,
|
|
174
|
-
"comment": "主键ID"
|
|
175
|
-
}
|
|
176
|
-
],
|
|
177
|
-
"constraints": [
|
|
178
|
-
{
|
|
179
|
-
"constraint_name": "tbl_order_0_pkey",
|
|
180
|
-
"constraint_type": "PRIMARY KEY",
|
|
181
|
-
"columns": "id"
|
|
182
|
-
}
|
|
183
|
-
],
|
|
184
|
-
"stats": {
|
|
185
|
-
"estimated_rows": 15000,
|
|
186
|
-
"total_size": "2048 kB",
|
|
187
|
-
"table_size": "1536 kB",
|
|
188
|
-
"index_size": "512 kB"
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
### describe_indexes
|
|
194
|
-
|
|
195
|
-
查询指定表的所有索引信息。
|
|
196
|
-
|
|
197
|
-
| 参数 | 类型 | 必填 | 说明 |
|
|
198
|
-
|------|------|------|------|
|
|
199
|
-
| datasource | string | 是 | 数据源名称 |
|
|
200
|
-
| table | string | 是 | 表名 |
|
|
201
|
-
| schema | string | 否 | Schema 名称,默认 `public` |
|
|
202
|
-
|
|
203
|
-
返回示例:
|
|
204
|
-
|
|
205
|
-
```json
|
|
206
|
-
[
|
|
207
|
-
{
|
|
208
|
-
"index_name": "tbl_order_0_pkey",
|
|
209
|
-
"index_columns": "id",
|
|
210
|
-
"is_unique": true,
|
|
211
|
-
"index_method": "btree",
|
|
212
|
-
"index_definition": "CREATE UNIQUE INDEX tbl_order_0_pkey ON public.tbl_order_0 USING btree (id)"
|
|
213
|
-
},
|
|
214
|
-
{
|
|
215
|
-
"index_name": "idx_order_corporation",
|
|
216
|
-
"index_columns": "corporation_id",
|
|
217
|
-
"is_unique": false,
|
|
218
|
-
"index_method": "btree",
|
|
219
|
-
"index_definition": "CREATE INDEX idx_order_corporation ON public.tbl_order_0 USING btree (corporation_id)"
|
|
220
|
-
}
|
|
221
|
-
]
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
### sharding_topology
|
|
225
|
-
|
|
226
|
-
查看分片拓扑信息。这是纯配置解析操作,不连接数据库。
|
|
227
|
-
|
|
228
|
-
| 参数 | 类型 | 必填 | 说明 |
|
|
229
|
-
|------|------|------|------|
|
|
230
|
-
| table | string | 否 | 逻辑表名(不传则返回所有表的拓扑) |
|
|
231
|
-
|
|
232
|
-
返回示例:
|
|
233
|
-
|
|
234
|
-
```json
|
|
235
|
-
[
|
|
236
|
-
{
|
|
237
|
-
"logicalTable": "tbl_order",
|
|
238
|
-
"actualDataNodes": [
|
|
239
|
-
"ds_0.tbl_order_0",
|
|
240
|
-
"ds_0.tbl_order_1",
|
|
241
|
-
"ds_1.tbl_order_0",
|
|
242
|
-
"ds_1.tbl_order_1"
|
|
243
|
-
],
|
|
244
|
-
"nodeCount": 4,
|
|
245
|
-
"tableStrategy": "standard",
|
|
246
|
-
"shardingColumn": "order_id",
|
|
247
|
-
"algorithmName": "tbl_order_inline",
|
|
248
|
-
"algorithmType": "INLINE",
|
|
249
|
-
"algorithmExpression": "tbl_order_$->{order_id % 2}",
|
|
250
|
-
"databaseStrategy": "standard",
|
|
251
|
-
"databaseShardingColumn": "corporation_id"
|
|
252
|
-
}
|
|
253
|
-
]
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
### query_metadata
|
|
257
|
-
|
|
258
|
-
执行自定义的元数据查询。仅允许查询 `information_schema` 或 `pg_catalog` 的 SELECT 语句。
|
|
259
|
-
|
|
260
|
-
| 参数 | 类型 | 必填 | 说明 |
|
|
261
|
-
|------|------|------|------|
|
|
262
|
-
| datasource | string | 是 | 数据源名称 |
|
|
263
|
-
| sql | string | 是 | SQL 查询语句 |
|
|
264
|
-
|
|
265
|
-
安全限制:
|
|
266
|
-
- 必须以 `SELECT` 开头
|
|
267
|
-
- 不允许包含分号(禁止多语句)
|
|
268
|
-
- 不允许包含写操作关键字(INSERT/UPDATE/DELETE/DROP/ALTER 等)
|
|
269
|
-
- `FROM` 子句必须直接引用 `information_schema` 或 `pg_catalog`
|
|
270
|
-
|
|
271
|
-
合法查询示例:
|
|
272
|
-
|
|
273
|
-
```sql
|
|
274
|
-
SELECT column_name, data_type FROM information_schema.columns WHERE table_name = 'tbl_order_0'
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
```sql
|
|
278
|
-
SELECT relname, reltuples FROM pg_catalog.pg_class WHERE relkind = 'r'
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
## 安全机制
|
|
282
|
-
|
|
283
|
-
本工具采用多层防御策略确保数据安全:
|
|
284
|
-
|
|
285
|
-
| 层级 | 措施 | 说明 |
|
|
286
|
-
|------|------|------|
|
|
287
|
-
| 连接层 | `default_transaction_read_only=on` | pg.Pool 级别强制只读,即使 SQL 注入也无法写入 |
|
|
288
|
-
| SQL 层 | 白名单过滤 | query_metadata 仅允许 SELECT + information_schema/pg_catalog |
|
|
289
|
-
| Tool 层 | 固定查询 | 预定义 tool 只执行硬编码的参数化查询 |
|
|
290
|
-
| 输出层 | 密码遮蔽 | 所有输出中密码显示为 `***` |
|
|
291
|
-
|
|
292
|
-
## 项目结构
|
|
293
|
-
|
|
294
|
-
```
|
|
295
|
-
src/
|
|
296
|
-
├── index.ts # MCP Server 入口,组装所有组件
|
|
297
|
-
├── config/
|
|
298
|
-
│ ├── types.ts # Zod 配置 schema 和 TypeScript 类型定义
|
|
299
|
-
│ └── parser.ts # YAML 解析、DataNodes 展开、JDBC URL 解析
|
|
300
|
-
├── db/
|
|
301
|
-
│ ├── connection-manager.ts # 多数据源连接池管理(懒初始化、并发安全)
|
|
302
|
-
│ └── metadata-queries.ts # PostgreSQL 元数据查询 SQL 封装
|
|
303
|
-
└── tools/
|
|
304
|
-
├── list-datasources.ts # Tool: 列出数据源
|
|
305
|
-
├── list-tables.ts # Tool: 列出表
|
|
306
|
-
├── describe-table.ts # Tool: 表结构详情
|
|
307
|
-
├── describe-indexes.ts # Tool: 索引详情
|
|
308
|
-
├── sharding-topology.ts # Tool: 分片拓扑
|
|
309
|
-
└── query-metadata.ts # Tool: 通用元数据查询(带安全过滤)
|
|
310
|
-
config/
|
|
311
|
-
├── datasource.yaml # 实际配置文件(.gitignore 忽略,含密码)
|
|
312
|
-
└── datasource.example.yaml # 示例配置文件
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
## 常用场景
|
|
316
|
-
|
|
317
|
-
### 了解数据库全貌
|
|
318
|
-
|
|
319
|
-
1. 调用 `list_datasources` 查看有哪些数据源
|
|
320
|
-
2. 调用 `sharding_topology` 了解分片规则和数据分布
|
|
321
|
-
3. 对感兴趣的数据源调用 `list_tables` 查看有哪些表
|
|
322
|
-
|
|
323
|
-
### 了解某张表的结构
|
|
324
|
-
|
|
325
|
-
1. 调用 `describe_table` 查看列定义、约束和统计信息
|
|
326
|
-
2. 调用 `describe_indexes` 查看索引设计
|
|
327
|
-
|
|
328
|
-
### 跨分片对比表结构
|
|
329
|
-
|
|
330
|
-
1. 调用 `sharding_topology` 获取逻辑表对应的所有物理节点
|
|
331
|
-
2. 对不同数据源的分片表分别调用 `describe_table` 对比结构差异
|
|
332
|
-
|
|
333
|
-
### 自定义元数据查询
|
|
334
|
-
|
|
335
|
-
使用 `query_metadata` 执行灵活的 information_schema / pg_catalog 查询,例如:
|
|
336
|
-
- 查找所有包含某列名的表
|
|
337
|
-
- 统计各 schema 下的表数量
|
|
338
|
-
- 查看表的存储参数
|
|
1
|
+
# Harneon DB MCP Server
|
|
2
|
+
|
|
3
|
+
一个 MCP (Model Context Protocol) Server,为 AI 助手提供只读的 PostgreSQL 数据库元数据查询能力,支持 ShardingSphere 风格的多数据源分片拓扑解析。
|
|
4
|
+
|
|
5
|
+
## 功能概览
|
|
6
|
+
|
|
7
|
+
- 查看多数据源配置信息
|
|
8
|
+
- 查询任意数据源的表列表、表结构、索引信息
|
|
9
|
+
- 解析 ShardingSphere 分片拓扑(逻辑表 → 实际数据节点映射)
|
|
10
|
+
- 执行自定义元数据查询(仅允许 information_schema / pg_catalog)
|
|
11
|
+
- 多层安全防护,严禁任何数据写入和业务数据读取
|
|
12
|
+
|
|
13
|
+
## 快速开始
|
|
14
|
+
|
|
15
|
+
### 1. 全局安装
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install -g @harneon-ai/db
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### 2. 在 Claude Desktop 中使用
|
|
22
|
+
|
|
23
|
+
编辑 Claude Desktop 配置文件(`claude_desktop_config.json`):
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"mcpServers": {
|
|
28
|
+
"harneon-db": {
|
|
29
|
+
"command": "harneon-db"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 3. 在 Claude Code 中使用
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
claude mcp add harneon-db -- harneon-db
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### 4. 配置数据源
|
|
42
|
+
|
|
43
|
+
配置文件默认保存在 `~/.harneon-ai/db/datasource.yaml`。
|
|
44
|
+
|
|
45
|
+
你可以手动创建该文件,也可以启动后通过 `save_datasource_config` 工具添加数据源(目录会自动创建)。
|
|
46
|
+
|
|
47
|
+
如需使用自定义配置路径:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
harneon-db /path/to/datasource.yaml
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
或通过环境变量:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
DB_CONFIG_PATH=/path/to/datasource.yaml harneon-db
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 5. 开发模式运行
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npm run dev
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 配置文件格式
|
|
66
|
+
|
|
67
|
+
配置文件采用 YAML 格式,兼容 ShardingSphere 配置:
|
|
68
|
+
|
|
69
|
+
```yaml
|
|
70
|
+
dataSources:
|
|
71
|
+
ds_0:
|
|
72
|
+
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
|
|
73
|
+
driverClassName: org.postgresql.Driver
|
|
74
|
+
jdbcUrl: jdbc:postgresql://localhost:5432/shop_db_0
|
|
75
|
+
username: postgres
|
|
76
|
+
password: your_password
|
|
77
|
+
ds_1:
|
|
78
|
+
jdbcUrl: jdbc:postgresql://localhost:5432/shop_db_1
|
|
79
|
+
username: postgres
|
|
80
|
+
password: your_password
|
|
81
|
+
|
|
82
|
+
rules:
|
|
83
|
+
- !SHARDING
|
|
84
|
+
tables:
|
|
85
|
+
tbl_order:
|
|
86
|
+
actualDataNodes: ds_$->{0..1}.tbl_order_$->{0..3}
|
|
87
|
+
tableStrategy:
|
|
88
|
+
standard:
|
|
89
|
+
shardingColumn: order_id
|
|
90
|
+
shardingAlgorithmName: tbl_order_inline
|
|
91
|
+
defaultShardingColumn: corporation_id
|
|
92
|
+
defaultDatabaseStrategy:
|
|
93
|
+
standard:
|
|
94
|
+
shardingColumn: corporation_id
|
|
95
|
+
shardingAlgorithmName: database_inline
|
|
96
|
+
shardingAlgorithms:
|
|
97
|
+
database_inline:
|
|
98
|
+
type: INLINE
|
|
99
|
+
props:
|
|
100
|
+
algorithm-expression: ds_$->{corporation_id % 2}
|
|
101
|
+
tbl_order_inline:
|
|
102
|
+
type: INLINE
|
|
103
|
+
props:
|
|
104
|
+
algorithm-expression: tbl_order_$->{order_id % 4}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
配置路径优先级:命令行参数 > `DB_CONFIG_PATH` 环境变量 > `~/.harneon-ai/db/datasource.yaml`
|
|
108
|
+
|
|
109
|
+
## MCP Tools 说明
|
|
110
|
+
|
|
111
|
+
### list_datasources
|
|
112
|
+
|
|
113
|
+
列出所有已配置的数据源信息。密码字段显示为 `***`。
|
|
114
|
+
|
|
115
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
116
|
+
|------|------|------|------|
|
|
117
|
+
| (无参数) | | | |
|
|
118
|
+
|
|
119
|
+
返回示例:
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
[
|
|
123
|
+
{
|
|
124
|
+
"name": "ds_0",
|
|
125
|
+
"host": "localhost",
|
|
126
|
+
"port": 5432,
|
|
127
|
+
"database": "shop_db_0",
|
|
128
|
+
"username": "postgres",
|
|
129
|
+
"password": "***"
|
|
130
|
+
}
|
|
131
|
+
]
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### list_tables
|
|
135
|
+
|
|
136
|
+
列出指定数据源中的所有用户表和视图。
|
|
137
|
+
|
|
138
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
139
|
+
|------|------|------|------|
|
|
140
|
+
| datasource | string | 是 | 数据源名称,如 `ds_0` |
|
|
141
|
+
| schema | string | 否 | Schema 名称,默认 `public` |
|
|
142
|
+
|
|
143
|
+
返回示例:
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
[
|
|
147
|
+
{ "table_name": "tbl_order_0", "table_type": "BASE TABLE" },
|
|
148
|
+
{ "table_name": "tbl_order_1", "table_type": "BASE TABLE" }
|
|
149
|
+
]
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### describe_table
|
|
153
|
+
|
|
154
|
+
查询指定表的详细结构,包含列信息、约束和统计数据。
|
|
155
|
+
|
|
156
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
157
|
+
|------|------|------|------|
|
|
158
|
+
| datasource | string | 是 | 数据源名称 |
|
|
159
|
+
| table | string | 是 | 表名 |
|
|
160
|
+
| schema | string | 否 | Schema 名称,默认 `public` |
|
|
161
|
+
|
|
162
|
+
返回示例:
|
|
163
|
+
|
|
164
|
+
```json
|
|
165
|
+
{
|
|
166
|
+
"columns": [
|
|
167
|
+
{
|
|
168
|
+
"column_name": "id",
|
|
169
|
+
"data_type": "bigint",
|
|
170
|
+
"is_nullable": "NO",
|
|
171
|
+
"column_default": "nextval('tbl_order_0_id_seq'::regclass)",
|
|
172
|
+
"character_maximum_length": null,
|
|
173
|
+
"ordinal_position": 1,
|
|
174
|
+
"comment": "主键ID"
|
|
175
|
+
}
|
|
176
|
+
],
|
|
177
|
+
"constraints": [
|
|
178
|
+
{
|
|
179
|
+
"constraint_name": "tbl_order_0_pkey",
|
|
180
|
+
"constraint_type": "PRIMARY KEY",
|
|
181
|
+
"columns": "id"
|
|
182
|
+
}
|
|
183
|
+
],
|
|
184
|
+
"stats": {
|
|
185
|
+
"estimated_rows": 15000,
|
|
186
|
+
"total_size": "2048 kB",
|
|
187
|
+
"table_size": "1536 kB",
|
|
188
|
+
"index_size": "512 kB"
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### describe_indexes
|
|
194
|
+
|
|
195
|
+
查询指定表的所有索引信息。
|
|
196
|
+
|
|
197
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
198
|
+
|------|------|------|------|
|
|
199
|
+
| datasource | string | 是 | 数据源名称 |
|
|
200
|
+
| table | string | 是 | 表名 |
|
|
201
|
+
| schema | string | 否 | Schema 名称,默认 `public` |
|
|
202
|
+
|
|
203
|
+
返回示例:
|
|
204
|
+
|
|
205
|
+
```json
|
|
206
|
+
[
|
|
207
|
+
{
|
|
208
|
+
"index_name": "tbl_order_0_pkey",
|
|
209
|
+
"index_columns": "id",
|
|
210
|
+
"is_unique": true,
|
|
211
|
+
"index_method": "btree",
|
|
212
|
+
"index_definition": "CREATE UNIQUE INDEX tbl_order_0_pkey ON public.tbl_order_0 USING btree (id)"
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
"index_name": "idx_order_corporation",
|
|
216
|
+
"index_columns": "corporation_id",
|
|
217
|
+
"is_unique": false,
|
|
218
|
+
"index_method": "btree",
|
|
219
|
+
"index_definition": "CREATE INDEX idx_order_corporation ON public.tbl_order_0 USING btree (corporation_id)"
|
|
220
|
+
}
|
|
221
|
+
]
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### sharding_topology
|
|
225
|
+
|
|
226
|
+
查看分片拓扑信息。这是纯配置解析操作,不连接数据库。
|
|
227
|
+
|
|
228
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
229
|
+
|------|------|------|------|
|
|
230
|
+
| table | string | 否 | 逻辑表名(不传则返回所有表的拓扑) |
|
|
231
|
+
|
|
232
|
+
返回示例:
|
|
233
|
+
|
|
234
|
+
```json
|
|
235
|
+
[
|
|
236
|
+
{
|
|
237
|
+
"logicalTable": "tbl_order",
|
|
238
|
+
"actualDataNodes": [
|
|
239
|
+
"ds_0.tbl_order_0",
|
|
240
|
+
"ds_0.tbl_order_1",
|
|
241
|
+
"ds_1.tbl_order_0",
|
|
242
|
+
"ds_1.tbl_order_1"
|
|
243
|
+
],
|
|
244
|
+
"nodeCount": 4,
|
|
245
|
+
"tableStrategy": "standard",
|
|
246
|
+
"shardingColumn": "order_id",
|
|
247
|
+
"algorithmName": "tbl_order_inline",
|
|
248
|
+
"algorithmType": "INLINE",
|
|
249
|
+
"algorithmExpression": "tbl_order_$->{order_id % 2}",
|
|
250
|
+
"databaseStrategy": "standard",
|
|
251
|
+
"databaseShardingColumn": "corporation_id"
|
|
252
|
+
}
|
|
253
|
+
]
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### query_metadata
|
|
257
|
+
|
|
258
|
+
执行自定义的元数据查询。仅允许查询 `information_schema` 或 `pg_catalog` 的 SELECT 语句。
|
|
259
|
+
|
|
260
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
261
|
+
|------|------|------|------|
|
|
262
|
+
| datasource | string | 是 | 数据源名称 |
|
|
263
|
+
| sql | string | 是 | SQL 查询语句 |
|
|
264
|
+
|
|
265
|
+
安全限制:
|
|
266
|
+
- 必须以 `SELECT` 开头
|
|
267
|
+
- 不允许包含分号(禁止多语句)
|
|
268
|
+
- 不允许包含写操作关键字(INSERT/UPDATE/DELETE/DROP/ALTER 等)
|
|
269
|
+
- `FROM` 子句必须直接引用 `information_schema` 或 `pg_catalog`
|
|
270
|
+
|
|
271
|
+
合法查询示例:
|
|
272
|
+
|
|
273
|
+
```sql
|
|
274
|
+
SELECT column_name, data_type FROM information_schema.columns WHERE table_name = 'tbl_order_0'
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
```sql
|
|
278
|
+
SELECT relname, reltuples FROM pg_catalog.pg_class WHERE relkind = 'r'
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## 安全机制
|
|
282
|
+
|
|
283
|
+
本工具采用多层防御策略确保数据安全:
|
|
284
|
+
|
|
285
|
+
| 层级 | 措施 | 说明 |
|
|
286
|
+
|------|------|------|
|
|
287
|
+
| 连接层 | `default_transaction_read_only=on` | pg.Pool 级别强制只读,即使 SQL 注入也无法写入 |
|
|
288
|
+
| SQL 层 | 白名单过滤 | query_metadata 仅允许 SELECT + information_schema/pg_catalog |
|
|
289
|
+
| Tool 层 | 固定查询 | 预定义 tool 只执行硬编码的参数化查询 |
|
|
290
|
+
| 输出层 | 密码遮蔽 | 所有输出中密码显示为 `***` |
|
|
291
|
+
|
|
292
|
+
## 项目结构
|
|
293
|
+
|
|
294
|
+
```
|
|
295
|
+
src/
|
|
296
|
+
├── index.ts # MCP Server 入口,组装所有组件
|
|
297
|
+
├── config/
|
|
298
|
+
│ ├── types.ts # Zod 配置 schema 和 TypeScript 类型定义
|
|
299
|
+
│ └── parser.ts # YAML 解析、DataNodes 展开、JDBC URL 解析
|
|
300
|
+
├── db/
|
|
301
|
+
│ ├── connection-manager.ts # 多数据源连接池管理(懒初始化、并发安全)
|
|
302
|
+
│ └── metadata-queries.ts # PostgreSQL 元数据查询 SQL 封装
|
|
303
|
+
└── tools/
|
|
304
|
+
├── list-datasources.ts # Tool: 列出数据源
|
|
305
|
+
├── list-tables.ts # Tool: 列出表
|
|
306
|
+
├── describe-table.ts # Tool: 表结构详情
|
|
307
|
+
├── describe-indexes.ts # Tool: 索引详情
|
|
308
|
+
├── sharding-topology.ts # Tool: 分片拓扑
|
|
309
|
+
└── query-metadata.ts # Tool: 通用元数据查询(带安全过滤)
|
|
310
|
+
config/
|
|
311
|
+
├── datasource.yaml # 实际配置文件(.gitignore 忽略,含密码)
|
|
312
|
+
└── datasource.example.yaml # 示例配置文件
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
## 常用场景
|
|
316
|
+
|
|
317
|
+
### 了解数据库全貌
|
|
318
|
+
|
|
319
|
+
1. 调用 `list_datasources` 查看有哪些数据源
|
|
320
|
+
2. 调用 `sharding_topology` 了解分片规则和数据分布
|
|
321
|
+
3. 对感兴趣的数据源调用 `list_tables` 查看有哪些表
|
|
322
|
+
|
|
323
|
+
### 了解某张表的结构
|
|
324
|
+
|
|
325
|
+
1. 调用 `describe_table` 查看列定义、约束和统计信息
|
|
326
|
+
2. 调用 `describe_indexes` 查看索引设计
|
|
327
|
+
|
|
328
|
+
### 跨分片对比表结构
|
|
329
|
+
|
|
330
|
+
1. 调用 `sharding_topology` 获取逻辑表对应的所有物理节点
|
|
331
|
+
2. 对不同数据源的分片表分别调用 `describe_table` 对比结构差异
|
|
332
|
+
|
|
333
|
+
### 自定义元数据查询
|
|
334
|
+
|
|
335
|
+
使用 `query_metadata` 执行灵活的 information_schema / pg_catalog 查询,例如:
|
|
336
|
+
- 查找所有包含某列名的表
|
|
337
|
+
- 统计各 schema 下的表数量
|
|
338
|
+
- 查看表的存储参数
|