@cano721/mysql-mcp-server 0.7.0 → 0.8.0
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 +28 -10
- package/build/index.js +55 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -343,6 +343,11 @@ MySQL 서버에서 접근 가능한 모든 데이터베이스를 나열합니다
|
|
|
343
343
|
- `table` (필수): 연관 테이블을 찾을 기준 테이블명
|
|
344
344
|
- `database` (선택사항): 데이터베이스명
|
|
345
345
|
- `depth` (선택사항): 탐색할 최대 깊이 (기본값: 3, 10 초과 시 경고)
|
|
346
|
+
- `include_pattern_match` (선택사항): 컬럼명 패턴 매칭 포함 여부 (기본값: false)
|
|
347
|
+
|
|
348
|
+
**검색 방법**:
|
|
349
|
+
1. **FK 제약조건 기반** (기본): 실제 Foreign Key가 설정된 테이블만 조회
|
|
350
|
+
2. **패턴 매칭 포함**: `user_sn`, `user_id` 같은 컬럼명 패턴으로 추가 테이블 탐색
|
|
346
351
|
|
|
347
352
|
**예제**:
|
|
348
353
|
```json
|
|
@@ -357,29 +362,41 @@ MySQL 서버에서 접근 가능한 모든 데이터베이스를 나열합니다
|
|
|
357
362
|
}
|
|
358
363
|
```
|
|
359
364
|
|
|
365
|
+
**패턴 매칭 포함 예제**:
|
|
366
|
+
```json
|
|
367
|
+
{
|
|
368
|
+
"server_name": "mysql",
|
|
369
|
+
"tool_name": "get_related_tables",
|
|
370
|
+
"arguments": {
|
|
371
|
+
"database": "my_database",
|
|
372
|
+
"table": "user",
|
|
373
|
+
"depth": 2,
|
|
374
|
+
"include_pattern_match": true
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
```
|
|
378
|
+
|
|
360
379
|
**응답 예시**:
|
|
361
380
|
```json
|
|
362
381
|
{
|
|
363
382
|
"root_table": "user",
|
|
364
383
|
"database": "my_database",
|
|
365
384
|
"requested_depth": 2,
|
|
385
|
+
"search_method": "fk_constraint",
|
|
386
|
+
"fk_relations_count": 55,
|
|
387
|
+
"pattern_match_count": 0,
|
|
366
388
|
"total_relations": 55,
|
|
367
|
-
"
|
|
389
|
+
"fk_relations": [
|
|
368
390
|
{
|
|
369
391
|
"depth": 1,
|
|
370
392
|
"child_table": "user_matching_information",
|
|
371
393
|
"fk_column": "user_sn",
|
|
372
394
|
"parent_table": "user",
|
|
373
|
-
"constraint_name": "FK_USER_MATCHING_INFORMATION_USER_SN"
|
|
374
|
-
|
|
375
|
-
{
|
|
376
|
-
"depth": 2,
|
|
377
|
-
"child_table": "user_matching_profile",
|
|
378
|
-
"fk_column": "user_matching_information_sn",
|
|
379
|
-
"parent_table": "user_matching_information",
|
|
380
|
-
"constraint_name": "FK_USER_MATCHING_PROFILE_USER_INFORMATION_SN"
|
|
395
|
+
"constraint_name": "FK_USER_MATCHING_INFORMATION_USER_SN",
|
|
396
|
+
"match_type": "fk_constraint"
|
|
381
397
|
}
|
|
382
|
-
]
|
|
398
|
+
],
|
|
399
|
+
"note": "FK 제약조건 기반으로 조회되었습니다. 패턴 매칭도 포함하려면 '패턴 매칭도 포함해줘'라고 요청해보세요."
|
|
383
400
|
}
|
|
384
401
|
```
|
|
385
402
|
|
|
@@ -775,6 +792,7 @@ echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | npx @cano721/mysql-mcp-s
|
|
|
775
792
|
|
|
776
793
|
| 버전 | 날짜 | 주요 변경 사항 |
|
|
777
794
|
|------|------|---------------|
|
|
795
|
+
| 0.8.0 | 2025-01-09 | `get_related_tables`에 패턴 매칭 옵션 추가, depth 제한 제거 |
|
|
778
796
|
| 0.7.0 | 2025-01-09 | `get_related_tables` 도구 추가 (FK 기반 연관 테이블 depth별 조회) |
|
|
779
797
|
| 0.6.0 | 2025-01-09 | `analyze_table` → `analyze_query`로 변경, `@latest` 태그 문서 추가 |
|
|
780
798
|
| 0.5.0 | 2025-01-09 | `explain_query`, `analyze_table` 전용 도구 추가 |
|
package/build/index.js
CHANGED
|
@@ -122,7 +122,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
122
122
|
},
|
|
123
123
|
{
|
|
124
124
|
name: "get_related_tables",
|
|
125
|
-
description: "Get all tables related to a specific table through foreign keys (parent and child relationships with depth)",
|
|
125
|
+
description: "Get all tables related to a specific table through foreign keys (parent and child relationships with depth). Results are based on FK constraints only. Set include_pattern_match=true to also find tables by column name patterns.",
|
|
126
126
|
inputSchema: {
|
|
127
127
|
type: "object",
|
|
128
128
|
properties: {
|
|
@@ -137,6 +137,10 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
137
137
|
depth: {
|
|
138
138
|
type: "number",
|
|
139
139
|
description: "Maximum depth to traverse relationships (default: 3, warning if > 10)"
|
|
140
|
+
},
|
|
141
|
+
include_pattern_match: {
|
|
142
|
+
type: "boolean",
|
|
143
|
+
description: "Include tables found by column name pattern matching (e.g., user_sn, user_id). Default: false"
|
|
140
144
|
}
|
|
141
145
|
},
|
|
142
146
|
required: ["table"]
|
|
@@ -295,6 +299,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
295
299
|
const table = request.params.arguments?.table;
|
|
296
300
|
const database = request.params.arguments?.database;
|
|
297
301
|
const requestedDepth = request.params.arguments?.depth || 3;
|
|
302
|
+
const includePatternMatch = request.params.arguments?.include_pattern_match || false;
|
|
298
303
|
if (!table) {
|
|
299
304
|
throw new McpError(ErrorCode.InvalidParams, "Table name is required");
|
|
300
305
|
}
|
|
@@ -340,7 +345,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
340
345
|
child_table: row.child_table,
|
|
341
346
|
fk_column: row.fk_column,
|
|
342
347
|
parent_table: row.parent_table,
|
|
343
|
-
constraint_name: row.constraint_name
|
|
348
|
+
constraint_name: row.constraint_name,
|
|
349
|
+
match_type: 'fk_constraint'
|
|
344
350
|
});
|
|
345
351
|
if (!visited.has(row.child_table)) {
|
|
346
352
|
visited.add(row.child_table);
|
|
@@ -371,7 +377,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
371
377
|
child_table: row.child_table,
|
|
372
378
|
fk_column: row.fk_column,
|
|
373
379
|
parent_table: row.parent_table,
|
|
374
|
-
constraint_name: row.constraint_name
|
|
380
|
+
constraint_name: row.constraint_name,
|
|
381
|
+
match_type: 'fk_constraint'
|
|
375
382
|
});
|
|
376
383
|
}
|
|
377
384
|
if (!visited.has(row.parent_table)) {
|
|
@@ -386,12 +393,55 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
386
393
|
return a.depth - b.depth;
|
|
387
394
|
return a.child_table.localeCompare(b.child_table);
|
|
388
395
|
});
|
|
396
|
+
// Pattern matching for tables without FK constraints
|
|
397
|
+
let patternMatchResults = [];
|
|
398
|
+
if (includePatternMatch) {
|
|
399
|
+
console.error('[Tool] Including pattern match results');
|
|
400
|
+
// Common patterns: table_sn, table_id, table_code, sn_table, id_table
|
|
401
|
+
const patterns = [
|
|
402
|
+
`${table}_sn`, `${table}_id`, `${table}_code`,
|
|
403
|
+
`sn_${table}`, `id_${table}`,
|
|
404
|
+
`${table}sn`, `${table}id`
|
|
405
|
+
];
|
|
406
|
+
const patternQuery = `
|
|
407
|
+
SELECT DISTINCT
|
|
408
|
+
c.TABLE_NAME as related_table,
|
|
409
|
+
c.COLUMN_NAME as matching_column
|
|
410
|
+
FROM information_schema.COLUMNS c
|
|
411
|
+
WHERE c.TABLE_SCHEMA = ?
|
|
412
|
+
AND c.TABLE_NAME != ?
|
|
413
|
+
AND (${patterns.map(() => 'LOWER(c.COLUMN_NAME) = LOWER(?)').join(' OR ')})
|
|
414
|
+
`;
|
|
415
|
+
const { rows: patternRows } = await executeQuery(pool, patternQuery, [dbName, table, ...patterns]);
|
|
416
|
+
// Filter out tables already found via FK
|
|
417
|
+
const fkTables = new Set(results.map(r => r.child_table));
|
|
418
|
+
fkTables.add(table);
|
|
419
|
+
for (const row of patternRows) {
|
|
420
|
+
if (!fkTables.has(row.related_table)) {
|
|
421
|
+
patternMatchResults.push({
|
|
422
|
+
depth: 1,
|
|
423
|
+
child_table: row.related_table,
|
|
424
|
+
fk_column: row.matching_column,
|
|
425
|
+
parent_table: table,
|
|
426
|
+
constraint_name: '(pattern match)',
|
|
427
|
+
match_type: 'pattern_match'
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
389
432
|
const response = {
|
|
390
433
|
root_table: table,
|
|
391
434
|
database: dbName,
|
|
392
435
|
requested_depth: requestedDepth,
|
|
393
|
-
|
|
394
|
-
|
|
436
|
+
search_method: includePatternMatch ? 'fk_constraint + pattern_match' : 'fk_constraint',
|
|
437
|
+
fk_relations_count: results.length,
|
|
438
|
+
pattern_match_count: patternMatchResults.length,
|
|
439
|
+
total_relations: results.length + patternMatchResults.length,
|
|
440
|
+
fk_relations: results,
|
|
441
|
+
pattern_match_relations: includePatternMatch ? patternMatchResults : undefined,
|
|
442
|
+
note: includePatternMatch
|
|
443
|
+
? "FK 제약조건 + 컬럼명 패턴 매칭 결과입니다."
|
|
444
|
+
: "FK 제약조건 기반으로 조회되었습니다. 패턴 매칭도 포함하려면 '패턴 매칭도 포함해줘'라고 요청해보세요."
|
|
395
445
|
};
|
|
396
446
|
if (warning) {
|
|
397
447
|
response.warning = warning;
|