@mcp-consultant-tools/azure-sql 1.0.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.
@@ -0,0 +1,224 @@
1
+ /**
2
+ * Database configuration within a server
3
+ */
4
+ export interface AzureSqlDatabaseConfig {
5
+ name: string;
6
+ active: boolean;
7
+ description?: string;
8
+ }
9
+ /**
10
+ * SQL Server resource configuration
11
+ */
12
+ export interface AzureSqlServerResource {
13
+ id: string;
14
+ name: string;
15
+ server: string;
16
+ port: number;
17
+ active: boolean;
18
+ databases: AzureSqlDatabaseConfig[];
19
+ username?: string;
20
+ password?: string;
21
+ useAzureAd?: boolean;
22
+ azureAdClientId?: string;
23
+ azureAdClientSecret?: string;
24
+ azureAdTenantId?: string;
25
+ description?: string;
26
+ }
27
+ /**
28
+ * Multi-server Azure SQL configuration
29
+ */
30
+ export interface AzureSqlConfig {
31
+ resources: AzureSqlServerResource[];
32
+ queryTimeout?: number;
33
+ maxResultRows?: number;
34
+ connectionTimeout?: number;
35
+ poolMin?: number;
36
+ poolMax?: number;
37
+ }
38
+ export interface SqlApiCollectionResponse<T> {
39
+ columns: string[];
40
+ rows: T[];
41
+ rowCount: number;
42
+ truncated?: boolean;
43
+ }
44
+ export interface TableInfo {
45
+ schemaName: string;
46
+ tableName: string;
47
+ rowCount: number;
48
+ sizeMB: number;
49
+ }
50
+ export interface ViewInfo {
51
+ schemaName: string;
52
+ viewName: string;
53
+ definition: string;
54
+ }
55
+ export interface StoredProcedureInfo {
56
+ schemaName: string;
57
+ procedureName: string;
58
+ createdDate: Date;
59
+ modifiedDate: Date;
60
+ }
61
+ export interface TriggerInfo {
62
+ schemaName: string;
63
+ triggerName: string;
64
+ objectName: string;
65
+ triggerEvent: string;
66
+ isDisabled: boolean;
67
+ createdDate: Date;
68
+ modifiedDate: Date;
69
+ }
70
+ export interface FunctionInfo {
71
+ schemaName: string;
72
+ functionName: string;
73
+ returnType: string;
74
+ createdDate: Date;
75
+ modifiedDate: Date;
76
+ }
77
+ export interface ColumnInfo {
78
+ columnName: string;
79
+ dataType: string;
80
+ maxLength: number | null;
81
+ isNullable: string;
82
+ defaultValue: string | null;
83
+ isIdentity: number;
84
+ }
85
+ export interface IndexInfo {
86
+ indexName: string;
87
+ indexType: string;
88
+ isUnique: boolean;
89
+ isPrimaryKey: boolean;
90
+ columns: string;
91
+ }
92
+ export interface ForeignKeyInfo {
93
+ foreignKeyName: string;
94
+ schemaName: string;
95
+ tableName: string;
96
+ columnName: string;
97
+ referencedSchema: string;
98
+ referencedTable: string;
99
+ referencedColumn: string;
100
+ }
101
+ export interface TableSchema {
102
+ schemaName: string;
103
+ tableName: string;
104
+ columns: ColumnInfo[];
105
+ indexes: IndexInfo[];
106
+ foreignKeys: ForeignKeyInfo[];
107
+ }
108
+ export interface ObjectDefinition {
109
+ objectName: string;
110
+ schemaName: string;
111
+ objectType: string;
112
+ createdDate: Date;
113
+ modifiedDate: Date;
114
+ definition: string;
115
+ }
116
+ export interface ConnectionTestResult {
117
+ connected: boolean;
118
+ server: string;
119
+ database: string;
120
+ sqlVersion?: string;
121
+ currentDatabase?: string;
122
+ loginName?: string;
123
+ userName?: string;
124
+ error?: string;
125
+ }
126
+ export interface ServerInfo {
127
+ id: string;
128
+ name: string;
129
+ server: string;
130
+ port: number;
131
+ active: boolean;
132
+ databaseCount: number;
133
+ description?: string;
134
+ authMethod: 'SQL' | 'Azure AD';
135
+ }
136
+ export interface DatabaseInfo {
137
+ name: string;
138
+ active: boolean;
139
+ description?: string;
140
+ }
141
+ /**
142
+ * Azure SQL Database Service
143
+ *
144
+ * Provides read-only access to Azure SQL Database for investigation and analysis.
145
+ * Supports multiple servers and databases with per-server credentials and active/inactive toggles.
146
+ * Implements security controls including query validation, result limits, and audit logging.
147
+ */
148
+ export declare class AzureSqlService {
149
+ private config;
150
+ private pools;
151
+ constructor(config: AzureSqlConfig);
152
+ /**
153
+ * Get server resource by ID with validation
154
+ */
155
+ private getServerById;
156
+ /**
157
+ * Get database configuration with validation
158
+ * Empty databases array = access all databases on server
159
+ */
160
+ private getDatabaseConfig;
161
+ /**
162
+ * Get or create connection pool for specific server and database
163
+ */
164
+ private getPool;
165
+ /**
166
+ * Sanitize error messages to prevent credential leakage
167
+ */
168
+ private sanitizeErrorMessage;
169
+ /**
170
+ * Execute a query with safety limits and size protection
171
+ */
172
+ private executeQuery;
173
+ /**
174
+ * Close all connection pools (cleanup)
175
+ */
176
+ close(): Promise<void>;
177
+ /**
178
+ * List all configured SQL servers
179
+ */
180
+ listServers(): Promise<ServerInfo[]>;
181
+ /**
182
+ * List databases on a server
183
+ * If server.databases is configured (non-empty), return configured databases
184
+ * If server.databases is empty, query sys.databases for all databases
185
+ */
186
+ listDatabases(serverId: string): Promise<DatabaseInfo[]>;
187
+ /**
188
+ * Test database connectivity
189
+ */
190
+ testConnection(serverId: string, database: string): Promise<ConnectionTestResult>;
191
+ /**
192
+ * List all user tables in the database
193
+ */
194
+ listTables(serverId: string, database: string): Promise<TableInfo[]>;
195
+ /**
196
+ * List all views in the database
197
+ */
198
+ listViews(serverId: string, database: string): Promise<ViewInfo[]>;
199
+ /**
200
+ * List all stored procedures
201
+ */
202
+ listStoredProcedures(serverId: string, database: string): Promise<StoredProcedureInfo[]>;
203
+ /**
204
+ * List all database triggers
205
+ */
206
+ listTriggers(serverId: string, database: string): Promise<TriggerInfo[]>;
207
+ /**
208
+ * List all user-defined functions
209
+ */
210
+ listFunctions(serverId: string, database: string): Promise<FunctionInfo[]>;
211
+ /**
212
+ * Get detailed schema information for a table
213
+ */
214
+ getTableSchema(serverId: string, database: string, schemaName: string, tableName: string): Promise<TableSchema>;
215
+ /**
216
+ * Get the SQL definition for views, stored procedures, functions, or triggers
217
+ */
218
+ getObjectDefinition(serverId: string, database: string, schemaName: string, objectName: string, objectType: 'VIEW' | 'PROCEDURE' | 'FUNCTION' | 'TRIGGER'): Promise<ObjectDefinition>;
219
+ /**
220
+ * Execute a user-provided SELECT query with enhanced safety validation
221
+ */
222
+ executeSelectQuery(serverId: string, database: string, query: string): Promise<SqlApiCollectionResponse<any>>;
223
+ }
224
+ //# sourceMappingURL=AzureSqlService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AzureSqlService.d.ts","sourceRoot":"","sources":["../src/AzureSqlService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,609 @@
1
+ import sql from 'mssql';
2
+ import { auditLogger } from '@mcp-consultant-tools/core';
3
+ // Configuration constants
4
+ const MAX_RESPONSE_SIZE_BYTES = 10 * 1024 * 1024; // 10MB
5
+ /**
6
+ * Azure SQL Database Service
7
+ *
8
+ * Provides read-only access to Azure SQL Database for investigation and analysis.
9
+ * Supports multiple servers and databases with per-server credentials and active/inactive toggles.
10
+ * Implements security controls including query validation, result limits, and audit logging.
11
+ */
12
+ export class AzureSqlService {
13
+ config;
14
+ // Multi-pool: Map<"serverId:database", ConnectionPool>
15
+ pools = new Map();
16
+ constructor(config) {
17
+ // Normalize server configurations
18
+ this.config = {
19
+ resources: config.resources.map(resource => ({
20
+ ...resource,
21
+ port: resource.port || 1433,
22
+ useAzureAd: resource.useAzureAd ?? false,
23
+ })),
24
+ queryTimeout: config.queryTimeout || 30000,
25
+ maxResultRows: config.maxResultRows || 1000,
26
+ connectionTimeout: config.connectionTimeout || 15000,
27
+ poolMin: config.poolMin || 0,
28
+ poolMax: config.poolMax || 10,
29
+ };
30
+ }
31
+ /**
32
+ * Get server resource by ID with validation
33
+ */
34
+ getServerById(serverId) {
35
+ const server = this.config.resources.find(r => r.id === serverId);
36
+ if (!server) {
37
+ const available = this.config.resources.map(r => `${r.id} (${r.name})`).join(', ');
38
+ throw new Error(`Server '${serverId}' not found. Available servers: ${available || 'none configured'}. ` +
39
+ `Use sql-list-servers to see all configured servers.`);
40
+ }
41
+ if (!server.active) {
42
+ throw new Error(`Server '${serverId}' is inactive. Set active=true in configuration to enable access.`);
43
+ }
44
+ return server;
45
+ }
46
+ /**
47
+ * Get database configuration with validation
48
+ * Empty databases array = access all databases on server
49
+ */
50
+ getDatabaseConfig(server, database) {
51
+ // Empty databases array = access all databases (discovery mode)
52
+ if (server.databases.length === 0) {
53
+ return { name: database, active: true };
54
+ }
55
+ const dbConfig = server.databases.find(db => db.name === database);
56
+ if (!dbConfig) {
57
+ const available = server.databases.map(db => db.name).join(', ');
58
+ throw new Error(`Database '${database}' not configured on server '${server.id}'. ` +
59
+ `Available databases: ${available || 'none configured'}. ` +
60
+ `Use sql-list-databases to see all databases on this server.`);
61
+ }
62
+ if (!dbConfig.active) {
63
+ throw new Error(`Database '${database}' is inactive on server '${server.id}'. ` +
64
+ `Set active=true in configuration to enable access.`);
65
+ }
66
+ return dbConfig;
67
+ }
68
+ /**
69
+ * Get or create connection pool for specific server and database
70
+ */
71
+ async getPool(serverId, database) {
72
+ const poolKey = `${serverId}:${database}`;
73
+ // Check if pool exists and is healthy
74
+ if (this.pools.has(poolKey)) {
75
+ const pool = this.pools.get(poolKey);
76
+ if (pool.connected && pool.healthy) {
77
+ return pool;
78
+ }
79
+ // Close unhealthy pool
80
+ try {
81
+ await pool.close();
82
+ }
83
+ catch (error) {
84
+ console.error(`Error closing unhealthy pool ${poolKey}:`, error);
85
+ }
86
+ this.pools.delete(poolKey);
87
+ }
88
+ // Validate server and database configuration
89
+ const server = this.getServerById(serverId);
90
+ this.getDatabaseConfig(server, database);
91
+ try {
92
+ const poolConfig = {
93
+ server: server.server,
94
+ database: database,
95
+ port: server.port,
96
+ connectionTimeout: this.config.connectionTimeout,
97
+ requestTimeout: this.config.queryTimeout,
98
+ pool: {
99
+ min: this.config.poolMin,
100
+ max: this.config.poolMax,
101
+ idleTimeoutMillis: 30000,
102
+ },
103
+ options: {
104
+ encrypt: true, // Required for Azure SQL
105
+ trustServerCertificate: false,
106
+ enableArithAbort: true,
107
+ },
108
+ };
109
+ // Per-server authentication
110
+ if (server.useAzureAd) {
111
+ poolConfig.authentication = {
112
+ type: 'azure-active-directory-service-principal-secret',
113
+ options: {
114
+ clientId: server.azureAdClientId,
115
+ clientSecret: server.azureAdClientSecret,
116
+ tenantId: server.azureAdTenantId,
117
+ },
118
+ };
119
+ }
120
+ else {
121
+ poolConfig.user = server.username;
122
+ poolConfig.password = server.password;
123
+ }
124
+ const pool = await sql.connect(poolConfig);
125
+ this.pools.set(poolKey, pool);
126
+ console.error(`Azure SQL connection pool established: ${poolKey}`);
127
+ return pool;
128
+ }
129
+ catch (error) {
130
+ console.error(`Failed to connect to Azure SQL Database (${poolKey}):`, {
131
+ server: server.server,
132
+ database: database,
133
+ error: this.sanitizeErrorMessage(error.message),
134
+ });
135
+ throw new Error(`Database connection failed for '${serverId}/${database}': ${this.sanitizeErrorMessage(error.message)}`);
136
+ }
137
+ }
138
+ /**
139
+ * Sanitize error messages to prevent credential leakage
140
+ */
141
+ sanitizeErrorMessage(message) {
142
+ return message
143
+ .replace(/password=[^;]+/gi, 'password=***')
144
+ .replace(/pwd=[^;]+/gi, 'pwd=***')
145
+ .replace(/clientSecret=[^;]+/gi, 'clientSecret=***')
146
+ .replace(/Authentication=ActiveDirectoryServicePrincipal;([^;]*);/gi, 'Authentication=***;');
147
+ }
148
+ /**
149
+ * Execute a query with safety limits and size protection
150
+ */
151
+ async executeQuery(serverId, database, query, parameters) {
152
+ try {
153
+ const pool = await this.getPool(serverId, database);
154
+ const request = pool.request();
155
+ // Add parameters if provided
156
+ if (parameters) {
157
+ for (const [key, value] of Object.entries(parameters)) {
158
+ request.input(key, value);
159
+ }
160
+ }
161
+ const result = await request.query(query);
162
+ const rows = result.recordset || [];
163
+ const columns = result.recordset?.columns
164
+ ? Object.keys(result.recordset.columns)
165
+ : [];
166
+ // Check response size BEFORE processing
167
+ const jsonSize = JSON.stringify(rows).length;
168
+ if (jsonSize > MAX_RESPONSE_SIZE_BYTES) {
169
+ throw new Error(`Query results too large (${(jsonSize / 1024 / 1024).toFixed(2)} MB). ` +
170
+ `Maximum allowed: ${MAX_RESPONSE_SIZE_BYTES / 1024 / 1024} MB. ` +
171
+ `Add WHERE clause or SELECT specific columns to reduce result size.`);
172
+ }
173
+ // Enforce row limit
174
+ const truncated = rows.length > this.config.maxResultRows;
175
+ const limitedRows = rows.slice(0, this.config.maxResultRows);
176
+ return {
177
+ columns,
178
+ rows: limitedRows,
179
+ rowCount: limitedRows.length,
180
+ truncated,
181
+ };
182
+ }
183
+ catch (error) {
184
+ console.error(`SQL query execution failed (${serverId}/${database}):`, {
185
+ error: this.sanitizeErrorMessage(error.message),
186
+ query: query.substring(0, 200), // Log first 200 chars
187
+ });
188
+ // Provide user-friendly error messages
189
+ if (error.message.includes('timeout') || error.message.includes('ETIMEDOUT')) {
190
+ throw new Error(`Query timeout exceeded (${this.config.queryTimeout}ms). ` +
191
+ `Try simplifying your query or adding WHERE clause filters.`);
192
+ }
193
+ if (error.message.includes('permission denied') || error.message.includes('denied')) {
194
+ throw new Error('Permission denied. Ensure the database user has SELECT permissions ' +
195
+ 'on the requested objects.');
196
+ }
197
+ throw new Error(`Query execution failed: ${this.sanitizeErrorMessage(error.message)}`);
198
+ }
199
+ }
200
+ /**
201
+ * Close all connection pools (cleanup)
202
+ */
203
+ async close() {
204
+ const closedPools = [];
205
+ const errors = [];
206
+ for (const [poolKey, pool] of this.pools.entries()) {
207
+ try {
208
+ await pool.close();
209
+ closedPools.push(poolKey);
210
+ }
211
+ catch (error) {
212
+ const errorMsg = this.sanitizeErrorMessage(error.message);
213
+ errors.push(`${poolKey}: ${errorMsg}`);
214
+ console.error(`Error closing pool ${poolKey}:`, errorMsg);
215
+ }
216
+ }
217
+ this.pools.clear();
218
+ if (closedPools.length > 0) {
219
+ console.error(`Azure SQL connection pools closed: ${closedPools.join(', ')}`);
220
+ }
221
+ if (errors.length > 0) {
222
+ console.error(`Errors closing pools: ${errors.join('; ')}`);
223
+ }
224
+ }
225
+ /**
226
+ * List all configured SQL servers
227
+ */
228
+ async listServers() {
229
+ return this.config.resources.map(resource => ({
230
+ id: resource.id,
231
+ name: resource.name,
232
+ server: resource.server,
233
+ port: resource.port,
234
+ active: resource.active,
235
+ databaseCount: resource.databases.length,
236
+ description: resource.description,
237
+ authMethod: resource.useAzureAd ? 'Azure AD' : 'SQL',
238
+ }));
239
+ }
240
+ /**
241
+ * List databases on a server
242
+ * If server.databases is configured (non-empty), return configured databases
243
+ * If server.databases is empty, query sys.databases for all databases
244
+ */
245
+ async listDatabases(serverId) {
246
+ const server = this.getServerById(serverId);
247
+ // If databases configured, return them
248
+ if (server.databases.length > 0) {
249
+ return server.databases.map(db => ({
250
+ name: db.name,
251
+ active: db.active,
252
+ description: db.description,
253
+ }));
254
+ }
255
+ // Otherwise, query SQL Server for all databases (discovery mode)
256
+ try {
257
+ const pool = await this.getPool(serverId, 'master');
258
+ const result = await pool.request().query(`
259
+ SELECT name
260
+ FROM sys.databases
261
+ WHERE database_id > 4 -- Exclude system databases (master, tempdb, model, msdb)
262
+ ORDER BY name
263
+ `);
264
+ return result.recordset.map((r) => ({
265
+ name: r.name,
266
+ active: true,
267
+ description: 'Discovered database',
268
+ }));
269
+ }
270
+ catch (error) {
271
+ throw new Error(`Failed to query databases on server '${serverId}': ${this.sanitizeErrorMessage(error.message)}`);
272
+ }
273
+ }
274
+ /**
275
+ * Test database connectivity
276
+ */
277
+ async testConnection(serverId, database) {
278
+ const server = this.getServerById(serverId);
279
+ try {
280
+ const pool = await this.getPool(serverId, database);
281
+ const result = await pool.request().query(`
282
+ SELECT
283
+ @@VERSION as sqlVersion,
284
+ DB_NAME() as currentDatabase,
285
+ SUSER_SNAME() as loginName,
286
+ USER_NAME() as userName
287
+ `);
288
+ return {
289
+ connected: true,
290
+ server: server.server,
291
+ database: database,
292
+ sqlVersion: result.recordset[0].sqlVersion,
293
+ currentDatabase: result.recordset[0].currentDatabase,
294
+ loginName: result.recordset[0].loginName,
295
+ userName: result.recordset[0].userName,
296
+ };
297
+ }
298
+ catch (error) {
299
+ return {
300
+ connected: false,
301
+ server: server.server,
302
+ database: database,
303
+ error: this.sanitizeErrorMessage(error.message),
304
+ };
305
+ }
306
+ }
307
+ /**
308
+ * List all user tables in the database
309
+ */
310
+ async listTables(serverId, database) {
311
+ const query = `
312
+ SELECT
313
+ t.TABLE_SCHEMA as schemaName,
314
+ t.TABLE_NAME as tableName,
315
+ p.rows as rowCount,
316
+ CAST(SUM(a.total_pages) * 8 / 1024.0 AS DECIMAL(10,2)) as sizeMB
317
+ FROM INFORMATION_SCHEMA.TABLES t
318
+ LEFT JOIN sys.tables st ON t.TABLE_NAME = st.name
319
+ LEFT JOIN sys.partitions p ON st.object_id = p.object_id AND p.index_id IN (0,1)
320
+ LEFT JOIN sys.allocation_units a ON p.partition_id = a.container_id
321
+ WHERE t.TABLE_TYPE = 'BASE TABLE'
322
+ AND t.TABLE_SCHEMA != 'sys'
323
+ GROUP BY t.TABLE_SCHEMA, t.TABLE_NAME, p.rows
324
+ ORDER BY t.TABLE_SCHEMA, t.TABLE_NAME
325
+ `;
326
+ const result = await this.executeQuery(serverId, database, query);
327
+ return result.rows;
328
+ }
329
+ /**
330
+ * List all views in the database
331
+ */
332
+ async listViews(serverId, database) {
333
+ const query = `
334
+ SELECT
335
+ TABLE_SCHEMA as schemaName,
336
+ TABLE_NAME as viewName,
337
+ VIEW_DEFINITION as definition
338
+ FROM INFORMATION_SCHEMA.VIEWS
339
+ WHERE TABLE_SCHEMA != 'sys'
340
+ ORDER BY TABLE_SCHEMA, TABLE_NAME
341
+ `;
342
+ const result = await this.executeQuery(serverId, database, query);
343
+ return result.rows;
344
+ }
345
+ /**
346
+ * List all stored procedures
347
+ */
348
+ async listStoredProcedures(serverId, database) {
349
+ const query = `
350
+ SELECT
351
+ ROUTINE_SCHEMA as schemaName,
352
+ ROUTINE_NAME as procedureName,
353
+ CREATED as createdDate,
354
+ LAST_ALTERED as modifiedDate
355
+ FROM INFORMATION_SCHEMA.ROUTINES
356
+ WHERE ROUTINE_TYPE = 'PROCEDURE'
357
+ AND ROUTINE_SCHEMA != 'sys'
358
+ ORDER BY ROUTINE_SCHEMA, ROUTINE_NAME
359
+ `;
360
+ const result = await this.executeQuery(serverId, database, query);
361
+ return result.rows;
362
+ }
363
+ /**
364
+ * List all database triggers
365
+ */
366
+ async listTriggers(serverId, database) {
367
+ const query = `
368
+ SELECT
369
+ s.name as schemaName,
370
+ t.name as triggerName,
371
+ OBJECT_NAME(t.parent_id) as objectName,
372
+ CASE
373
+ WHEN OBJECTPROPERTY(t.object_id, 'ExecIsInsertTrigger') = 1 THEN 'INSERT'
374
+ WHEN OBJECTPROPERTY(t.object_id, 'ExecIsUpdateTrigger') = 1 THEN 'UPDATE'
375
+ WHEN OBJECTPROPERTY(t.object_id, 'ExecIsDeleteTrigger') = 1 THEN 'DELETE'
376
+ ELSE 'UNKNOWN'
377
+ END as triggerEvent,
378
+ t.is_disabled as isDisabled,
379
+ t.create_date as createdDate,
380
+ t.modify_date as modifiedDate
381
+ FROM sys.triggers t
382
+ INNER JOIN sys.objects o ON t.parent_id = o.object_id
383
+ INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
384
+ WHERE t.parent_class = 1 -- Object triggers (not database triggers)
385
+ ORDER BY s.name, t.name
386
+ `;
387
+ const result = await this.executeQuery(serverId, database, query);
388
+ return result.rows;
389
+ }
390
+ /**
391
+ * List all user-defined functions
392
+ */
393
+ async listFunctions(serverId, database) {
394
+ const query = `
395
+ SELECT
396
+ ROUTINE_SCHEMA as schemaName,
397
+ ROUTINE_NAME as functionName,
398
+ DATA_TYPE as returnType,
399
+ CREATED as createdDate,
400
+ LAST_ALTERED as modifiedDate
401
+ FROM INFORMATION_SCHEMA.ROUTINES
402
+ WHERE ROUTINE_TYPE = 'FUNCTION'
403
+ AND ROUTINE_SCHEMA != 'sys'
404
+ ORDER BY ROUTINE_SCHEMA, ROUTINE_NAME
405
+ `;
406
+ const result = await this.executeQuery(serverId, database, query);
407
+ return result.rows;
408
+ }
409
+ /**
410
+ * Get detailed schema information for a table
411
+ */
412
+ async getTableSchema(serverId, database, schemaName, tableName) {
413
+ // First, verify table exists
414
+ const existsQuery = `
415
+ SELECT 1 FROM INFORMATION_SCHEMA.TABLES
416
+ WHERE TABLE_SCHEMA = @schema AND TABLE_NAME = @table
417
+ `;
418
+ const existsResult = await this.executeQuery(serverId, database, existsQuery, { schema: schemaName, table: tableName });
419
+ if (existsResult.rows.length === 0) {
420
+ throw new Error(`Table '${schemaName}.${tableName}' not found. ` +
421
+ `Use sql-list-tables to see available tables.`);
422
+ }
423
+ // Get columns
424
+ const columnsQuery = `
425
+ SELECT
426
+ COLUMN_NAME as columnName,
427
+ DATA_TYPE as dataType,
428
+ CHARACTER_MAXIMUM_LENGTH as maxLength,
429
+ IS_NULLABLE as isNullable,
430
+ COLUMN_DEFAULT as defaultValue,
431
+ COLUMNPROPERTY(OBJECT_ID(@schema + '.' + @table), COLUMN_NAME, 'IsIdentity') as isIdentity
432
+ FROM INFORMATION_SCHEMA.COLUMNS
433
+ WHERE TABLE_SCHEMA = @schema AND TABLE_NAME = @table
434
+ ORDER BY ORDINAL_POSITION
435
+ `;
436
+ // Get indexes
437
+ const indexesQuery = `
438
+ SELECT
439
+ i.name as indexName,
440
+ i.type_desc as indexType,
441
+ i.is_unique as isUnique,
442
+ i.is_primary_key as isPrimaryKey,
443
+ STRING_AGG(c.name, ', ') WITHIN GROUP (ORDER BY ic.key_ordinal) as columns
444
+ FROM sys.indexes i
445
+ INNER JOIN sys.tables t ON i.object_id = t.object_id
446
+ INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
447
+ INNER JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
448
+ INNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
449
+ WHERE s.name = @schema AND t.name = @table
450
+ GROUP BY i.name, i.type_desc, i.is_unique, i.is_primary_key
451
+ ORDER BY i.is_primary_key DESC, i.name
452
+ `;
453
+ // Get foreign keys
454
+ const foreignKeysQuery = `
455
+ SELECT
456
+ fk.name as foreignKeyName,
457
+ OBJECT_SCHEMA_NAME(fk.parent_object_id) as schemaName,
458
+ OBJECT_NAME(fk.parent_object_id) as tableName,
459
+ COL_NAME(fkc.parent_object_id, fkc.parent_column_id) as columnName,
460
+ OBJECT_SCHEMA_NAME(fk.referenced_object_id) as referencedSchema,
461
+ OBJECT_NAME(fk.referenced_object_id) as referencedTable,
462
+ COL_NAME(fkc.referenced_object_id, fkc.referenced_column_id) as referencedColumn
463
+ FROM sys.foreign_keys fk
464
+ INNER JOIN sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id
465
+ WHERE OBJECT_SCHEMA_NAME(fk.parent_object_id) = @schema
466
+ AND OBJECT_NAME(fk.parent_object_id) = @table
467
+ ORDER BY fk.name
468
+ `;
469
+ // Query all schema information with graceful degradation
470
+ try {
471
+ const [columnsResult, indexesResult, foreignKeysResult] = await Promise.all([
472
+ this.executeQuery(serverId, database, columnsQuery, { schema: schemaName, table: tableName }),
473
+ this.executeQuery(serverId, database, indexesQuery, { schema: schemaName, table: tableName })
474
+ .catch(() => ({ rows: [], rowCount: 0, columns: [] })),
475
+ this.executeQuery(serverId, database, foreignKeysQuery, { schema: schemaName, table: tableName })
476
+ .catch(() => ({ rows: [], rowCount: 0, columns: [] })),
477
+ ]);
478
+ return {
479
+ schemaName,
480
+ tableName,
481
+ columns: columnsResult.rows,
482
+ indexes: indexesResult.rows,
483
+ foreignKeys: foreignKeysResult.rows,
484
+ };
485
+ }
486
+ catch (error) {
487
+ throw new Error(`Failed to retrieve schema for '${schemaName}.${tableName}': ${this.sanitizeErrorMessage(error.message)}`);
488
+ }
489
+ }
490
+ /**
491
+ * Get the SQL definition for views, stored procedures, functions, or triggers
492
+ */
493
+ async getObjectDefinition(serverId, database, schemaName, objectName, objectType) {
494
+ const query = `
495
+ SELECT
496
+ o.name as objectName,
497
+ s.name as schemaName,
498
+ o.type_desc as objectType,
499
+ o.create_date as createdDate,
500
+ o.modify_date as modifiedDate,
501
+ OBJECT_DEFINITION(o.object_id) as definition
502
+ FROM sys.objects o
503
+ INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
504
+ WHERE s.name = @schema
505
+ AND o.name = @object
506
+ AND o.type_desc LIKE '%' + @type + '%'
507
+ `;
508
+ const result = await this.executeQuery(serverId, database, query, {
509
+ schema: schemaName,
510
+ object: objectName,
511
+ type: objectType,
512
+ });
513
+ if (result.rows.length === 0) {
514
+ throw new Error(`${objectType} '${schemaName}.${objectName}' not found. ` +
515
+ `Check the schema name, object name, and object type.`);
516
+ }
517
+ return result.rows[0];
518
+ }
519
+ /**
520
+ * Execute a user-provided SELECT query with enhanced safety validation
521
+ */
522
+ async executeSelectQuery(serverId, database, query) {
523
+ const timer = auditLogger.startTimer();
524
+ // Step 1: Remove comments (SQL and C-style)
525
+ let cleanQuery = query
526
+ .replace(/--.*$/gm, '') // Remove -- comments
527
+ .replace(/\/\*[\s\S]*?\*\//g, '') // Remove /* */ comments
528
+ .replace(/\s+/g, ' ') // Normalize whitespace
529
+ .trim()
530
+ .toLowerCase();
531
+ // Step 2: Validate SELECT query
532
+ if (!cleanQuery.startsWith('select')) {
533
+ const error = 'Only SELECT queries are allowed. Write operations (INSERT, UPDATE, DELETE, etc.) are not permitted.';
534
+ auditLogger.log({
535
+ operation: 'execute-select-query',
536
+ operationType: 'READ',
537
+ componentType: 'Query',
538
+ componentName: `${serverId}/${database}`,
539
+ success: false,
540
+ error,
541
+ parameters: { query: query.substring(0, 500) },
542
+ executionTimeMs: timer()
543
+ });
544
+ throw new Error(error);
545
+ }
546
+ // Step 3: Check for dangerous keywords with word boundaries
547
+ const dangerousPatterns = [
548
+ { pattern: /\b(insert|update|delete|merge)\b/i, name: 'write operations' },
549
+ { pattern: /\b(drop|create|alter|truncate)\b/i, name: 'schema modifications' },
550
+ { pattern: /\b(exec|execute|sp_executesql)\b/i, name: 'command execution' },
551
+ { pattern: /\b(xp_|sp_)\w+/i, name: 'system stored procedures' },
552
+ { pattern: /\b(grant|revoke|deny)\b/i, name: 'permission changes' },
553
+ { pattern: /\binto\b/i, name: 'SELECT INTO' },
554
+ { pattern: /\b(openquery|openrowset|opendatasource)\b/i, name: 'linked server queries' },
555
+ ];
556
+ for (const { pattern, name } of dangerousPatterns) {
557
+ if (pattern.test(cleanQuery)) {
558
+ const error = `Query contains forbidden keyword or pattern (${name}). Only SELECT queries are allowed for investigation purposes.`;
559
+ auditLogger.log({
560
+ operation: 'execute-select-query',
561
+ operationType: 'READ',
562
+ componentType: 'Query',
563
+ componentName: `${serverId}/${database}`,
564
+ success: false,
565
+ error,
566
+ parameters: { query: query.substring(0, 500) },
567
+ executionTimeMs: timer()
568
+ });
569
+ throw new Error(error);
570
+ }
571
+ }
572
+ // Execute query with audit logging
573
+ try {
574
+ const result = await this.executeQuery(serverId, database, query);
575
+ auditLogger.log({
576
+ operation: 'execute-select-query',
577
+ operationType: 'READ',
578
+ componentType: 'Query',
579
+ componentName: `${serverId}/${database}`,
580
+ parameters: {
581
+ query: query.substring(0, 500),
582
+ rowCount: result.rowCount,
583
+ truncated: result.truncated
584
+ },
585
+ success: true,
586
+ executionTimeMs: timer()
587
+ });
588
+ if (result.truncated) {
589
+ console.error(`Query results truncated. Returned ${result.rowCount} of potentially more rows. ` +
590
+ `Maximum: ${this.config.maxResultRows}. Add WHERE clause to filter results.`);
591
+ }
592
+ return result;
593
+ }
594
+ catch (error) {
595
+ auditLogger.log({
596
+ operation: 'execute-select-query',
597
+ operationType: 'READ',
598
+ componentType: 'Query',
599
+ componentName: `${serverId}/${database}`,
600
+ success: false,
601
+ error: error instanceof Error ? error.message : String(error),
602
+ parameters: { query: query.substring(0, 500) },
603
+ executionTimeMs: timer()
604
+ });
605
+ throw error;
606
+ }
607
+ }
608
+ }
609
+ //# sourceMappingURL=AzureSqlService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AzureSqlService.js","sourceRoot":"","sources":["../src/AzureSqlService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ import { AzureSqlService } from "./AzureSqlService.js";
3
+ export declare function registerAzureSqlTools(server: any, service?: AzureSqlService): void;
4
+ export { AzureSqlService } from "./AzureSqlService.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,eAAe,QAE3E;AAED,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC"}
package/build/index.js ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { createMcpServer, createEnvLoader } from "@mcp-consultant-tools/core";
4
+ export function registerAzureSqlTools(server, service) {
5
+ console.error("Azure SQL tools registered (tool extraction pending)");
6
+ }
7
+ export { AzureSqlService } from "./AzureSqlService.js";
8
+ if (import.meta.url === `file://${process.argv[1]}`) {
9
+ const loadEnv = createEnvLoader();
10
+ loadEnv();
11
+ const server = createMcpServer({ name: "@mcp-consultant-tools/azure-sql", version: "1.0.0", capabilities: { tools: {} } });
12
+ registerAzureSqlTools(server);
13
+ const transport = new StdioServerTransport();
14
+ server.connect(transport).catch((error) => { console.error("Failed to start Azure SQL server:", error); process.exit(1); });
15
+ console.error("@mcp-consultant-tools/azure-sql server running");
16
+ }
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAG9E,MAAM,UAAU,qBAAqB,CAAC,MAAW,EAAE,OAAyB;IAC1E,OAAO,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;AACxE,CAAC;AAED,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACpD,MAAM,OAAO,GAAG,eAAe,EAAE,CAAC;IAClC,OAAO,EAAE,CAAC;IACV,MAAM,MAAM,GAAG,eAAe,CAAC,EAAE,IAAI,EAAE,iCAAiC,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAC3H,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,KAAY,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnI,OAAO,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;AAClE,CAAC"}
@@ -0,0 +1,54 @@
1
+ import { SqlApiCollectionResponse, TableInfo, ViewInfo, StoredProcedureInfo, TriggerInfo, FunctionInfo, TableSchema, ColumnInfo, IndexInfo, ForeignKeyInfo } from '../AzureSqlService.js';
2
+ /**
3
+ * Format SQL query results as markdown table
4
+ */
5
+ export declare function formatSqlResultsAsMarkdown(result: SqlApiCollectionResponse<any>): string;
6
+ /**
7
+ * Format table list as markdown
8
+ */
9
+ export declare function formatTableList(tables: TableInfo[]): string;
10
+ /**
11
+ * Format view list as markdown
12
+ */
13
+ export declare function formatViewList(views: ViewInfo[]): string;
14
+ /**
15
+ * Format stored procedure list as markdown
16
+ */
17
+ export declare function formatProcedureList(procedures: StoredProcedureInfo[]): string;
18
+ /**
19
+ * Format trigger list as markdown
20
+ */
21
+ export declare function formatTriggerList(triggers: TriggerInfo[]): string;
22
+ /**
23
+ * Format function list as markdown
24
+ */
25
+ export declare function formatFunctionList(functions: FunctionInfo[]): string;
26
+ /**
27
+ * Format columns as markdown table
28
+ */
29
+ export declare function formatColumnsAsMarkdown(columns: ColumnInfo[]): string;
30
+ /**
31
+ * Format indexes as markdown table
32
+ */
33
+ export declare function formatIndexesAsMarkdown(indexes: IndexInfo[]): string;
34
+ /**
35
+ * Format foreign keys as markdown table
36
+ */
37
+ export declare function formatForeignKeysAsMarkdown(foreignKeys: ForeignKeyInfo[]): string;
38
+ /**
39
+ * Format table schema as comprehensive markdown
40
+ */
41
+ export declare function formatTableSchemaAsMarkdown(schema: TableSchema): string;
42
+ /**
43
+ * Format database overview as markdown
44
+ */
45
+ export declare function formatDatabaseOverview(tables: TableInfo[], views: ViewInfo[], procedures: StoredProcedureInfo[], triggers: TriggerInfo[], functions: FunctionInfo[]): string;
46
+ /**
47
+ * Format server list as markdown
48
+ */
49
+ export declare function formatServerListAsMarkdown(servers: any[]): string;
50
+ /**
51
+ * Format database list as markdown
52
+ */
53
+ export declare function formatDatabaseListAsMarkdown(serverId: string, databases: any[]): string;
54
+ //# sourceMappingURL=sql-formatters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-formatters.d.ts","sourceRoot":"","sources":["../../src/utils/sql-formatters.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,SAAS,EACT,QAAQ,EACR,mBAAmB,EACnB,WAAW,EACX,YAAY,EACZ,WAAW,EACX,UAAU,EACV,SAAS,EACT,cAAc,EACf,MAAM,uBAAuB,CAAC;AAE/B;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,wBAAwB,CAAC,GAAG,CAAC,GAAG,MAAM,CA8BxF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAe3D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CAUxD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,mBAAmB,EAAE,GAAG,MAAM,CAW7E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM,CAWjE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,MAAM,CAUpE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM,CAkBrE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,MAAM,CAgBpE;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,cAAc,EAAE,GAAG,MAAM,CAcjF;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAevE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,SAAS,EAAE,EACnB,KAAK,EAAE,QAAQ,EAAE,EACjB,UAAU,EAAE,mBAAmB,EAAE,EACjC,QAAQ,EAAE,WAAW,EAAE,EACvB,SAAS,EAAE,YAAY,EAAE,GACxB,MAAM,CAuBR;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,MAAM,CA0BjE;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,MAAM,CAyBvF"}
@@ -0,0 +1,228 @@
1
+ /**
2
+ * Format SQL query results as markdown table
3
+ */
4
+ export function formatSqlResultsAsMarkdown(result) {
5
+ if (!result.rows || result.rows.length === 0) {
6
+ return '*No results*';
7
+ }
8
+ // Column headers
9
+ const header = '| ' + result.columns.join(' | ') + ' |';
10
+ const separator = '| ' + result.columns.map(() => '---').join(' | ') + ' |';
11
+ // Data rows
12
+ const rows = result.rows.map(row => {
13
+ const values = result.columns.map(col => {
14
+ const value = row[col];
15
+ if (value === null || value === undefined)
16
+ return '';
17
+ if (typeof value === 'object')
18
+ return JSON.stringify(value);
19
+ if (typeof value === 'string' && value.length > 100) {
20
+ return value.substring(0, 97) + '...';
21
+ }
22
+ return String(value);
23
+ });
24
+ return '| ' + values.join(' | ') + ' |';
25
+ });
26
+ let markdown = [header, separator, ...rows].join('\n');
27
+ if (result.truncated) {
28
+ markdown += `\n\n⚠️ **Results truncated to ${result.rowCount} rows.**`;
29
+ }
30
+ return markdown;
31
+ }
32
+ /**
33
+ * Format table list as markdown
34
+ */
35
+ export function formatTableList(tables) {
36
+ if (!tables || tables.length === 0) {
37
+ return '*No tables found*';
38
+ }
39
+ const header = '| Schema | Table Name | Rows | Size (MB) |';
40
+ const separator = '| --- | --- | ---: | ---: |';
41
+ const rows = tables.map(table => {
42
+ const rowCount = table.rowCount?.toLocaleString() || '0';
43
+ const sizeMB = table.sizeMB?.toFixed(2) || '0.00';
44
+ return `| ${table.schemaName} | ${table.tableName} | ${rowCount} | ${sizeMB} |`;
45
+ });
46
+ return [header, separator, ...rows].join('\n');
47
+ }
48
+ /**
49
+ * Format view list as markdown
50
+ */
51
+ export function formatViewList(views) {
52
+ if (!views || views.length === 0) {
53
+ return '*No views found*';
54
+ }
55
+ const items = views.map(view => {
56
+ return `- **${view.schemaName}.${view.viewName}**`;
57
+ });
58
+ return items.join('\n');
59
+ }
60
+ /**
61
+ * Format stored procedure list as markdown
62
+ */
63
+ export function formatProcedureList(procedures) {
64
+ if (!procedures || procedures.length === 0) {
65
+ return '*No stored procedures found*';
66
+ }
67
+ const items = procedures.map(proc => {
68
+ const modified = new Date(proc.modifiedDate).toLocaleDateString();
69
+ return `- **${proc.schemaName}.${proc.procedureName}** *(modified: ${modified})*`;
70
+ });
71
+ return items.join('\n');
72
+ }
73
+ /**
74
+ * Format trigger list as markdown
75
+ */
76
+ export function formatTriggerList(triggers) {
77
+ if (!triggers || triggers.length === 0) {
78
+ return '*No triggers found*';
79
+ }
80
+ const items = triggers.map(trigger => {
81
+ const status = trigger.isDisabled ? '⚠️ Disabled' : '✅ Enabled';
82
+ return `- **${trigger.schemaName}.${trigger.triggerName}** on ${trigger.objectName} (${trigger.triggerEvent}) - ${status}`;
83
+ });
84
+ return items.join('\n');
85
+ }
86
+ /**
87
+ * Format function list as markdown
88
+ */
89
+ export function formatFunctionList(functions) {
90
+ if (!functions || functions.length === 0) {
91
+ return '*No functions found*';
92
+ }
93
+ const items = functions.map(func => {
94
+ return `- **${func.schemaName}.${func.functionName}** → ${func.returnType}`;
95
+ });
96
+ return items.join('\n');
97
+ }
98
+ /**
99
+ * Format columns as markdown table
100
+ */
101
+ export function formatColumnsAsMarkdown(columns) {
102
+ if (!columns || columns.length === 0) {
103
+ return '*No columns found*';
104
+ }
105
+ const header = '| Column Name | Data Type | Max Length | Nullable | Default | Identity |';
106
+ const separator = '| --- | --- | ---: | --- | --- | --- |';
107
+ const rows = columns.map(col => {
108
+ const maxLength = col.maxLength !== null ? String(col.maxLength) : 'N/A';
109
+ const nullable = col.isNullable === 'YES' ? '✓' : '';
110
+ const defaultValue = col.defaultValue || '';
111
+ const identity = col.isIdentity === 1 ? '✓' : '';
112
+ return `| ${col.columnName} | ${col.dataType} | ${maxLength} | ${nullable} | ${defaultValue} | ${identity} |`;
113
+ });
114
+ return [header, separator, ...rows].join('\n');
115
+ }
116
+ /**
117
+ * Format indexes as markdown table
118
+ */
119
+ export function formatIndexesAsMarkdown(indexes) {
120
+ if (!indexes || indexes.length === 0) {
121
+ return '*No indexes found*';
122
+ }
123
+ const header = '| Index Name | Type | Columns | Unique | Primary Key |';
124
+ const separator = '| --- | --- | --- | --- | --- |';
125
+ const rows = indexes.map(idx => {
126
+ const unique = idx.isUnique ? '✓' : '';
127
+ const pk = idx.isPrimaryKey ? '✓' : '';
128
+ return `| ${idx.indexName} | ${idx.indexType} | ${idx.columns} | ${unique} | ${pk} |`;
129
+ });
130
+ return [header, separator, ...rows].join('\n');
131
+ }
132
+ /**
133
+ * Format foreign keys as markdown table
134
+ */
135
+ export function formatForeignKeysAsMarkdown(foreignKeys) {
136
+ if (!foreignKeys || foreignKeys.length === 0) {
137
+ return '*No foreign keys found*';
138
+ }
139
+ const header = '| Foreign Key | Column | References |';
140
+ const separator = '| --- | --- | --- |';
141
+ const rows = foreignKeys.map(fk => {
142
+ const references = `${fk.referencedSchema}.${fk.referencedTable}(${fk.referencedColumn})`;
143
+ return `| ${fk.foreignKeyName} | ${fk.columnName} | ${references} |`;
144
+ });
145
+ return [header, separator, ...rows].join('\n');
146
+ }
147
+ /**
148
+ * Format table schema as comprehensive markdown
149
+ */
150
+ export function formatTableSchemaAsMarkdown(schema) {
151
+ let md = `# Table: ${schema.schemaName}.${schema.tableName}\n\n`;
152
+ md += `## Columns (${schema.columns.length})\n\n`;
153
+ md += formatColumnsAsMarkdown(schema.columns);
154
+ md += `\n\n## Indexes (${schema.indexes.length})\n\n`;
155
+ md += formatIndexesAsMarkdown(schema.indexes);
156
+ if (schema.foreignKeys && schema.foreignKeys.length > 0) {
157
+ md += `\n\n## Foreign Keys (${schema.foreignKeys.length})\n\n`;
158
+ md += formatForeignKeysAsMarkdown(schema.foreignKeys);
159
+ }
160
+ return md;
161
+ }
162
+ /**
163
+ * Format database overview as markdown
164
+ */
165
+ export function formatDatabaseOverview(tables, views, procedures, triggers, functions) {
166
+ let md = `## Azure SQL Database Overview\n\n`;
167
+ md += `This is a comprehensive overview of the connected Azure SQL Database:\n\n`;
168
+ md += `### Tables (${tables.length})\n\n`;
169
+ md += formatTableList(tables);
170
+ md += `\n\n### Views (${views.length})\n\n`;
171
+ md += formatViewList(views);
172
+ md += `\n\n### Stored Procedures (${procedures.length})\n\n`;
173
+ md += formatProcedureList(procedures);
174
+ md += `\n\n### Triggers (${triggers.length})\n\n`;
175
+ md += formatTriggerList(triggers);
176
+ md += `\n\n### Functions (${functions.length})\n\n`;
177
+ md += formatFunctionList(functions);
178
+ md += `\n\nYou can query tables and views using the sql-execute-query tool.`;
179
+ return md;
180
+ }
181
+ /**
182
+ * Format server list as markdown
183
+ */
184
+ export function formatServerListAsMarkdown(servers) {
185
+ if (servers.length === 0) {
186
+ return 'No SQL servers configured.';
187
+ }
188
+ let md = `# Configured SQL Servers\n\n`;
189
+ md += `**Total Servers:** ${servers.length}\n`;
190
+ md += `**Active Servers:** ${servers.filter(s => s.active).length}\n\n`;
191
+ md += `| Server ID | Name | Server | Port | Status | Databases | Auth Method | Description |\n`;
192
+ md += `|-----------|------|--------|------|--------|-----------|-------------|-------------|\n`;
193
+ for (const server of servers) {
194
+ const status = server.active ? '✅ Active' : '❌ Inactive';
195
+ const dbCount = server.databaseCount || 0;
196
+ const description = server.description || '-';
197
+ md += `| ${server.id} | ${server.name} | ${server.server} | ${server.port} | ${status} | ${dbCount} | ${server.authMethod} | ${description} |\n`;
198
+ }
199
+ md += `\n\n**Usage:**\n`;
200
+ md += `- Use \`sql-list-databases\` to see databases on a server\n`;
201
+ md += `- Use \`sql-test-connection\` to test connectivity to a specific database\n`;
202
+ md += `- Use \`sql-list-tables\` and other schema tools to explore database objects\n`;
203
+ return md;
204
+ }
205
+ /**
206
+ * Format database list as markdown
207
+ */
208
+ export function formatDatabaseListAsMarkdown(serverId, databases) {
209
+ if (databases.length === 0) {
210
+ return `No databases configured on server '${serverId}'.`;
211
+ }
212
+ let md = `# Databases on Server: ${serverId}\n\n`;
213
+ md += `**Total Databases:** ${databases.length}\n`;
214
+ md += `**Active Databases:** ${databases.filter(d => d.active).length}\n\n`;
215
+ md += `| Database Name | Status | Description |\n`;
216
+ md += `|---------------|--------|-------------|\n`;
217
+ for (const db of databases) {
218
+ const status = db.active ? '✅ Active' : '❌ Inactive';
219
+ const description = db.description || '-';
220
+ md += `| ${db.name} | ${status} | ${description} |\n`;
221
+ }
222
+ md += `\n\n**Next Steps:**\n`;
223
+ md += `- Use \`sql-test-connection\` to verify connectivity to a database\n`;
224
+ md += `- Use \`sql-list-tables\` to see tables in a database\n`;
225
+ md += `- Use \`sql-execute-query\` to run queries against a database\n`;
226
+ return md;
227
+ }
228
+ //# sourceMappingURL=sql-formatters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-formatters.js","sourceRoot":"","sources":["../../src/utils/sql-formatters.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@mcp-consultant-tools/azure-sql",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for Azure SQL Database - read-only queries and schema exploration",
5
+ "type": "module",
6
+ "main": "./build/index.js",
7
+ "types": "./build/index.d.ts",
8
+ "bin": { "mcp-azuresql": "./build/index.js" },
9
+ "exports": { ".": { "import": "./build/index.js", "types": "./build/index.d.ts" } },
10
+ "files": ["build", "README.md"],
11
+ "scripts": { "build": "tsc", "clean": "rm -rf build *.tsbuildinfo", "prepublishOnly": "npm run build" },
12
+ "keywords": ["mcp", "model-context-protocol", "azure", "sql", "database", "sql-server"],
13
+ "author": "Michal Sobieraj",
14
+ "license": "MIT",
15
+ "repository": { "type": "git", "url": "git+https://github.com/klemensms/mcp-consultant-tools.git", "directory": "packages/azure-sql" },
16
+ "engines": { "node": ">=16.0.0" },
17
+ "dependencies": {
18
+ "@mcp-consultant-tools/core": "^1.0.0",
19
+ "@modelcontextprotocol/sdk": "^1.0.4",
20
+ "mssql": "^11.0.1",
21
+ "zod": "^3.24.1"
22
+ },
23
+ "devDependencies": { "@types/mssql": "^9.1.8", "@types/node": "^22.10.5", "typescript": "^5.8.2" }
24
+ }