@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.
Files changed (44) hide show
  1. package/README.md +338 -338
  2. package/config/datasource.example.yaml +68 -62
  3. package/dist/config/config-manager.d.ts +110 -0
  4. package/dist/config/config-manager.js +275 -0
  5. package/dist/config/parser.d.ts +35 -21
  6. package/dist/config/parser.js +84 -36
  7. package/dist/config/types.d.ts +349 -1
  8. package/dist/config/types.js +19 -1
  9. package/dist/config/writer.d.ts +35 -1
  10. package/dist/config/writer.js +83 -0
  11. package/dist/db/connection-manager.d.ts +52 -18
  12. package/dist/db/connection-manager.js +93 -35
  13. package/dist/db/driver-registry.d.ts +51 -0
  14. package/dist/db/driver-registry.js +89 -0
  15. package/dist/db/driver.d.ts +63 -0
  16. package/dist/db/driver.js +15 -0
  17. package/dist/db/drivers/mysql.d.ts +89 -0
  18. package/dist/db/drivers/mysql.js +268 -0
  19. package/dist/db/drivers/postgresql.d.ts +95 -0
  20. package/dist/db/drivers/postgresql.js +252 -0
  21. package/dist/db/metadata-queries.js +53 -53
  22. package/dist/db/types.d.ts +95 -0
  23. package/dist/db/types.js +14 -0
  24. package/dist/index.d.ts +9 -8
  25. package/dist/index.js +33 -28
  26. package/dist/tools/delete-datasource-config.d.ts +12 -0
  27. package/dist/tools/delete-datasource-config.js +75 -0
  28. package/dist/tools/describe-indexes.d.ts +1 -1
  29. package/dist/tools/describe-indexes.js +7 -5
  30. package/dist/tools/describe-table.d.ts +1 -0
  31. package/dist/tools/describe-table.js +9 -6
  32. package/dist/tools/list-datasources.d.ts +3 -2
  33. package/dist/tools/list-datasources.js +19 -8
  34. package/dist/tools/list-tables.d.ts +1 -1
  35. package/dist/tools/list-tables.js +7 -5
  36. package/dist/tools/query-metadata.d.ts +2 -7
  37. package/dist/tools/query-metadata.js +18 -51
  38. package/dist/tools/save-datasource-config.d.ts +5 -4
  39. package/dist/tools/save-datasource-config.js +25 -28
  40. package/dist/tools/test-connection.d.ts +4 -2
  41. package/dist/tools/test-connection.js +47 -40
  42. package/dist/tools/update-datasource-config.d.ts +14 -0
  43. package/dist/tools/update-datasource-config.js +243 -0
  44. 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
+ - 查看表的存储参数