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.
Files changed (105) hide show
  1. package/README.md +197 -0
  2. package/dist/database/connection.d.ts +13 -0
  3. package/dist/database/connection.d.ts.map +1 -0
  4. package/dist/database/connection.js +155 -0
  5. package/dist/database/connection.js.map +1 -0
  6. package/dist/database/manager.d.ts +28 -0
  7. package/dist/database/manager.d.ts.map +1 -0
  8. package/dist/database/manager.js +621 -0
  9. package/dist/database/manager.js.map +1 -0
  10. package/dist/database/postgres-connection.d.ts +10 -0
  11. package/dist/database/postgres-connection.d.ts.map +1 -0
  12. package/dist/database/postgres-connection.js +113 -0
  13. package/dist/database/postgres-connection.js.map +1 -0
  14. package/dist/database/types.d.ts +84 -0
  15. package/dist/database/types.d.ts.map +1 -0
  16. package/dist/database/types.js +6 -0
  17. package/dist/database/types.js.map +1 -0
  18. package/dist/index.d.ts +2 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +120 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/server.d.ts +14 -0
  23. package/dist/server.d.ts.map +1 -0
  24. package/dist/server.js +186 -0
  25. package/dist/server.js.map +1 -0
  26. package/dist/test-defaults.d.ts +2 -0
  27. package/dist/test-defaults.d.ts.map +1 -0
  28. package/dist/test-defaults.js +57 -0
  29. package/dist/test-defaults.js.map +1 -0
  30. package/dist/tools/analyze-query.d.ts +27 -0
  31. package/dist/tools/analyze-query.d.ts.map +1 -0
  32. package/dist/tools/analyze-query.js +71 -0
  33. package/dist/tools/analyze-query.js.map +1 -0
  34. package/dist/tools/execute-query.d.ts +33 -0
  35. package/dist/tools/execute-query.d.ts.map +1 -0
  36. package/dist/tools/execute-query.js +57 -0
  37. package/dist/tools/execute-query.js.map +1 -0
  38. package/dist/tools/get-foreign-keys.d.ts +38 -0
  39. package/dist/tools/get-foreign-keys.d.ts.map +1 -0
  40. package/dist/tools/get-foreign-keys.js +391 -0
  41. package/dist/tools/get-foreign-keys.js.map +1 -0
  42. package/dist/tools/get-indexes.d.ts +38 -0
  43. package/dist/tools/get-indexes.d.ts.map +1 -0
  44. package/dist/tools/get-indexes.js +472 -0
  45. package/dist/tools/get-indexes.js.map +1 -0
  46. package/dist/tools/information-schema-query.d.ts +33 -0
  47. package/dist/tools/information-schema-query.d.ts.map +1 -0
  48. package/dist/tools/information-schema-query.js +76 -0
  49. package/dist/tools/information-schema-query.js.map +1 -0
  50. package/dist/tools/inspect-table.d.ts +38 -0
  51. package/dist/tools/inspect-table.d.ts.map +1 -0
  52. package/dist/tools/inspect-table.js +351 -0
  53. package/dist/tools/inspect-table.js.map +1 -0
  54. package/dist/tools/list-databases.d.ts +14 -0
  55. package/dist/tools/list-databases.d.ts.map +1 -0
  56. package/dist/tools/list-databases.js +83 -0
  57. package/dist/tools/list-databases.js.map +1 -0
  58. package/dist/tools/list-tables.d.ts +19 -0
  59. package/dist/tools/list-tables.d.ts.map +1 -0
  60. package/dist/tools/list-tables.js +130 -0
  61. package/dist/tools/list-tables.js.map +1 -0
  62. package/dist/utils/errors.d.ts +32 -0
  63. package/dist/utils/errors.d.ts.map +1 -0
  64. package/dist/utils/errors.js +98 -0
  65. package/dist/utils/errors.js.map +1 -0
  66. package/dist/utils/logger.d.ts +28 -0
  67. package/dist/utils/logger.d.ts.map +1 -0
  68. package/dist/utils/logger.js +132 -0
  69. package/dist/utils/logger.js.map +1 -0
  70. package/dist/validators/input-validator.d.ts +76 -0
  71. package/dist/validators/input-validator.d.ts.map +1 -0
  72. package/dist/validators/input-validator.js +295 -0
  73. package/dist/validators/input-validator.js.map +1 -0
  74. package/dist/validators/query-validator.d.ts +19 -0
  75. package/dist/validators/query-validator.d.ts.map +1 -0
  76. package/dist/validators/query-validator.js +229 -0
  77. package/dist/validators/query-validator.js.map +1 -0
  78. package/enhanced_sql_prompt.md +324 -0
  79. package/examples/claude-config.json +23 -0
  80. package/examples/roo-config.json +16 -0
  81. package/package.json +42 -0
  82. package/src/database/connection.ts +165 -0
  83. package/src/database/manager.ts +682 -0
  84. package/src/database/postgres-connection.ts +123 -0
  85. package/src/database/types.ts +93 -0
  86. package/src/index.ts +136 -0
  87. package/src/server.ts +254 -0
  88. package/src/test-defaults.ts +63 -0
  89. package/src/tools/analyze-query.test.ts +100 -0
  90. package/src/tools/analyze-query.ts +112 -0
  91. package/src/tools/execute-query.ts +91 -0
  92. package/src/tools/get-foreign-keys.test.ts +51 -0
  93. package/src/tools/get-foreign-keys.ts +488 -0
  94. package/src/tools/get-indexes.test.ts +51 -0
  95. package/src/tools/get-indexes.ts +570 -0
  96. package/src/tools/information-schema-query.ts +125 -0
  97. package/src/tools/inspect-table.test.ts +59 -0
  98. package/src/tools/inspect-table.ts +440 -0
  99. package/src/tools/list-databases.ts +119 -0
  100. package/src/tools/list-tables.ts +181 -0
  101. package/src/utils/errors.ts +103 -0
  102. package/src/utils/logger.ts +158 -0
  103. package/src/validators/input-validator.ts +318 -0
  104. package/src/validators/query-validator.ts +267 -0
  105. package/tsconfig.json +30 -0
@@ -0,0 +1,113 @@
1
+ import pg from 'pg';
2
+ import { URL } from 'url';
3
+ import { DatabaseType } from './types.js';
4
+ import { Logger } from '../utils/logger.js';
5
+ import { DatabaseError } from '../utils/errors.js';
6
+ export class PostgresConnection {
7
+ static parseConnectionUrl(url) {
8
+ try {
9
+ const parsedUrl = new URL(url);
10
+ if (parsedUrl.protocol !== 'postgresql:' && parsedUrl.protocol !== 'postgres:') {
11
+ throw new DatabaseError(`Unsupported protocol: ${parsedUrl.protocol}. Only 'postgresql:' or 'postgres:' is supported.`);
12
+ }
13
+ const options = {
14
+ type: DatabaseType.PostgreSQL,
15
+ host: parsedUrl.hostname,
16
+ port: parsedUrl.port ? parseInt(parsedUrl.port) : 5432,
17
+ user: parsedUrl.username,
18
+ password: parsedUrl.password,
19
+ database: parsedUrl.pathname.slice(1), // Remove leading slash
20
+ reconnect: true
21
+ };
22
+ // Parse SSL settings from query parameters
23
+ const searchParams = parsedUrl.searchParams;
24
+ if (searchParams.has('ssl')) {
25
+ const sslValue = searchParams.get('ssl');
26
+ if (sslValue === 'true' || sslValue === '1') {
27
+ options.ssl = true;
28
+ }
29
+ else if (sslValue === 'false' || sslValue === '0') {
30
+ options.ssl = false;
31
+ }
32
+ else if (sslValue === 'no-verify') {
33
+ options.ssl = { rejectUnauthorized: false };
34
+ }
35
+ }
36
+ return options;
37
+ }
38
+ catch (error) {
39
+ throw new DatabaseError(`Invalid connection URL: ${error instanceof Error ? error.message : 'Unknown error'}`);
40
+ }
41
+ }
42
+ static async createClient(options) {
43
+ try {
44
+ Logger.info(`Connecting to PostgreSQL database at ${options.host}:${options.port}/${options.database}`);
45
+ const clientConfig = {
46
+ host: options.host,
47
+ port: options.port,
48
+ user: options.user,
49
+ password: options.password,
50
+ database: options.database,
51
+ };
52
+ if (options.ssl) {
53
+ clientConfig.ssl = options.ssl;
54
+ }
55
+ const client = new pg.Client(clientConfig);
56
+ await client.connect();
57
+ // Test the connection
58
+ await client.query('SELECT 1');
59
+ Logger.info(`Successfully connected to PostgreSQL database: ${options.database}`);
60
+ return client;
61
+ }
62
+ catch (error) {
63
+ Logger.error(`Failed to connect to PostgreSQL database: ${error instanceof Error ? error.message : 'Unknown error'}`);
64
+ throw new DatabaseError(`Connection failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
65
+ }
66
+ }
67
+ static async executeQuery(client, query, params) {
68
+ try {
69
+ Logger.debug(`Executing PostgreSQL query: ${query.substring(0, 100)}${query.length > 100 ? '...' : ''}`);
70
+ // PostgreSQL uses $1, $2 for parameters, but if we receive ? from MySQL style queries
71
+ // we might need translation, but for now we expect raw compatibility or manual handling
72
+ const res = await client.query(query, params);
73
+ const result = {
74
+ rows: res.rows,
75
+ fields: res.fields.map((f) => ({ name: f.name, type: f.dataTypeID })),
76
+ };
77
+ Logger.debug(`Query executed successfully, returned ${result.rows.length} rows`);
78
+ return result;
79
+ }
80
+ catch (error) {
81
+ Logger.error(`PostgreSQL query execution failed: ${error instanceof Error ? error.message : 'Unknown error'}\n` +
82
+ `Full SQL: ${query}\n` +
83
+ `Params: ${JSON.stringify(params)}`);
84
+ throw new DatabaseError(`Query execution failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
85
+ }
86
+ }
87
+ static async closeConnection(client) {
88
+ try {
89
+ await client.end();
90
+ Logger.info('PostgreSQL connection closed successfully');
91
+ }
92
+ catch (error) {
93
+ Logger.warn(`Error closing PostgreSQL connection: ${error instanceof Error ? error.message : 'Unknown error'}`);
94
+ }
95
+ }
96
+ static async testConnection(options) {
97
+ let client = null;
98
+ try {
99
+ client = await this.createClient(options);
100
+ return true;
101
+ }
102
+ catch (error) {
103
+ Logger.warn(`PostgreSQL connection test failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
104
+ return false;
105
+ }
106
+ finally {
107
+ if (client) {
108
+ await this.closeConnection(client);
109
+ }
110
+ }
111
+ }
112
+ }
113
+ //# sourceMappingURL=postgres-connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-connection.js","sourceRoot":"","sources":["../../src/database/postgres-connection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ export declare enum DatabaseType {
2
+ MySQL = "mysql",
3
+ PostgreSQL = "postgresql"
4
+ }
5
+ export interface DatabaseConfig {
6
+ name: string;
7
+ url: string;
8
+ type: DatabaseType;
9
+ connection: any | null;
10
+ lastUsed: Date;
11
+ host: string;
12
+ port: number;
13
+ username: string;
14
+ password?: string;
15
+ database: string;
16
+ ssl?: boolean | any;
17
+ }
18
+ export interface DatabaseInfo {
19
+ name: string;
20
+ type: DatabaseType;
21
+ connected: boolean;
22
+ lastUsed: Date;
23
+ host: string;
24
+ database: string;
25
+ }
26
+ export interface TableInfo {
27
+ tableName: string;
28
+ tableType: string;
29
+ engine?: string;
30
+ tableRows?: number;
31
+ tableComment?: string;
32
+ }
33
+ export interface ColumnInfo {
34
+ columnName: string;
35
+ dataType: string;
36
+ isNullable: string;
37
+ columnDefault?: any;
38
+ isPrimaryKey: boolean;
39
+ isAutoIncrement: boolean;
40
+ columnComment?: string;
41
+ characterMaximumLength?: number;
42
+ numericPrecision?: number;
43
+ numericScale?: number;
44
+ }
45
+ export interface ForeignKeyInfo {
46
+ constraintName: string;
47
+ tableName: string;
48
+ columnName: string;
49
+ referencedTableName: string;
50
+ referencedColumnName: string;
51
+ updateRule?: string;
52
+ deleteRule?: string;
53
+ }
54
+ export interface IndexInfo {
55
+ tableName: string;
56
+ indexName: string;
57
+ columnName: string;
58
+ nonUnique: boolean;
59
+ indexType?: string;
60
+ cardinality?: number;
61
+ subPart?: number;
62
+ nullable: boolean;
63
+ isPrimary?: boolean;
64
+ }
65
+ export interface QueryResult {
66
+ rows: any[];
67
+ fields: any[];
68
+ }
69
+ export interface ValidationResult {
70
+ isValid: boolean;
71
+ error?: string;
72
+ warnings?: string[];
73
+ }
74
+ export interface DatabaseConnectionOptions {
75
+ type: DatabaseType;
76
+ host: string;
77
+ port: number;
78
+ user: string;
79
+ password: string;
80
+ database: string;
81
+ ssl?: boolean | object;
82
+ reconnect?: boolean;
83
+ }
84
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/database/types.ts"],"names":[],"mappings":"AAAA,oBAAY,YAAY;IACtB,KAAK,UAAU;IACf,UAAU,eAAe;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,YAAY,CAAC;IACnB,UAAU,EAAE,GAAG,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,IAAI,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,GAAG,GAAG,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,YAAY,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,IAAI,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,GAAG,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,MAAM,EAAE,GAAG,EAAE,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAEvB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB"}
@@ -0,0 +1,6 @@
1
+ export var DatabaseType;
2
+ (function (DatabaseType) {
3
+ DatabaseType["MySQL"] = "mysql";
4
+ DatabaseType["PostgreSQL"] = "postgresql";
5
+ })(DatabaseType || (DatabaseType = {}));
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/database/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,YAGX;AAHD,WAAY,YAAY;IACtB,+BAAe,CAAA;IACf,yCAAyB,CAAA;AAC3B,CAAC,EAHW,YAAY,KAAZ,YAAY,QAGvB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,120 @@
1
+ import { DatabaseInspectorServer } from './server.js';
2
+ import { Logger } from './utils/logger.js';
3
+ import { InputValidator } from './validators/input-validator.js';
4
+ async function main() {
5
+ try {
6
+ // Parse command line arguments
7
+ const args = process.argv.slice(2);
8
+ if (args.length === 0) {
9
+ console.error(`
10
+ Usage: mcp-database-inspector <database_url1> [database_url2] [database_url3] ...
11
+
12
+ Examples:
13
+ # Single MySQL database
14
+ mcp-database-inspector "mysql://user:password@localhost:3306/mydb"
15
+
16
+ # Single PostgreSQL database
17
+ mcp-database-inspector "postgresql://user:password@localhost:5432/mydb"
18
+
19
+ # Mixed databases
20
+ mcp-database-inspector \\
21
+ "mysql://user:pass@mysql-host:3306/orders" \\
22
+ "postgresql://user:pass@pg-host:5432/analytics"
23
+
24
+ # With SSL
25
+ mcp-database-inspector "mysql://user:pass@localhost:3306/db?ssl=true"
26
+
27
+ Environment Variables:
28
+ LOG_LEVEL - Set logging level (error, warn, info, debug, trace)
29
+ Default: info
30
+
31
+ Database URL Format:
32
+ mysql://username:password@hostname:port/database?options
33
+ postgresql://username:password@hostname:port/database?options
34
+
35
+ Supported Options:
36
+ - ssl=true/false - Enable/disable SSL connection
37
+ - timeout=30 - Connection timeout in seconds (default: 30)
38
+ `);
39
+ process.exit(1);
40
+ }
41
+ // Set log level from environment
42
+ const logLevel = process.env.LOG_LEVEL?.toLowerCase();
43
+ if (logLevel && ['error', 'warn', 'info', 'debug', 'trace'].includes(logLevel)) {
44
+ Logger.setLogLevel(logLevel);
45
+ }
46
+ Logger.info('MCP Database Inspector starting...');
47
+ Logger.info(`Log level: ${Logger.getLogLevel()}`);
48
+ // Validate connection URLs
49
+ const connectionUrls = [];
50
+ for (const url of args) {
51
+ Logger.debug(`Validating connection URL: ${InputValidator.sanitizeForLogging(url)}`);
52
+ const validation = InputValidator.validateConnectionUrl(url);
53
+ if (!validation.isValid) {
54
+ Logger.error(`Invalid connection URL: ${validation.error}`);
55
+ console.error(`Error: Invalid connection URL - ${validation.error}`);
56
+ process.exit(1);
57
+ }
58
+ connectionUrls.push(url);
59
+ Logger.debug(`Connection URL validated successfully`);
60
+ }
61
+ Logger.info(`Validated ${connectionUrls.length} connection URL(s)`);
62
+ // Create and initialize server
63
+ const server = new DatabaseInspectorServer();
64
+ // Set up graceful shutdown
65
+ let isShuttingDown = false;
66
+ const shutdownHandler = async () => {
67
+ if (isShuttingDown)
68
+ return;
69
+ isShuttingDown = true;
70
+ Logger.info('Shutting down...');
71
+ try {
72
+ await server.shutdown();
73
+ }
74
+ catch (error) {
75
+ Logger.error('Error during shutdown:', error);
76
+ }
77
+ process.exit(0);
78
+ };
79
+ process.on('SIGINT', shutdownHandler);
80
+ process.on('SIGTERM', shutdownHandler);
81
+ // Initialize with database connections
82
+ Logger.info('Initializing database connections...');
83
+ await server.initialize(connectionUrls);
84
+ // Get server info for logging
85
+ const serverInfo = await server.getServerInfo();
86
+ Logger.info('Server initialization complete', {
87
+ connectedDatabases: serverInfo.connectedDatabases,
88
+ databases: serverInfo.databases.map((db) => db.name),
89
+ status: serverInfo.status
90
+ });
91
+ // Start the server
92
+ await server.run();
93
+ // This point should not be reached as the server runs indefinitely
94
+ Logger.warn('Server.run() returned unexpectedly');
95
+ }
96
+ catch (error) {
97
+ Logger.error('Fatal error during startup:', error);
98
+ console.error(`Fatal error: ${error instanceof Error ? error.message : 'Unknown error'}`);
99
+ process.exit(1);
100
+ }
101
+ }
102
+ // Handle unhandled promise rejections
103
+ process.on('unhandledRejection', (reason, promise) => {
104
+ Logger.error('Unhandled Promise Rejection:', { promise, reason });
105
+ console.error('Unhandled Promise Rejection:', reason);
106
+ process.exit(1);
107
+ });
108
+ // Handle uncaught exceptions
109
+ process.on('uncaughtException', (error) => {
110
+ Logger.error('Uncaught Exception:', error);
111
+ console.error('Uncaught Exception:', error.message);
112
+ process.exit(1);
113
+ });
114
+ // Start the application
115
+ main().catch((error) => {
116
+ Logger.error('Error in main function:', error);
117
+ console.error('Startup error:', error.message);
118
+ process.exit(1);
119
+ });
120
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEjE,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC;QACH,+BAA+B;QAC/B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAEnC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BnB,CAAC,CAAC;YACG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,iCAAiC;QACjC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,CAAC;QACtD,IAAI,QAAQ,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC/E,MAAM,CAAC,WAAW,CAAC,QAAe,CAAC,CAAC;QACtC,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;QAClD,MAAM,CAAC,IAAI,CAAC,cAAc,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAElD,2BAA2B;QAC3B,MAAM,cAAc,GAAa,EAAE,CAAC;QACpC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,CAAC,KAAK,CAAC,8BAA8B,cAAc,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAErF,MAAM,UAAU,GAAG,cAAc,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC;YAC7D,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;gBACxB,MAAM,CAAC,KAAK,CAAC,2BAA2B,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;gBAC5D,OAAO,CAAC,KAAK,CAAC,mCAAmC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;gBACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACzB,MAAM,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;QACxD,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,aAAa,cAAc,CAAC,MAAM,oBAAoB,CAAC,CAAC;QAEpE,+BAA+B;QAC/B,MAAM,MAAM,GAAG,IAAI,uBAAuB,EAAE,CAAC;QAE7C,2BAA2B;QAC3B,IAAI,cAAc,GAAG,KAAK,CAAC;QAC3B,MAAM,eAAe,GAAG,KAAK,IAAI,EAAE;YACjC,IAAI,cAAc;gBAAE,OAAO;YAC3B,cAAc,GAAG,IAAI,CAAC;YAEtB,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YAChC,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;YAC1B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;YAChD,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC;QAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;QACtC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;QAEvC,uCAAuC;QACvC,MAAM,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;QACpD,MAAM,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;QAExC,8BAA8B;QAC9B,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,aAAa,EAAE,CAAC;QAChD,MAAM,CAAC,IAAI,CAAC,gCAAgC,EAAE;YAC5C,kBAAkB,EAAE,UAAU,CAAC,kBAAkB;YACjD,SAAS,EAAE,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAO,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;YACzD,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;QAEH,mBAAmB;QACnB,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC;QAEnB,mEAAmE;QACnE,MAAM,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;IAEpD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;QACnD,OAAO,CAAC,KAAK,CAAC,gBAAgB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC;QAC1F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,sCAAsC;AACtC,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE;IACnD,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IAClE,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,MAAM,CAAC,CAAC;IACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,6BAA6B;AAC7B,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,KAAK,EAAE,EAAE;IACxC,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;IAC3C,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,wBAAwB;AACxB,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;IAC/C,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { DatabaseManager } from './database/manager.js';
2
+ export declare class DatabaseInspectorServer {
3
+ private server;
4
+ private dbManager;
5
+ constructor();
6
+ private setupHandlers;
7
+ initialize(connectionUrls: string[]): Promise<void>;
8
+ run(): Promise<void>;
9
+ shutdown(): Promise<void>;
10
+ getDatabaseManager(): DatabaseManager;
11
+ getServerInfo(): Promise<any>;
12
+ }
13
+ export default DatabaseInspectorServer;
14
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAyCxD,qBAAa,uBAAuB;IAClC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAkB;;IAmBnC,OAAO,CAAC,aAAa;IA6Ef,UAAU,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA6BnD,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IASpB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAc/B,kBAAkB,IAAI,eAAe;IAI/B,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC;CA2BpC;AAwBD,eAAe,uBAAuB,CAAC"}
package/dist/server.js ADDED
@@ -0,0 +1,186 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
4
+ import { DatabaseManager } from './database/manager.js';
5
+ import { Logger } from './utils/logger.js';
6
+ import { createErrorResponse, ToolError } from './utils/errors.js';
7
+ // Import tool handlers
8
+ import { listDatabasesToolDefinition, handleListDatabases } from './tools/list-databases.js';
9
+ import { listTablesToolDefinition, handleListTables } from './tools/list-tables.js';
10
+ import { inspectTableToolDefinition, handleInspectTable } from './tools/inspect-table.js';
11
+ import { getForeignKeysToolDefinition, handleGetForeignKeys } from './tools/get-foreign-keys.js';
12
+ import { getIndexesToolDefinition, handleGetIndexes } from './tools/get-indexes.js';
13
+ import { informationSchemaQueryToolDefinition, handleInformationSchemaQuery } from './tools/information-schema-query.js';
14
+ import { executeQueryToolDefinition, handleExecuteQuery } from './tools/execute-query.js';
15
+ import { analyzeQueryToolDefinition, handleAnalyzeQuery } from './tools/analyze-query.js';
16
+ export class DatabaseInspectorServer {
17
+ server;
18
+ dbManager;
19
+ constructor() {
20
+ this.server = new Server({
21
+ name: 'mcp-database-inspector',
22
+ version: '2.0.1',
23
+ }, {
24
+ capabilities: {
25
+ tools: {},
26
+ },
27
+ });
28
+ this.dbManager = new DatabaseManager();
29
+ this.setupHandlers();
30
+ }
31
+ setupHandlers() {
32
+ // List available tools
33
+ this.server.setRequestHandler(ListToolsRequestSchema, async () => {
34
+ Logger.debug('Received list_tools request');
35
+ return {
36
+ tools: [
37
+ listDatabasesToolDefinition,
38
+ listTablesToolDefinition,
39
+ inspectTableToolDefinition,
40
+ getForeignKeysToolDefinition,
41
+ getIndexesToolDefinition,
42
+ informationSchemaQueryToolDefinition,
43
+ executeQueryToolDefinition,
44
+ analyzeQueryToolDefinition
45
+ ]
46
+ };
47
+ });
48
+ // Handle tool calls
49
+ this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
50
+ const { name, arguments: args } = request.params;
51
+ Logger.info(`Received tool call: ${name}`);
52
+ Logger.debug(`Tool arguments:`, args);
53
+ try {
54
+ switch (name) {
55
+ case 'list_databases':
56
+ return await handleListDatabases(args, this.dbManager);
57
+ case 'list_tables':
58
+ return await handleListTables(args, this.dbManager);
59
+ case 'inspect_table':
60
+ return await handleInspectTable(args, this.dbManager);
61
+ case 'get_foreign_keys':
62
+ return await handleGetForeignKeys(args, this.dbManager);
63
+ case 'get_indexes':
64
+ return await handleGetIndexes(args, this.dbManager);
65
+ case 'information_schema_query':
66
+ return await handleInformationSchemaQuery(args, this.dbManager);
67
+ case 'execute_query':
68
+ return await handleExecuteQuery(args, this.dbManager);
69
+ case 'analyze_query':
70
+ return await handleAnalyzeQuery(args, this.dbManager);
71
+ default:
72
+ Logger.warn(`Unknown tool requested: ${name}`);
73
+ throw new ToolError(`Unknown tool: ${name}`);
74
+ }
75
+ }
76
+ catch (error) {
77
+ Logger.error(`Error executing tool ${name}:`, error);
78
+ const errorResponse = createErrorResponse(error instanceof Error ? error : new Error('Unknown error'));
79
+ return {
80
+ content: [{
81
+ type: 'text',
82
+ text: `Error: ${errorResponse.error}`
83
+ }],
84
+ isError: true
85
+ };
86
+ }
87
+ });
88
+ // Handle server errors
89
+ this.server.onerror = (error) => {
90
+ Logger.error('Server error:', error);
91
+ };
92
+ }
93
+ async initialize(connectionUrls) {
94
+ Logger.info('Initializing MySQL Inspector Server');
95
+ Logger.info(`Connection URLs provided: ${connectionUrls.length}`);
96
+ if (connectionUrls.length === 0) {
97
+ throw new Error('At least one database connection URL is required');
98
+ }
99
+ // Add databases to manager
100
+ for (let i = 0; i < connectionUrls.length; i++) {
101
+ const url = connectionUrls[i];
102
+ try {
103
+ Logger.info(`Adding database connection ${i + 1}/${connectionUrls.length}`);
104
+ const dbName = await this.dbManager.addDatabase(url);
105
+ Logger.info(`Successfully added database: ${dbName}`);
106
+ }
107
+ catch (error) {
108
+ Logger.error(`Failed to add database from URL: ${url}`, error);
109
+ // Continue with other databases instead of failing completely
110
+ }
111
+ }
112
+ const databases = this.dbManager.listDatabases();
113
+ if (databases.length === 0) {
114
+ throw new Error('No valid database connections could be established');
115
+ }
116
+ Logger.info(`Server initialized with ${databases.length} database(s): ${databases.map(db => db.name).join(', ')}`);
117
+ }
118
+ async run() {
119
+ Logger.info('Starting MySQL Inspector MCP Server');
120
+ const transport = new StdioServerTransport();
121
+ await this.server.connect(transport);
122
+ Logger.info('Server started and listening for requests');
123
+ }
124
+ async shutdown() {
125
+ Logger.info('Shutting down MySQL Inspector Server');
126
+ try {
127
+ await this.dbManager.cleanup();
128
+ Logger.info('Database connections cleaned up');
129
+ }
130
+ catch (error) {
131
+ Logger.error('Error during database cleanup:', error);
132
+ }
133
+ Logger.info('Server shutdown complete');
134
+ }
135
+ // Utility methods for external use
136
+ getDatabaseManager() {
137
+ return this.dbManager;
138
+ }
139
+ async getServerInfo() {
140
+ const databases = this.dbManager.listDatabases();
141
+ return {
142
+ serverName: 'mcp-database-inspector',
143
+ version: '2.0.0',
144
+ connectedDatabases: databases.length,
145
+ databases: databases.map(db => ({
146
+ name: db.name,
147
+ host: db.host,
148
+ database: db.database,
149
+ connected: db.connected,
150
+ lastUsed: db.lastUsed.toISOString()
151
+ })),
152
+ capabilities: [
153
+ 'list_databases',
154
+ 'list_tables',
155
+ 'inspect_table',
156
+ 'get_foreign_keys',
157
+ 'get_foreign_keys',
158
+ 'get_indexes',
159
+ 'information_schema_query',
160
+ 'execute_query',
161
+ 'analyze_query'
162
+ ],
163
+ status: databases.length > 0 ? 'ready' : 'no_connections'
164
+ };
165
+ }
166
+ }
167
+ // Error handling for uncaught exceptions
168
+ process.on('uncaughtException', (error) => {
169
+ Logger.error('Uncaught exception:', error);
170
+ process.exit(1);
171
+ });
172
+ process.on('unhandledRejection', (reason, promise) => {
173
+ Logger.error('Unhandled rejection:', { promise, reason });
174
+ process.exit(1);
175
+ });
176
+ // Graceful shutdown
177
+ process.on('SIGINT', async () => {
178
+ Logger.info('Received SIGINT, shutting down gracefully...');
179
+ process.exit(0);
180
+ });
181
+ process.on('SIGTERM', async () => {
182
+ Logger.info('Received SIGTERM, shutting down gracefully...');
183
+ process.exit(0);
184
+ });
185
+ export default DatabaseInspectorServer;
186
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnE,uBAAuB;AACvB,OAAO,EACL,2BAA2B,EAC3B,mBAAmB,EACpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,wBAAwB,EACxB,gBAAgB,EACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,0BAA0B,EAC1B,kBAAkB,EACnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,4BAA4B,EAC5B,oBAAoB,EACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,wBAAwB,EACxB,gBAAgB,EACjB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,oCAAoC,EACpC,4BAA4B,EAC7B,MAAM,qCAAqC,CAAC;AAE7C,OAAO,EACL,0BAA0B,EAC1B,kBAAkB,EACnB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,0BAA0B,EAC1B,kBAAkB,EACnB,MAAM,0BAA0B,CAAC;AAElC,MAAM,OAAO,uBAAuB;IAC1B,MAAM,CAAS;IACf,SAAS,CAAkB;IAEnC;QACE,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CACtB;YACE,IAAI,EAAE,wBAAwB;YAC9B,OAAO,EAAE,OAAO;SACjB,EACD;YACE,YAAY,EAAE;gBACZ,KAAK,EAAE,EAAE;aACV;SACF,CACF,CAAC;QAEF,IAAI,CAAC,SAAS,GAAG,IAAI,eAAe,EAAE,CAAC;QACvC,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC;IAEO,aAAa;QACnB,uBAAuB;QACvB,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;YAC/D,MAAM,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;YAE5C,OAAO;gBACL,KAAK,EAAE;oBACL,2BAA2B;oBAC3B,wBAAwB;oBACxB,0BAA0B;oBAC1B,4BAA4B;oBAC5B,wBAAwB;oBACxB,oCAAoC;oBACpC,0BAA0B;oBAC1B,0BAA0B;iBAC3B;aACF,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,oBAAoB;QACpB,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACrE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;YAEjD,MAAM,CAAC,IAAI,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC;YAC3C,MAAM,CAAC,KAAK,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC;YAEtC,IAAI,CAAC;gBACH,QAAQ,IAAI,EAAE,CAAC;oBACb,KAAK,gBAAgB;wBACnB,OAAO,MAAM,mBAAmB,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;oBAEzD,KAAK,aAAa;wBAChB,OAAO,MAAM,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;oBAEtD,KAAK,eAAe;wBAClB,OAAO,MAAM,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;oBAExD,KAAK,kBAAkB;wBACrB,OAAO,MAAM,oBAAoB,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;oBAE1D,KAAK,aAAa;wBAChB,OAAO,MAAM,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;oBAEtD,KAAK,0BAA0B;wBAC7B,OAAO,MAAM,4BAA4B,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;oBAElE,KAAK,eAAe;wBAClB,OAAO,MAAM,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;oBAExD,KAAK,eAAe;wBAClB,OAAO,MAAM,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;oBAExD;wBACE,MAAM,CAAC,IAAI,CAAC,2BAA2B,IAAI,EAAE,CAAC,CAAC;wBAC/C,MAAM,IAAI,SAAS,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;gBACjD,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,KAAK,CAAC,wBAAwB,IAAI,GAAG,EAAE,KAAK,CAAC,CAAC;gBAErD,MAAM,aAAa,GAAG,mBAAmB,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;gBAEvG,OAAO;oBACL,OAAO,EAAE,CAAC;4BACR,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,UAAU,aAAa,CAAC,KAAK,EAAE;yBACtC,CAAC;oBACF,OAAO,EAAE,IAAI;iBACd,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,uBAAuB;QACvB,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC,KAAK,EAAE,EAAE;YAC9B,MAAM,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;QACvC,CAAC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,cAAwB;QACvC,MAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;QACnD,MAAM,CAAC,IAAI,CAAC,6BAA6B,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC;QAElE,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACtE,CAAC;QAED,2BAA2B;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/C,MAAM,GAAG,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;YAC9B,IAAI,CAAC;gBACH,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,GAAG,CAAC,IAAI,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC;gBAC5E,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;gBACrD,MAAM,CAAC,IAAI,CAAC,gCAAgC,MAAM,EAAE,CAAC,CAAC;YACxD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,KAAK,CAAC,oCAAoC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC;gBAC/D,8DAA8D;YAChE,CAAC;QACH,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC;QACjD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;QACxE,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,2BAA2B,SAAS,CAAC,MAAM,iBAAiB,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrH,CAAC;IAED,KAAK,CAAC,GAAG;QACP,MAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;QAEnD,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAErC,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;IAC3D,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;QAEpD,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;YAC/B,MAAM,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;QACxD,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAC1C,CAAC;IAED,mCAAmC;IACnC,kBAAkB;QAChB,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC;QACjD,OAAO;YACL,UAAU,EAAE,wBAAwB;YACpC,OAAO,EAAE,OAAO;YAChB,kBAAkB,EAAE,SAAS,CAAC,MAAM;YACpC,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;gBAC9B,IAAI,EAAE,EAAE,CAAC,IAAI;gBACb,IAAI,EAAE,EAAE,CAAC,IAAI;gBACb,QAAQ,EAAE,EAAE,CAAC,QAAQ;gBACrB,SAAS,EAAE,EAAE,CAAC,SAAS;gBACvB,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE;aACpC,CAAC,CAAC;YACH,YAAY,EAAE;gBACZ,gBAAgB;gBAChB,aAAa;gBACb,eAAe;gBACf,kBAAkB;gBAClB,kBAAkB;gBAClB,aAAa;gBACb,0BAA0B;gBAC1B,eAAe;gBACf,eAAe;aAChB;YACD,MAAM,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB;SAC1D,CAAC;IACJ,CAAC;CACF;AAED,yCAAyC;AACzC,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,KAAK,EAAE,EAAE;IACxC,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;IAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE;IACnD,MAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,oBAAoB;AACpB,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;IAC9B,MAAM,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;IAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;IAC/B,MAAM,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;IAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,eAAe,uBAAuB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test-defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-defaults.d.ts","sourceRoot":"","sources":["../src/test-defaults.ts"],"names":[],"mappings":""}
@@ -0,0 +1,57 @@
1
+ import { DatabaseManager } from './database/manager.js';
2
+ import { Logger } from './utils/logger.js';
3
+ async function testConnections() {
4
+ const dbManager = new DatabaseManager();
5
+ // Default credentials
6
+ const mysqlUrl = 'mysql://root:root@localhost:3306/mysql';
7
+ const postgresUrl = 'postgresql://postgres:postgres@localhost:5432/postgres';
8
+ Logger.setLogLevel('info');
9
+ console.log('Starting connectivity test with default credentials...');
10
+ // Test MySQL
11
+ console.log('\n--- Testing MySQL (root/root) ---');
12
+ try {
13
+ const mysqlName = await dbManager.addDatabase(mysqlUrl, 'mysql_default');
14
+ console.log(`✅ Successfully added MySQL database: ${mysqlName}`);
15
+ const tables = await dbManager.getTables(mysqlName);
16
+ console.log(`✅ Retrieved ${tables.length} tables from MySQL`);
17
+ if (tables.length > 0) {
18
+ const table = tables[0].tableName;
19
+ console.log(`\n--- Analyzing MySQL Query on ${table} ---`);
20
+ const analysis = await dbManager.analyzeQuery(mysqlName, `SELECT * FROM ${table} LIMIT 10`);
21
+ console.log('✅ Analysis Success');
22
+ console.log(' Cost:', analysis.summary.cost);
23
+ console.log(' Operations:', analysis.summary.operations.join(', '));
24
+ if (analysis.summary.potentialIssues.length > 0) {
25
+ console.log(' ⚠️ Issues:', analysis.summary.potentialIssues.join(', '));
26
+ }
27
+ }
28
+ }
29
+ catch (error) {
30
+ console.error(`❌ MySQL test failed: ${error instanceof Error ? error.message : String(error)}`);
31
+ }
32
+ // Test PostgreSQL
33
+ console.log('\n--- Testing PostgreSQL (postgres/postgres) ---');
34
+ try {
35
+ const pgName = await dbManager.addDatabase(postgresUrl, 'postgres_default');
36
+ console.log(`✅ Successfully added PostgreSQL database: ${pgName}`);
37
+ console.log(`\n--- Analyzing PostgreSQL Query ---`);
38
+ // Use a system table that always exists
39
+ const analysis = await dbManager.analyzeQuery(pgName, 'SELECT * FROM pg_catalog.pg_class LIMIT 5');
40
+ console.log('✅ Analysis Success');
41
+ console.log(' Cost:', analysis.summary.cost);
42
+ console.log(' Operations:', analysis.summary.operations.join(', '));
43
+ if (analysis.summary.potentialIssues.length > 0) {
44
+ console.log(' ⚠️ Issues:', analysis.summary.potentialIssues.join(', '));
45
+ }
46
+ }
47
+ catch (error) {
48
+ console.error(`❌ PostgreSQL test failed: ${error instanceof Error ? error.message : String(error)}`);
49
+ }
50
+ await dbManager.cleanup();
51
+ console.log('\nTest complete.');
52
+ }
53
+ testConnections().catch(err => {
54
+ console.error('Fatal error during test:', err);
55
+ process.exit(1);
56
+ });
57
+ //# sourceMappingURL=test-defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-defaults.js","sourceRoot":"","sources":["../src/test-defaults.ts"],"names":[],"mappings":"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"}