@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.
- package/build/AzureSqlService.d.ts +224 -0
- package/build/AzureSqlService.d.ts.map +1 -0
- package/build/AzureSqlService.js +609 -0
- package/build/AzureSqlService.js.map +1 -0
- package/build/index.d.ts +5 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +17 -0
- package/build/index.js.map +1 -0
- package/build/utils/sql-formatters.d.ts +54 -0
- package/build/utils/sql-formatters.d.ts.map +1 -0
- package/build/utils/sql-formatters.js +228 -0
- package/build/utils/sql-formatters.js.map +1 -0
- package/package.json +24 -0
|
@@ -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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"}
|
package/build/index.d.ts
ADDED
|
@@ -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
|
+
}
|