mcp-database-inspector 2.0.1
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 +197 -0
- package/dist/database/connection.d.ts +13 -0
- package/dist/database/connection.d.ts.map +1 -0
- package/dist/database/connection.js +155 -0
- package/dist/database/connection.js.map +1 -0
- package/dist/database/manager.d.ts +28 -0
- package/dist/database/manager.d.ts.map +1 -0
- package/dist/database/manager.js +621 -0
- package/dist/database/manager.js.map +1 -0
- package/dist/database/postgres-connection.d.ts +10 -0
- package/dist/database/postgres-connection.d.ts.map +1 -0
- package/dist/database/postgres-connection.js +113 -0
- package/dist/database/postgres-connection.js.map +1 -0
- package/dist/database/types.d.ts +84 -0
- package/dist/database/types.d.ts.map +1 -0
- package/dist/database/types.js +6 -0
- package/dist/database/types.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +120 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +14 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +186 -0
- package/dist/server.js.map +1 -0
- package/dist/test-defaults.d.ts +2 -0
- package/dist/test-defaults.d.ts.map +1 -0
- package/dist/test-defaults.js +57 -0
- package/dist/test-defaults.js.map +1 -0
- package/dist/tools/analyze-query.d.ts +27 -0
- package/dist/tools/analyze-query.d.ts.map +1 -0
- package/dist/tools/analyze-query.js +71 -0
- package/dist/tools/analyze-query.js.map +1 -0
- package/dist/tools/execute-query.d.ts +33 -0
- package/dist/tools/execute-query.d.ts.map +1 -0
- package/dist/tools/execute-query.js +57 -0
- package/dist/tools/execute-query.js.map +1 -0
- package/dist/tools/get-foreign-keys.d.ts +38 -0
- package/dist/tools/get-foreign-keys.d.ts.map +1 -0
- package/dist/tools/get-foreign-keys.js +391 -0
- package/dist/tools/get-foreign-keys.js.map +1 -0
- package/dist/tools/get-indexes.d.ts +38 -0
- package/dist/tools/get-indexes.d.ts.map +1 -0
- package/dist/tools/get-indexes.js +472 -0
- package/dist/tools/get-indexes.js.map +1 -0
- package/dist/tools/information-schema-query.d.ts +33 -0
- package/dist/tools/information-schema-query.d.ts.map +1 -0
- package/dist/tools/information-schema-query.js +76 -0
- package/dist/tools/information-schema-query.js.map +1 -0
- package/dist/tools/inspect-table.d.ts +38 -0
- package/dist/tools/inspect-table.d.ts.map +1 -0
- package/dist/tools/inspect-table.js +351 -0
- package/dist/tools/inspect-table.js.map +1 -0
- package/dist/tools/list-databases.d.ts +14 -0
- package/dist/tools/list-databases.d.ts.map +1 -0
- package/dist/tools/list-databases.js +83 -0
- package/dist/tools/list-databases.js.map +1 -0
- package/dist/tools/list-tables.d.ts +19 -0
- package/dist/tools/list-tables.d.ts.map +1 -0
- package/dist/tools/list-tables.js +130 -0
- package/dist/tools/list-tables.js.map +1 -0
- package/dist/utils/errors.d.ts +32 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +98 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/logger.d.ts +28 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +132 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/validators/input-validator.d.ts +76 -0
- package/dist/validators/input-validator.d.ts.map +1 -0
- package/dist/validators/input-validator.js +295 -0
- package/dist/validators/input-validator.js.map +1 -0
- package/dist/validators/query-validator.d.ts +19 -0
- package/dist/validators/query-validator.d.ts.map +1 -0
- package/dist/validators/query-validator.js +229 -0
- package/dist/validators/query-validator.js.map +1 -0
- package/enhanced_sql_prompt.md +324 -0
- package/examples/claude-config.json +23 -0
- package/examples/roo-config.json +16 -0
- package/package.json +42 -0
- package/src/database/connection.ts +165 -0
- package/src/database/manager.ts +682 -0
- package/src/database/postgres-connection.ts +123 -0
- package/src/database/types.ts +93 -0
- package/src/index.ts +136 -0
- package/src/server.ts +254 -0
- package/src/test-defaults.ts +63 -0
- package/src/tools/analyze-query.test.ts +100 -0
- package/src/tools/analyze-query.ts +112 -0
- package/src/tools/execute-query.ts +91 -0
- package/src/tools/get-foreign-keys.test.ts +51 -0
- package/src/tools/get-foreign-keys.ts +488 -0
- package/src/tools/get-indexes.test.ts +51 -0
- package/src/tools/get-indexes.ts +570 -0
- package/src/tools/information-schema-query.ts +125 -0
- package/src/tools/inspect-table.test.ts +59 -0
- package/src/tools/inspect-table.ts +440 -0
- package/src/tools/list-databases.ts +119 -0
- package/src/tools/list-tables.ts +181 -0
- package/src/utils/errors.ts +103 -0
- package/src/utils/logger.ts +158 -0
- package/src/validators/input-validator.ts +318 -0
- package/src/validators/query-validator.ts +267 -0
- package/tsconfig.json +30 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// Tool: informationSchemaQuery
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { InputValidator } from '../validators/input-validator.js';
|
|
4
|
+
import { Logger } from '../utils/logger.js';
|
|
5
|
+
import { ToolError } from '../utils/errors.js';
|
|
6
|
+
// Allowed tables for INFORMATION_SCHEMA
|
|
7
|
+
const ALLOWED_TABLES = ['COLUMNS', 'TABLES', 'ROUTINES'];
|
|
8
|
+
// Zod schema for arguments
|
|
9
|
+
const InformationSchemaQueryArgsSchema = z.object({
|
|
10
|
+
database: z.string().min(1, 'Database name is required'),
|
|
11
|
+
table: z.enum(ALLOWED_TABLES),
|
|
12
|
+
filters: z.record(z.string(), z.string()).optional(), // key-value pairs for WHERE
|
|
13
|
+
limit: z.number().int().min(1).max(1000).optional()
|
|
14
|
+
});
|
|
15
|
+
export const informationSchemaQueryToolDefinition = {
|
|
16
|
+
name: 'information_schema_query',
|
|
17
|
+
description: 'Query INFORMATION_SCHEMA tables (COLUMNS, TABLES, ROUTINES) with filters and limits. Only safe, parameterized queries are allowed.',
|
|
18
|
+
inputSchema: {
|
|
19
|
+
type: 'object',
|
|
20
|
+
properties: {
|
|
21
|
+
database: { type: 'string', description: 'Database name' },
|
|
22
|
+
table: { type: 'string', enum: ALLOWED_TABLES, description: 'INFORMATION_SCHEMA table to query' },
|
|
23
|
+
filters: { type: 'object', description: 'Key-value filters for WHERE clause' },
|
|
24
|
+
limit: { type: 'number', description: 'Maximum number of rows to return (default 100)' }
|
|
25
|
+
},
|
|
26
|
+
required: ['database', 'table']
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
export async function handleInformationSchemaQuery(args, dbManager) {
|
|
30
|
+
try {
|
|
31
|
+
Logger.info('Executing information_schema_query tool');
|
|
32
|
+
const validationResult = InformationSchemaQueryArgsSchema.safeParse(args);
|
|
33
|
+
if (!validationResult.success) {
|
|
34
|
+
Logger.warn('Invalid arguments for information_schema_query', validationResult.error);
|
|
35
|
+
throw new ToolError(`Invalid arguments: ${validationResult.error.issues.map(e => `${e.path.join('.')}: ${e.message}`).join(', ')}`, 'information_schema_query');
|
|
36
|
+
}
|
|
37
|
+
const { database, table, filters, limit } = validationResult.data;
|
|
38
|
+
// Sanitize and validate database name
|
|
39
|
+
const sanitizedDatabase = InputValidator.sanitizeString(database);
|
|
40
|
+
const dbNameValidation = InputValidator.validateDatabaseName(sanitizedDatabase);
|
|
41
|
+
if (!dbNameValidation.isValid) {
|
|
42
|
+
throw new ToolError(`Invalid database name: ${dbNameValidation.error}`, 'information_schema_query');
|
|
43
|
+
}
|
|
44
|
+
// Only allow specific INFORMATION_SCHEMA tables
|
|
45
|
+
if (!ALLOWED_TABLES.includes(table)) {
|
|
46
|
+
throw new ToolError(`Table '${table}' is not allowed. Only ${ALLOWED_TABLES.join(', ')} are permitted.`, 'information_schema_query');
|
|
47
|
+
}
|
|
48
|
+
// Validate filters: only allow string keys/values, and only safe columns
|
|
49
|
+
let safeFilters = {};
|
|
50
|
+
if (filters) {
|
|
51
|
+
for (const [key, value] of Object.entries(filters)) {
|
|
52
|
+
if (!/^[A-Z_]+$/.test(key)) {
|
|
53
|
+
throw new ToolError(`Invalid filter key: ${key}. Only uppercase letters and underscores allowed.`, 'information_schema_query');
|
|
54
|
+
}
|
|
55
|
+
safeFilters[key] = InputValidator.sanitizeString(value);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Limit
|
|
59
|
+
const safeLimit = limit && limit > 0 && limit <= 1000 ? limit : 100;
|
|
60
|
+
Logger.info(`Querying INFORMATION_SCHEMA.${table} for database ${sanitizedDatabase} with filters: ${JSON.stringify(safeFilters)} and limit ${safeLimit}`);
|
|
61
|
+
const result = await dbManager.queryInformationSchema(sanitizedDatabase, table, safeFilters, safeLimit);
|
|
62
|
+
return {
|
|
63
|
+
content: [{
|
|
64
|
+
type: 'text',
|
|
65
|
+
text: JSON.stringify(result.rows, null, 2)
|
|
66
|
+
}]
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
Logger.error('Error in information_schema_query tool', error);
|
|
71
|
+
if (error instanceof ToolError)
|
|
72
|
+
throw error;
|
|
73
|
+
throw new ToolError(`Failed to query INFORMATION_SCHEMA: ${error instanceof Error ? error.message : 'Unknown error'}`, 'information_schema_query', error instanceof Error ? error : undefined);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=information-schema-query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"information-schema-query.js","sourceRoot":"","sources":["../../src/tools/information-schema-query.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { DatabaseManager } from '../database/manager.js';
|
|
2
|
+
/**
|
|
3
|
+
* Tool: inspect_table
|
|
4
|
+
* Get complete table schema including columns, types, constraints, and metadata.
|
|
5
|
+
*
|
|
6
|
+
* Supports both single-table and multi-table inspection:
|
|
7
|
+
* - Provide either `table` (string) for a single table, or `tables` (string[]) for multiple tables.
|
|
8
|
+
* - If `tables` is provided, returns a mapping of table names to their schema analysis.
|
|
9
|
+
* - Do not provide both `table` and `tables` at the same time.
|
|
10
|
+
*/
|
|
11
|
+
export interface InspectTableTool {
|
|
12
|
+
name: 'inspect_table';
|
|
13
|
+
description: 'Get complete table schema including columns, types, constraints, and metadata. Supports multi-table inspection via the tables: string[] parameter.';
|
|
14
|
+
inputSchema: {
|
|
15
|
+
type: 'object';
|
|
16
|
+
properties: {
|
|
17
|
+
database: {
|
|
18
|
+
type: 'string';
|
|
19
|
+
description: 'Name of the database containing the table(s)';
|
|
20
|
+
};
|
|
21
|
+
table: {
|
|
22
|
+
type: 'string';
|
|
23
|
+
description: 'Name of the table to inspect (single-table mode)';
|
|
24
|
+
};
|
|
25
|
+
tables: {
|
|
26
|
+
type: 'array';
|
|
27
|
+
items: {
|
|
28
|
+
type: 'string';
|
|
29
|
+
};
|
|
30
|
+
description: 'Array of table names to inspect (multi-table mode)';
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
required: ['database'];
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export declare const inspectTableToolDefinition: InspectTableTool;
|
|
37
|
+
export declare function handleInspectTable(args: unknown, dbManager: DatabaseManager): Promise<any>;
|
|
38
|
+
//# sourceMappingURL=inspect-table.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspect-table.d.ts","sourceRoot":"","sources":["../../src/tools/inspect-table.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AA0BzD;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,eAAe,CAAC;IACtB,WAAW,EAAE,oJAAoJ,CAAC;IAClK,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE;YACV,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ,CAAC;gBACf,WAAW,EAAE,8CAA8C,CAAC;aAC7D,CAAC;YACF,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ,CAAC;gBACf,WAAW,EAAE,kDAAkD,CAAC;aACjE,CAAC;YACF,MAAM,EAAE;gBACN,IAAI,EAAE,OAAO,CAAC;gBACd,KAAK,EAAE;oBAAE,IAAI,EAAE,QAAQ,CAAA;iBAAE,CAAC;gBAC1B,WAAW,EAAE,oDAAoD,CAAC;aACnE,CAAC;SACH,CAAC;QACF,QAAQ,EAAE,CAAC,UAAU,CAAC,CAAC;KACxB,CAAC;CACH;AAED,eAAO,MAAM,0BAA0B,EAAE,gBAsBxC,CAAC;AAEF,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,OAAO,EACb,SAAS,EAAE,eAAe,GACzB,OAAO,CAAC,GAAG,CAAC,CAyNd"}
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { InputValidator } from '../validators/input-validator.js';
|
|
3
|
+
import { Logger } from '../utils/logger.js';
|
|
4
|
+
import { ToolError } from '../utils/errors.js';
|
|
5
|
+
// Tool schema
|
|
6
|
+
const InspectTableArgsSchema = z.object({
|
|
7
|
+
database: z.string().min(1, 'Database name is required'),
|
|
8
|
+
table: z.string().optional(),
|
|
9
|
+
tables: z.array(z.string().min(1)).optional()
|
|
10
|
+
}).superRefine((data, ctx) => {
|
|
11
|
+
const hasTable = typeof data.table === 'string' && data.table.length > 0;
|
|
12
|
+
const hasTables = Array.isArray(data.tables) && data.tables.length > 0;
|
|
13
|
+
if (hasTable && hasTables) {
|
|
14
|
+
ctx.addIssue({
|
|
15
|
+
code: z.ZodIssueCode.custom,
|
|
16
|
+
message: "Provide either 'table' or 'tables', not both"
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
else if (!hasTable && !hasTables) {
|
|
20
|
+
ctx.addIssue({
|
|
21
|
+
code: z.ZodIssueCode.custom,
|
|
22
|
+
message: "Either 'table' or non-empty 'tables' must be provided"
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
export const inspectTableToolDefinition = {
|
|
27
|
+
name: 'inspect_table',
|
|
28
|
+
description: 'Get complete table schema including columns, types, constraints, and metadata. Supports multi-table inspection via the tables: string[] parameter.',
|
|
29
|
+
inputSchema: {
|
|
30
|
+
type: 'object',
|
|
31
|
+
properties: {
|
|
32
|
+
database: {
|
|
33
|
+
type: 'string',
|
|
34
|
+
description: 'Name of the database containing the table(s)'
|
|
35
|
+
},
|
|
36
|
+
table: {
|
|
37
|
+
type: 'string',
|
|
38
|
+
description: 'Name of the table to inspect (single-table mode)'
|
|
39
|
+
},
|
|
40
|
+
tables: {
|
|
41
|
+
type: 'array',
|
|
42
|
+
items: { type: 'string' },
|
|
43
|
+
description: 'Array of table names to inspect (multi-table mode)'
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
required: ['database']
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
export async function handleInspectTable(args, dbManager) {
|
|
50
|
+
try {
|
|
51
|
+
Logger.info('Executing inspect_table tool');
|
|
52
|
+
// Validate arguments
|
|
53
|
+
const validationResult = InspectTableArgsSchema.safeParse(args);
|
|
54
|
+
if (!validationResult.success) {
|
|
55
|
+
Logger.warn('Invalid arguments for inspect_table', validationResult.error);
|
|
56
|
+
throw new ToolError(`Invalid arguments: ${validationResult.error.issues.map(e => `${e.path.join('.')}: ${e.message}`).join(', ')}`, 'inspect_table');
|
|
57
|
+
}
|
|
58
|
+
const { database, table, tables } = validationResult.data;
|
|
59
|
+
// Sanitize database input
|
|
60
|
+
const sanitizedDatabase = InputValidator.sanitizeString(database);
|
|
61
|
+
// Validate database name format
|
|
62
|
+
const dbNameValidation = InputValidator.validateDatabaseName(sanitizedDatabase);
|
|
63
|
+
if (!dbNameValidation.isValid) {
|
|
64
|
+
throw new ToolError(`Invalid database name: ${dbNameValidation.error}`, 'inspect_table');
|
|
65
|
+
}
|
|
66
|
+
// Helper to process a single table
|
|
67
|
+
const processTable = async (tableName) => {
|
|
68
|
+
try {
|
|
69
|
+
const sanitizedTable = InputValidator.sanitizeString(tableName);
|
|
70
|
+
// Validate table name format
|
|
71
|
+
const tableNameValidation = InputValidator.validateTableName(sanitizedTable);
|
|
72
|
+
if (!tableNameValidation.isValid) {
|
|
73
|
+
throw new ToolError(`Invalid table name: ${tableNameValidation.error}`, 'inspect_table');
|
|
74
|
+
}
|
|
75
|
+
Logger.info(`Inspecting table: ${sanitizedDatabase}.${sanitizedTable}`);
|
|
76
|
+
Logger.time(`inspect_table_execution_${sanitizedTable}`);
|
|
77
|
+
// Get table schema
|
|
78
|
+
const columns = await dbManager.getTableSchema(sanitizedDatabase, sanitizedTable);
|
|
79
|
+
// Get additional metadata in parallel
|
|
80
|
+
const [foreignKeys, indexes] = await Promise.all([
|
|
81
|
+
dbManager.getForeignKeys(sanitizedDatabase, sanitizedTable),
|
|
82
|
+
dbManager.getIndexes(sanitizedDatabase, sanitizedTable)
|
|
83
|
+
]);
|
|
84
|
+
Logger.timeEnd(`inspect_table_execution_${sanitizedTable}`);
|
|
85
|
+
Logger.info(`Retrieved schema for table: ${sanitizedDatabase}.${sanitizedTable} with ${columns.length} columns`);
|
|
86
|
+
if (columns.length === 0) {
|
|
87
|
+
throw new ToolError(`Table '${sanitizedTable}' not found in database '${sanitizedDatabase}' or has no accessible columns`, 'inspect_table');
|
|
88
|
+
}
|
|
89
|
+
// Analyze schema patterns
|
|
90
|
+
const analysis = analyzeTableSchema(columns, indexes, foreignKeys);
|
|
91
|
+
// Group columns by characteristics
|
|
92
|
+
const columnsByType = groupColumnsByType(columns);
|
|
93
|
+
// Create comprehensive response
|
|
94
|
+
const response = {
|
|
95
|
+
database: sanitizedDatabase,
|
|
96
|
+
table: sanitizedTable,
|
|
97
|
+
columns: columns.map(col => ({
|
|
98
|
+
name: col.columnName,
|
|
99
|
+
dataType: col.dataType,
|
|
100
|
+
fullType: formatFullDataType(col),
|
|
101
|
+
nullable: col.isNullable === 'YES',
|
|
102
|
+
defaultValue: col.columnDefault,
|
|
103
|
+
isPrimaryKey: col.isPrimaryKey,
|
|
104
|
+
isAutoIncrement: col.isAutoIncrement,
|
|
105
|
+
comment: col.columnComment,
|
|
106
|
+
constraints: getColumnConstraints(col),
|
|
107
|
+
properties: {
|
|
108
|
+
hasLength: col.characterMaximumLength !== null && col.characterMaximumLength !== undefined,
|
|
109
|
+
hasPrecision: col.numericPrecision !== null && col.numericPrecision !== undefined,
|
|
110
|
+
hasScale: col.numericScale !== null && col.numericScale !== undefined
|
|
111
|
+
}
|
|
112
|
+
})),
|
|
113
|
+
constraints: {
|
|
114
|
+
primaryKey: columns.filter(col => col.isPrimaryKey).map(col => col.columnName),
|
|
115
|
+
foreignKeys: foreignKeys.map(fk => ({
|
|
116
|
+
constraintName: fk.constraintName,
|
|
117
|
+
columnName: fk.columnName,
|
|
118
|
+
referencedTable: fk.referencedTableName,
|
|
119
|
+
referencedColumn: fk.referencedColumnName,
|
|
120
|
+
updateRule: fk.updateRule,
|
|
121
|
+
deleteRule: fk.deleteRule
|
|
122
|
+
})),
|
|
123
|
+
unique: indexes.filter(idx => !idx.nonUnique && !idx.isPrimary)
|
|
124
|
+
.map(idx => idx.indexName)
|
|
125
|
+
.filter((value, index, self) => self.indexOf(value) === index) // Remove duplicates
|
|
126
|
+
},
|
|
127
|
+
indexes: groupIndexesByName(indexes),
|
|
128
|
+
statistics: {
|
|
129
|
+
totalColumns: columns.length,
|
|
130
|
+
nullableColumns: columns.filter(col => col.isNullable === 'YES').length,
|
|
131
|
+
primaryKeyColumns: columns.filter(col => col.isPrimaryKey).length,
|
|
132
|
+
autoIncrementColumns: columns.filter(col => col.isAutoIncrement).length,
|
|
133
|
+
indexedColumns: [...new Set(indexes.map(idx => idx.columnName))].length,
|
|
134
|
+
foreignKeyColumns: [...new Set(foreignKeys.map(fk => fk.columnName))].length,
|
|
135
|
+
totalIndexes: [...new Set(indexes.map(idx => idx.indexName))].length,
|
|
136
|
+
totalForeignKeys: foreignKeys.length
|
|
137
|
+
},
|
|
138
|
+
columnsByType,
|
|
139
|
+
analysis,
|
|
140
|
+
summary: {
|
|
141
|
+
description: `Table '${sanitizedTable}' has ${columns.length} columns with ${columns.filter(col => col.isPrimaryKey).length} primary key column(s) and ${indexes.length > 0 ? [...new Set(indexes.map(idx => idx.indexName))].length : 0} index(es)`,
|
|
142
|
+
recommendations: analysis.recommendations
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
Logger.debug('inspect_table completed successfully', {
|
|
146
|
+
database: sanitizedDatabase,
|
|
147
|
+
table: sanitizedTable,
|
|
148
|
+
columnCount: columns.length,
|
|
149
|
+
indexCount: indexes.length,
|
|
150
|
+
foreignKeyCount: foreignKeys.length
|
|
151
|
+
});
|
|
152
|
+
return { ok: true, result: response };
|
|
153
|
+
}
|
|
154
|
+
catch (err) {
|
|
155
|
+
Logger.error(`Error inspecting table '${tableName}'`, err);
|
|
156
|
+
return {
|
|
157
|
+
ok: false,
|
|
158
|
+
error: err instanceof ToolError
|
|
159
|
+
? err.message
|
|
160
|
+
: (err instanceof Error ? err.message : 'Unknown error')
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
// Multi-table support
|
|
165
|
+
if (Array.isArray(tables) && tables.length > 0) {
|
|
166
|
+
const results = {};
|
|
167
|
+
for (const t of tables) {
|
|
168
|
+
const res = await processTable(t);
|
|
169
|
+
if (res.ok) {
|
|
170
|
+
results[t] = res.result;
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
results[t] = { error: res.error };
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return {
|
|
177
|
+
content: [{
|
|
178
|
+
type: 'text',
|
|
179
|
+
text: JSON.stringify(results, null, 2)
|
|
180
|
+
}]
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
// Single-table fallback (backward compatible)
|
|
184
|
+
if (typeof table === 'string' && table.length > 0) {
|
|
185
|
+
const res = await processTable(table);
|
|
186
|
+
if (res.ok) {
|
|
187
|
+
return {
|
|
188
|
+
content: [{
|
|
189
|
+
type: 'text',
|
|
190
|
+
text: JSON.stringify(res.result, null, 2)
|
|
191
|
+
}]
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
throw new ToolError(`Failed to inspect table '${table}': ${res.error}`, 'inspect_table');
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// Should not reach here due to schema refinement
|
|
199
|
+
throw new ToolError("Either 'table' or non-empty 'tables' must be provided", 'inspect_table');
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
// Add table context to error logs
|
|
203
|
+
let tableContext;
|
|
204
|
+
let argTables;
|
|
205
|
+
let argTable;
|
|
206
|
+
if (args && typeof args === 'object') {
|
|
207
|
+
// @ts-ignore
|
|
208
|
+
argTables = Array.isArray(args.tables) ? args.tables : undefined;
|
|
209
|
+
// @ts-ignore
|
|
210
|
+
argTable = typeof args.table === 'string' ? args.table : undefined;
|
|
211
|
+
}
|
|
212
|
+
if (Array.isArray(argTables) && argTables.length > 0) {
|
|
213
|
+
tableContext = `tables: [${argTables.join(', ')}]`;
|
|
214
|
+
}
|
|
215
|
+
else if (typeof argTable === 'string' && argTable.length > 0) {
|
|
216
|
+
tableContext = `table: ${argTable}`;
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
tableContext = 'no table(s) specified';
|
|
220
|
+
}
|
|
221
|
+
Logger.error(`Error in inspect_table tool (${tableContext})`, error);
|
|
222
|
+
if (error instanceof ToolError) {
|
|
223
|
+
throw error;
|
|
224
|
+
}
|
|
225
|
+
throw new ToolError(`Failed to inspect table(s) (${tableContext}): ${error instanceof Error ? error.message : 'Unknown error'}`, 'inspect_table', error instanceof Error ? error : undefined);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
// Helper functions
|
|
229
|
+
function formatFullDataType(column) {
|
|
230
|
+
let type = column.dataType.toLowerCase();
|
|
231
|
+
if (column.characterMaximumLength !== null && column.characterMaximumLength !== undefined) {
|
|
232
|
+
type += `(${column.characterMaximumLength})`;
|
|
233
|
+
}
|
|
234
|
+
else if (column.numericPrecision !== null && column.numericPrecision !== undefined) {
|
|
235
|
+
if (column.numericScale !== null && column.numericScale !== undefined && column.numericScale > 0) {
|
|
236
|
+
type += `(${column.numericPrecision},${column.numericScale})`;
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
type += `(${column.numericPrecision})`;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return type;
|
|
243
|
+
}
|
|
244
|
+
function getColumnConstraints(column) {
|
|
245
|
+
const constraints = [];
|
|
246
|
+
if (column.isPrimaryKey)
|
|
247
|
+
constraints.push('PRIMARY KEY');
|
|
248
|
+
if (column.isAutoIncrement)
|
|
249
|
+
constraints.push('AUTO_INCREMENT');
|
|
250
|
+
if (column.isNullable === 'NO')
|
|
251
|
+
constraints.push('NOT NULL');
|
|
252
|
+
return constraints;
|
|
253
|
+
}
|
|
254
|
+
function groupColumnsByType(columns) {
|
|
255
|
+
const groups = {
|
|
256
|
+
numeric: [],
|
|
257
|
+
string: [],
|
|
258
|
+
datetime: [],
|
|
259
|
+
binary: [],
|
|
260
|
+
json: [],
|
|
261
|
+
other: []
|
|
262
|
+
};
|
|
263
|
+
columns.forEach(col => {
|
|
264
|
+
const type = col.dataType.toLowerCase();
|
|
265
|
+
if (['int', 'bigint', 'smallint', 'tinyint', 'mediumint', 'decimal', 'numeric', 'float', 'double', 'bit', 'real', 'serial'].some(t => type.includes(t))) {
|
|
266
|
+
groups.numeric.push(col.columnName);
|
|
267
|
+
}
|
|
268
|
+
else if (['varchar', 'char', 'text', 'longtext', 'mediumtext', 'tinytext', 'enum', 'set', 'uuid', 'inet', 'cidr', 'macaddr'].some(t => type.includes(t))) {
|
|
269
|
+
groups.string.push(col.columnName);
|
|
270
|
+
}
|
|
271
|
+
else if (['datetime', 'date', 'time', 'timestamp', 'year', 'interval'].some(t => type.includes(t))) {
|
|
272
|
+
groups.datetime.push(col.columnName);
|
|
273
|
+
}
|
|
274
|
+
else if (['binary', 'varbinary', 'blob', 'longblob', 'mediumblob', 'tinyblob', 'bytea'].some(t => type.includes(t))) {
|
|
275
|
+
groups.binary.push(col.columnName);
|
|
276
|
+
}
|
|
277
|
+
else if (type === 'json' || type === 'jsonb') {
|
|
278
|
+
groups.json.push(col.columnName);
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
groups.other.push(col.columnName);
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
// Remove empty groups
|
|
285
|
+
Object.keys(groups).forEach(key => {
|
|
286
|
+
if (groups[key].length === 0) {
|
|
287
|
+
delete groups[key];
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
return groups;
|
|
291
|
+
}
|
|
292
|
+
function groupIndexesByName(indexes) {
|
|
293
|
+
const indexGroups = {};
|
|
294
|
+
indexes.forEach(idx => {
|
|
295
|
+
if (!indexGroups[idx.indexName]) {
|
|
296
|
+
indexGroups[idx.indexName] = {
|
|
297
|
+
name: idx.indexName,
|
|
298
|
+
type: idx.indexType,
|
|
299
|
+
unique: !idx.nonUnique,
|
|
300
|
+
columns: []
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
indexGroups[idx.indexName].columns.push({
|
|
304
|
+
name: idx.columnName,
|
|
305
|
+
cardinality: idx.cardinality,
|
|
306
|
+
subPart: idx.subPart
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
return Object.values(indexGroups);
|
|
310
|
+
}
|
|
311
|
+
function analyzeTableSchema(columns, indexes, foreignKeys) {
|
|
312
|
+
const recommendations = [];
|
|
313
|
+
const patterns = [];
|
|
314
|
+
// Check for common patterns
|
|
315
|
+
const hasId = columns.some(col => col.columnName.toLowerCase() === 'id');
|
|
316
|
+
const hasCreatedAt = columns.some(col => col.columnName.toLowerCase().includes('created'));
|
|
317
|
+
const hasUpdatedAt = columns.some(col => col.columnName.toLowerCase().includes('updated'));
|
|
318
|
+
if (hasId && hasCreatedAt && hasUpdatedAt) {
|
|
319
|
+
patterns.push('Standard entity pattern (id, created_at, updated_at)');
|
|
320
|
+
}
|
|
321
|
+
// Check for missing primary key
|
|
322
|
+
const hasPrimaryKey = columns.some(col => col.isPrimaryKey);
|
|
323
|
+
if (!hasPrimaryKey) {
|
|
324
|
+
recommendations.push('Consider adding a primary key for better performance and replication');
|
|
325
|
+
}
|
|
326
|
+
// Check for missing indexes on foreign key columns
|
|
327
|
+
const fkColumns = new Set(foreignKeys.map(fk => fk.columnName));
|
|
328
|
+
const indexedColumns = new Set(indexes.map(idx => idx.columnName));
|
|
329
|
+
fkColumns.forEach(fkCol => {
|
|
330
|
+
if (!indexedColumns.has(fkCol)) {
|
|
331
|
+
recommendations.push(`Consider adding an index on foreign key column '${fkCol}' for better join performance`);
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
// Check for very wide tables
|
|
335
|
+
if (columns.length > 50) {
|
|
336
|
+
recommendations.push('Table has many columns. Consider normalization or vertical partitioning');
|
|
337
|
+
}
|
|
338
|
+
// Check for nullable primary key (should not happen but good to check)
|
|
339
|
+
const nullablePK = columns.find(col => col.isPrimaryKey && col.isNullable === 'YES');
|
|
340
|
+
if (nullablePK) {
|
|
341
|
+
recommendations.push(`Primary key column '${nullablePK.columnName}' should not be nullable`);
|
|
342
|
+
}
|
|
343
|
+
return {
|
|
344
|
+
patterns,
|
|
345
|
+
recommendations,
|
|
346
|
+
hasStandardAuditFields: hasCreatedAt && hasUpdatedAt,
|
|
347
|
+
hasAutoIncrementPK: columns.some(col => col.isPrimaryKey && col.isAutoIncrement),
|
|
348
|
+
isWellIndexed: fkColumns.size === 0 || Array.from(fkColumns).every(col => indexedColumns.has(col))
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
//# sourceMappingURL=inspect-table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspect-table.js","sourceRoot":"","sources":["../../src/tools/inspect-table.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { DatabaseManager } from '../database/manager.js';
|
|
2
|
+
export interface ListDatabasesTool {
|
|
3
|
+
name: 'list_databases';
|
|
4
|
+
description: 'List all connected database names with connection status';
|
|
5
|
+
inputSchema: {
|
|
6
|
+
type: 'object';
|
|
7
|
+
properties: {};
|
|
8
|
+
required: never[];
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export declare const listDatabasesToolDefinition: ListDatabasesTool;
|
|
12
|
+
export declare function handleListDatabases(args: unknown, dbManager: DatabaseManager): Promise<any>;
|
|
13
|
+
export declare function getListDatabasesSummary(dbManager: DatabaseManager): string;
|
|
14
|
+
//# sourceMappingURL=list-databases.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-databases.d.ts","sourceRoot":"","sources":["../../src/tools/list-databases.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAOzD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,gBAAgB,CAAC;IACvB,WAAW,EAAE,0DAA0D,CAAC;IACxE,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,EAAE,CAAC;QACf,QAAQ,EAAE,KAAK,EAAE,CAAC;KACnB,CAAC;CACH;AAED,eAAO,MAAM,2BAA2B,EAAE,iBAQzC,CAAC;AAEF,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,OAAO,EACb,SAAS,EAAE,eAAe,GACzB,OAAO,CAAC,GAAG,CAAC,CAqEd;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,eAAe,GAAG,MAAM,CAgB1E"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { Logger } from '../utils/logger.js';
|
|
3
|
+
import { ToolError } from '../utils/errors.js';
|
|
4
|
+
// Tool schema - no input required
|
|
5
|
+
const ListDatabasesArgsSchema = z.object({});
|
|
6
|
+
export const listDatabasesToolDefinition = {
|
|
7
|
+
name: 'list_databases',
|
|
8
|
+
description: 'List all connected database names with connection status',
|
|
9
|
+
inputSchema: {
|
|
10
|
+
type: 'object',
|
|
11
|
+
properties: {},
|
|
12
|
+
required: []
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
export async function handleListDatabases(args, dbManager) {
|
|
16
|
+
try {
|
|
17
|
+
Logger.info('Executing list_databases tool');
|
|
18
|
+
// Validate arguments (should be empty object)
|
|
19
|
+
const validationResult = ListDatabasesArgsSchema.safeParse(args);
|
|
20
|
+
if (!validationResult.success) {
|
|
21
|
+
Logger.warn('Invalid arguments for list_databases', validationResult.error);
|
|
22
|
+
throw new ToolError(`Invalid arguments: ${validationResult.error.issues.map(e => e.message).join(', ')}`, 'list_databases');
|
|
23
|
+
}
|
|
24
|
+
Logger.time('list_databases_execution');
|
|
25
|
+
// Get database list from manager
|
|
26
|
+
const databases = dbManager.listDatabases();
|
|
27
|
+
Logger.timeEnd('list_databases_execution');
|
|
28
|
+
Logger.info(`Found ${databases.length} configured databases`);
|
|
29
|
+
// Format response with detailed information
|
|
30
|
+
const response = {
|
|
31
|
+
databases: databases.map(db => ({
|
|
32
|
+
name: db.name,
|
|
33
|
+
type: db.type,
|
|
34
|
+
host: db.host,
|
|
35
|
+
database: db.database,
|
|
36
|
+
connected: db.connected,
|
|
37
|
+
lastUsed: db.lastUsed.toISOString(),
|
|
38
|
+
connectionStatus: db.connected ? 'active' : 'disconnected'
|
|
39
|
+
})),
|
|
40
|
+
totalCount: databases.length,
|
|
41
|
+
connectedCount: databases.filter(db => db.connected).length,
|
|
42
|
+
summary: {
|
|
43
|
+
hasConnectedDatabases: databases.length > 0,
|
|
44
|
+
allConnected: databases.every(db => db.connected),
|
|
45
|
+
message: databases.length === 0
|
|
46
|
+
? 'No databases configured. Add database connections first.'
|
|
47
|
+
: `Found ${databases.length} database(s), ${databases.filter(db => db.connected).length} connected.`
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
Logger.debug('list_databases completed successfully', {
|
|
51
|
+
totalDatabases: response.totalCount,
|
|
52
|
+
connectedCount: response.connectedCount
|
|
53
|
+
});
|
|
54
|
+
return {
|
|
55
|
+
content: [{
|
|
56
|
+
type: 'text',
|
|
57
|
+
text: JSON.stringify(response, null, 2)
|
|
58
|
+
}]
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
Logger.error('Error in list_databases tool', error);
|
|
63
|
+
if (error instanceof ToolError) {
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
throw new ToolError(`Failed to list databases: ${error instanceof Error ? error.message : 'Unknown error'}`, 'list_databases', error instanceof Error ? error : undefined);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export function getListDatabasesSummary(dbManager) {
|
|
70
|
+
try {
|
|
71
|
+
const databases = dbManager.listDatabases();
|
|
72
|
+
const connectedCount = databases.filter(db => db.connected).length;
|
|
73
|
+
if (databases.length === 0) {
|
|
74
|
+
return 'No databases configured';
|
|
75
|
+
}
|
|
76
|
+
return `${databases.length} database(s) configured, ${connectedCount} connected: ${databases.map(db => `${db.name} (${db.connected ? 'connected' : 'disconnected'})`).join(', ')}`;
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
Logger.error('Error getting database summary', error);
|
|
80
|
+
return 'Error retrieving database information';
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=list-databases.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-databases.js","sourceRoot":"","sources":["../../src/tools/list-databases.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { DatabaseManager } from '../database/manager.js';
|
|
2
|
+
export interface ListTablesTool {
|
|
3
|
+
name: 'list_tables';
|
|
4
|
+
description: 'List all tables in the specified database with metadata';
|
|
5
|
+
inputSchema: {
|
|
6
|
+
type: 'object';
|
|
7
|
+
properties: {
|
|
8
|
+
database: {
|
|
9
|
+
type: 'string';
|
|
10
|
+
description: 'Name of the database to list tables from';
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
required: ['database'];
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export declare const listTablesToolDefinition: ListTablesTool;
|
|
17
|
+
export declare function handleListTables(args: unknown, dbManager: DatabaseManager): Promise<any>;
|
|
18
|
+
export declare function getTablesSummary(dbManager: DatabaseManager, database: string): Promise<string>;
|
|
19
|
+
//# sourceMappingURL=list-tables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-tables.d.ts","sourceRoot":"","sources":["../../src/tools/list-tables.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAUzD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,aAAa,CAAC;IACpB,WAAW,EAAE,yDAAyD,CAAC;IACvE,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE;YACV,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ,CAAC;gBACf,WAAW,EAAE,0CAA0C,CAAC;aACzD,CAAC;SACH,CAAC;QACF,QAAQ,EAAE,CAAC,UAAU,CAAC,CAAC;KACxB,CAAC;CACH;AAED,eAAO,MAAM,wBAAwB,EAAE,cAatC,CAAC;AAEF,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,OAAO,EACb,SAAS,EAAE,eAAe,GACzB,OAAO,CAAC,GAAG,CAAC,CA8Gd;AAED,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,eAAe,EAC1B,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAqBjB"}
|