@connorbritain/mssql-mcp-core 0.1.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.
Files changed (129) hide show
  1. package/dist/audit/AuditLogger.d.ts +37 -0
  2. package/dist/audit/AuditLogger.d.ts.map +1 -0
  3. package/dist/audit/AuditLogger.js +145 -0
  4. package/dist/audit/AuditLogger.js.map +1 -0
  5. package/dist/config/EnvironmentManager.d.ts +75 -0
  6. package/dist/config/EnvironmentManager.d.ts.map +1 -0
  7. package/dist/config/EnvironmentManager.js +305 -0
  8. package/dist/config/EnvironmentManager.js.map +1 -0
  9. package/dist/config/ScriptManager.d.ts +69 -0
  10. package/dist/config/ScriptManager.d.ts.map +1 -0
  11. package/dist/config/ScriptManager.js +166 -0
  12. package/dist/config/ScriptManager.js.map +1 -0
  13. package/dist/config/SecretResolver.d.ts +66 -0
  14. package/dist/config/SecretResolver.d.ts.map +1 -0
  15. package/dist/config/SecretResolver.js +230 -0
  16. package/dist/config/SecretResolver.js.map +1 -0
  17. package/dist/index.d.ts +14 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +17 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/routing/IntentRouter.d.ts +17 -0
  22. package/dist/routing/IntentRouter.d.ts.map +1 -0
  23. package/dist/routing/IntentRouter.js +243 -0
  24. package/dist/routing/IntentRouter.js.map +1 -0
  25. package/dist/server/createMcpServer.d.ts +7 -0
  26. package/dist/server/createMcpServer.d.ts.map +1 -0
  27. package/dist/server/createMcpServer.js +100 -0
  28. package/dist/server/createMcpServer.js.map +1 -0
  29. package/dist/server/toolsets.d.ts +42 -0
  30. package/dist/server/toolsets.d.ts.map +1 -0
  31. package/dist/server/toolsets.js +303 -0
  32. package/dist/server/toolsets.js.map +1 -0
  33. package/dist/server/wrapToolRun.d.ts +13 -0
  34. package/dist/server/wrapToolRun.d.ts.map +1 -0
  35. package/dist/server/wrapToolRun.js +102 -0
  36. package/dist/server/wrapToolRun.js.map +1 -0
  37. package/dist/shims.d.ts +2 -0
  38. package/dist/shims.d.ts.map +1 -0
  39. package/dist/shims.js +15 -0
  40. package/dist/shims.js.map +1 -0
  41. package/dist/tools/CreateIndexTool.d.ts +24 -0
  42. package/dist/tools/CreateIndexTool.d.ts.map +1 -0
  43. package/dist/tools/CreateIndexTool.js +64 -0
  44. package/dist/tools/CreateIndexTool.js.map +1 -0
  45. package/dist/tools/CreateTableTool.d.ts +12 -0
  46. package/dist/tools/CreateTableTool.d.ts.map +1 -0
  47. package/dist/tools/CreateTableTool.js +49 -0
  48. package/dist/tools/CreateTableTool.js.map +1 -0
  49. package/dist/tools/DeleteDataTool.d.ts +56 -0
  50. package/dist/tools/DeleteDataTool.d.ts.map +1 -0
  51. package/dist/tools/DeleteDataTool.js +103 -0
  52. package/dist/tools/DeleteDataTool.js.map +1 -0
  53. package/dist/tools/DescribeTableTool.d.ts +32 -0
  54. package/dist/tools/DescribeTableTool.d.ts.map +1 -0
  55. package/dist/tools/DescribeTableTool.js +116 -0
  56. package/dist/tools/DescribeTableTool.js.map +1 -0
  57. package/dist/tools/DropTableTool.d.ts +12 -0
  58. package/dist/tools/DropTableTool.d.ts.map +1 -0
  59. package/dist/tools/DropTableTool.js +37 -0
  60. package/dist/tools/DropTableTool.js.map +1 -0
  61. package/dist/tools/ExplainQueryTool.d.ts +24 -0
  62. package/dist/tools/ExplainQueryTool.d.ts.map +1 -0
  63. package/dist/tools/ExplainQueryTool.js +98 -0
  64. package/dist/tools/ExplainQueryTool.js.map +1 -0
  65. package/dist/tools/InsertDataTool.d.ts +17 -0
  66. package/dist/tools/InsertDataTool.d.ts.map +1 -0
  67. package/dist/tools/InsertDataTool.js +102 -0
  68. package/dist/tools/InsertDataTool.js.map +1 -0
  69. package/dist/tools/InspectDependenciesTool.d.ts +46 -0
  70. package/dist/tools/InspectDependenciesTool.d.ts.map +1 -0
  71. package/dist/tools/InspectDependenciesTool.js +215 -0
  72. package/dist/tools/InspectDependenciesTool.js.map +1 -0
  73. package/dist/tools/ListDatabasesTool.d.ts +27 -0
  74. package/dist/tools/ListDatabasesTool.d.ts.map +1 -0
  75. package/dist/tools/ListDatabasesTool.js +107 -0
  76. package/dist/tools/ListDatabasesTool.js.map +1 -0
  77. package/dist/tools/ListEnvironmentsTool.d.ts +49 -0
  78. package/dist/tools/ListEnvironmentsTool.d.ts.map +1 -0
  79. package/dist/tools/ListEnvironmentsTool.js +73 -0
  80. package/dist/tools/ListEnvironmentsTool.js.map +1 -0
  81. package/dist/tools/ListScriptsTool.d.ts +41 -0
  82. package/dist/tools/ListScriptsTool.d.ts.map +1 -0
  83. package/dist/tools/ListScriptsTool.js +86 -0
  84. package/dist/tools/ListScriptsTool.js.map +1 -0
  85. package/dist/tools/ListTableTool.d.ts +24 -0
  86. package/dist/tools/ListTableTool.d.ts.map +1 -0
  87. package/dist/tools/ListTableTool.js +85 -0
  88. package/dist/tools/ListTableTool.js.map +1 -0
  89. package/dist/tools/ProfileTableTool.d.ts +78 -0
  90. package/dist/tools/ProfileTableTool.d.ts.map +1 -0
  91. package/dist/tools/ProfileTableTool.js +373 -0
  92. package/dist/tools/ProfileTableTool.js.map +1 -0
  93. package/dist/tools/ReadDataTool.d.ts +61 -0
  94. package/dist/tools/ReadDataTool.d.ts.map +1 -0
  95. package/dist/tools/ReadDataTool.js +299 -0
  96. package/dist/tools/ReadDataTool.js.map +1 -0
  97. package/dist/tools/RelationshipInspectorTool.d.ts +46 -0
  98. package/dist/tools/RelationshipInspectorTool.d.ts.map +1 -0
  99. package/dist/tools/RelationshipInspectorTool.js +156 -0
  100. package/dist/tools/RelationshipInspectorTool.js.map +1 -0
  101. package/dist/tools/RunScriptTool.d.ts +214 -0
  102. package/dist/tools/RunScriptTool.d.ts.map +1 -0
  103. package/dist/tools/RunScriptTool.js +186 -0
  104. package/dist/tools/RunScriptTool.js.map +1 -0
  105. package/dist/tools/SearchSchemaTool.d.ts +88 -0
  106. package/dist/tools/SearchSchemaTool.d.ts.map +1 -0
  107. package/dist/tools/SearchSchemaTool.js +237 -0
  108. package/dist/tools/SearchSchemaTool.js.map +1 -0
  109. package/dist/tools/TestConnectionTool.d.ts +38 -0
  110. package/dist/tools/TestConnectionTool.d.ts.map +1 -0
  111. package/dist/tools/TestConnectionTool.js +156 -0
  112. package/dist/tools/TestConnectionTool.js.map +1 -0
  113. package/dist/tools/UpdateDataTool.d.ts +61 -0
  114. package/dist/tools/UpdateDataTool.d.ts.map +1 -0
  115. package/dist/tools/UpdateDataTool.js +117 -0
  116. package/dist/tools/UpdateDataTool.js.map +1 -0
  117. package/dist/tools/ValidateEnvironmentConfigTool.d.ts +51 -0
  118. package/dist/tools/ValidateEnvironmentConfigTool.d.ts.map +1 -0
  119. package/dist/tools/ValidateEnvironmentConfigTool.js +320 -0
  120. package/dist/tools/ValidateEnvironmentConfigTool.js.map +1 -0
  121. package/dist/tools/index.d.ts +21 -0
  122. package/dist/tools/index.d.ts.map +1 -0
  123. package/dist/tools/index.js +22 -0
  124. package/dist/tools/index.js.map +1 -0
  125. package/dist/types.d.ts +60 -0
  126. package/dist/types.d.ts.map +1 -0
  127. package/dist/types.js +2 -0
  128. package/dist/types.js.map +1 -0
  129. package/package.json +53 -0
@@ -0,0 +1,237 @@
1
+ import sql from "mssql";
2
+ const clampEnvLimit = (value, fallback, max) => {
3
+ if (!value) {
4
+ return fallback;
5
+ }
6
+ const parsed = parseInt(value, 10);
7
+ if (Number.isNaN(parsed) || parsed <= 0) {
8
+ return fallback;
9
+ }
10
+ return Math.min(parsed, max);
11
+ };
12
+ const SEARCH_DEFAULT_LIMIT = clampEnvLimit(process.env.SEARCH_SCHEMA_DEFAULT_LIMIT, 50, 200);
13
+ export class SearchSchemaTool {
14
+ constructor() {
15
+ this.name = "search_schema";
16
+ this.description = "Searches tables and columns using wildcard patterns to discover schema names.";
17
+ this.inputSchema = {
18
+ type: "object",
19
+ properties: {
20
+ tablePattern: {
21
+ type: "string",
22
+ description: "Wildcard pattern for table names (e.g. 'doc%')."
23
+ },
24
+ columnPattern: {
25
+ type: "string",
26
+ description: "Wildcard pattern for column names (e.g. '%id')."
27
+ },
28
+ limit: {
29
+ type: "number",
30
+ description: "Maximum rows to return per section (default 50, max 200)."
31
+ },
32
+ tableLimit: {
33
+ type: "number",
34
+ description: "Override for table section limit (defaults to limit)."
35
+ },
36
+ columnLimit: {
37
+ type: "number",
38
+ description: "Override for column section limit (defaults to limit)."
39
+ },
40
+ tableOffset: {
41
+ type: "number",
42
+ description: "Number of table rows to skip (for pagination)."
43
+ },
44
+ columnOffset: {
45
+ type: "number",
46
+ description: "Number of column rows to skip (for pagination)."
47
+ }
48
+ }
49
+ };
50
+ }
51
+ normalizePattern(value) {
52
+ if (!value) {
53
+ return null;
54
+ }
55
+ const trimmed = value.trim();
56
+ if (!trimmed) {
57
+ return null;
58
+ }
59
+ return `%${trimmed.replace(/%/g, "%").replace(/_/g, "_")}%`;
60
+ }
61
+ stripWildcards(value) {
62
+ if (!value) {
63
+ return null;
64
+ }
65
+ return value.replace(/[\%_]/g, "").trim() || null;
66
+ }
67
+ normalizeLimit(value, fallback = 50) {
68
+ if (typeof value !== "number" || Number.isNaN(value) || value <= 0) {
69
+ return fallback;
70
+ }
71
+ return Math.min(Math.floor(value), 200);
72
+ }
73
+ normalizeOffset(value) {
74
+ if (typeof value !== "number" || Number.isNaN(value) || value <= 0) {
75
+ return 0;
76
+ }
77
+ return Math.floor(value);
78
+ }
79
+ levenshteinDistance(a, b) {
80
+ const rows = a.length + 1;
81
+ const cols = b.length + 1;
82
+ const matrix = Array.from({ length: rows }, () => Array(cols).fill(0));
83
+ for (let i = 0; i < rows; i++) {
84
+ matrix[i][0] = i;
85
+ }
86
+ for (let j = 0; j < cols; j++) {
87
+ matrix[0][j] = j;
88
+ }
89
+ for (let i = 1; i < rows; i++) {
90
+ for (let j = 1; j < cols; j++) {
91
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
92
+ matrix[i][j] = Math.min(matrix[i - 1][j] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j - 1] + cost);
93
+ }
94
+ }
95
+ return matrix[rows - 1][cols - 1];
96
+ }
97
+ calculateSimilarity(a, b) {
98
+ if (!a || !b) {
99
+ return 0;
100
+ }
101
+ const lowerA = a.toLowerCase();
102
+ const lowerB = b.toLowerCase();
103
+ const distance = this.levenshteinDistance(lowerA, lowerB);
104
+ const maxLength = Math.max(lowerA.length, lowerB.length, 1);
105
+ return 1 - distance / maxLength;
106
+ }
107
+ async findSimilarTables(searchTerm, maxSuggestions, pool) {
108
+ const request = new sql.Request(pool);
109
+ const result = await request.query(`
110
+ SELECT TABLE_SCHEMA AS schemaName, TABLE_NAME AS tableName
111
+ FROM INFORMATION_SCHEMA.TABLES
112
+ `);
113
+ const suggestions = result.recordset
114
+ .map((row) => ({
115
+ ...row,
116
+ similarity: this.calculateSimilarity(row.tableName, searchTerm)
117
+ }))
118
+ .filter((row) => row.similarity >= 0.5)
119
+ .sort((a, b) => b.similarity - a.similarity)
120
+ .slice(0, maxSuggestions)
121
+ .map((row) => ({
122
+ schemaName: row.schemaName,
123
+ tableName: row.tableName,
124
+ similarity: Number(row.similarity.toFixed(3))
125
+ }));
126
+ return suggestions;
127
+ }
128
+ async run(params) {
129
+ try {
130
+ const rawTableSearch = this.stripWildcards(params.tablePattern);
131
+ const tablePattern = this.normalizePattern(params.tablePattern);
132
+ const columnPattern = this.normalizePattern(params.columnPattern);
133
+ const limit = typeof params.limit === "number" && params.limit > 0 ? Math.min(params.limit, 200) : SEARCH_DEFAULT_LIMIT;
134
+ const tableLimit = this.normalizeLimit(params.tableLimit, limit);
135
+ const columnLimit = this.normalizeLimit(params.columnLimit, limit);
136
+ const tableOffset = this.normalizeOffset(params.tableOffset);
137
+ const columnOffset = this.normalizeOffset(params.columnOffset);
138
+ if (!tablePattern && !columnPattern) {
139
+ return {
140
+ success: false,
141
+ message: "Provide at least one of tablePattern or columnPattern."
142
+ };
143
+ }
144
+ const pool = params.pool;
145
+ const tablesRequest = new sql.Request(pool);
146
+ tablesRequest.input("tablePattern", sql.NVarChar, tablePattern);
147
+ tablesRequest.input("tableOffset", sql.Int, tableOffset);
148
+ tablesRequest.input("tablesLimit", sql.Int, tableLimit);
149
+ const columnsRequest = new sql.Request(pool);
150
+ columnsRequest.input("tablePattern", sql.NVarChar, tablePattern);
151
+ columnsRequest.input("columnPattern", sql.NVarChar, columnPattern);
152
+ columnsRequest.input("columnOffset", sql.Int, columnOffset);
153
+ columnsRequest.input("columnLimit", sql.Int, columnLimit);
154
+ const tablesQuery = `
155
+ SELECT TABLE_SCHEMA AS schemaName, TABLE_NAME AS tableName
156
+ FROM INFORMATION_SCHEMA.TABLES
157
+ WHERE (@tablePattern IS NULL OR TABLE_NAME LIKE @tablePattern)
158
+ ORDER BY TABLE_SCHEMA, TABLE_NAME
159
+ OFFSET @tableOffset ROWS
160
+ FETCH NEXT @tablesLimit ROWS ONLY;
161
+
162
+ SELECT COUNT(*) AS total
163
+ FROM INFORMATION_SCHEMA.TABLES
164
+ WHERE (@tablePattern IS NULL OR TABLE_NAME LIKE @tablePattern)`;
165
+ const columnsQuery = `
166
+ SELECT TABLE_SCHEMA AS schemaName, TABLE_NAME AS tableName, COLUMN_NAME AS columnName, DATA_TYPE AS dataType
167
+ FROM INFORMATION_SCHEMA.COLUMNS
168
+ WHERE (@tablePattern IS NULL OR TABLE_NAME LIKE @tablePattern)
169
+ AND (@columnPattern IS NULL OR COLUMN_NAME LIKE @columnPattern)
170
+ ORDER BY TABLE_SCHEMA, TABLE_NAME, ORDINAL_POSITION
171
+ OFFSET @columnOffset ROWS
172
+ FETCH NEXT @columnLimit ROWS ONLY;
173
+
174
+ SELECT COUNT(*) AS total
175
+ FROM INFORMATION_SCHEMA.COLUMNS
176
+ WHERE (@tablePattern IS NULL OR TABLE_NAME LIKE @tablePattern)
177
+ AND (@columnPattern IS NULL OR COLUMN_NAME LIKE @columnPattern)`;
178
+ const [tablesResult, columnsResult] = await Promise.all([
179
+ tablesRequest.query(tablesQuery),
180
+ columnsRequest.query(columnsQuery)
181
+ ]);
182
+ const tableRecordsets = Array.isArray(tablesResult.recordsets) && tablesResult.recordsets.length
183
+ ? tablesResult.recordsets
184
+ : tablesResult.recordset
185
+ ? [tablesResult.recordset]
186
+ : [];
187
+ const columnRecordsets = Array.isArray(columnsResult.recordsets) && columnsResult.recordsets.length
188
+ ? columnsResult.recordsets
189
+ : columnsResult.recordset
190
+ ? [columnsResult.recordset]
191
+ : [];
192
+ const tableRecords = tableRecordsets[0] ?? [];
193
+ const tableTotalRecord = tableRecordsets[1]?.[0];
194
+ const totalTables = typeof tableTotalRecord?.total === "number" ? tableTotalRecord.total : tableRecords.length;
195
+ const columnRecords = columnRecordsets[0] ?? [];
196
+ const columnTotalRecord = columnRecordsets[1]?.[0];
197
+ const totalColumns = typeof columnTotalRecord?.total === "number" ? columnTotalRecord.total : columnRecords.length;
198
+ const response = {
199
+ success: true,
200
+ totalTables,
201
+ totalColumns,
202
+ tables: tableRecords,
203
+ columns: columnRecords,
204
+ tablesPage: {
205
+ offset: tableOffset,
206
+ limit: tableLimit,
207
+ total: totalTables,
208
+ hasMore: tableOffset + tableRecords.length < totalTables
209
+ },
210
+ columnsPage: {
211
+ offset: columnOffset,
212
+ limit: columnLimit,
213
+ total: totalColumns,
214
+ hasMore: columnOffset + columnRecords.length < totalColumns
215
+ }
216
+ };
217
+ const needsFuzzyTables = Boolean(rawTableSearch &&
218
+ !totalTables &&
219
+ !totalColumns);
220
+ if (needsFuzzyTables && rawTableSearch) {
221
+ const fuzzySuggestions = await this.findSimilarTables(rawTableSearch, 10, pool);
222
+ if (fuzzySuggestions.length) {
223
+ response.fuzzySuggestions = fuzzySuggestions;
224
+ response.fuzzySearchTerm = rawTableSearch;
225
+ }
226
+ }
227
+ return response;
228
+ }
229
+ catch (error) {
230
+ return {
231
+ success: false,
232
+ message: `Failed to search schema: ${error}`
233
+ };
234
+ }
235
+ }
236
+ }
237
+ //# sourceMappingURL=SearchSchemaTool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchSchemaTool.js","sourceRoot":"","sources":["../../src/tools/SearchSchemaTool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import { Tool } from "@modelcontextprotocol/sdk/types.js";
2
+ export declare class TestConnectionTool implements Tool {
3
+ [key: string]: any;
4
+ name: string;
5
+ description: string;
6
+ inputSchema: any;
7
+ run(params: any): Promise<{
8
+ success: boolean;
9
+ message: string;
10
+ connected: boolean;
11
+ mcpServerVersion: any;
12
+ latency: {
13
+ connectionMs: number;
14
+ queryMs: number;
15
+ totalMs: number;
16
+ };
17
+ serverInfo: any;
18
+ error?: undefined;
19
+ } | {
20
+ success: boolean;
21
+ message: string;
22
+ connected: boolean;
23
+ latency: {
24
+ totalMs: number;
25
+ connectionMs?: undefined;
26
+ queryMs?: undefined;
27
+ };
28
+ error: {
29
+ code: string;
30
+ suggestion: string;
31
+ };
32
+ mcpServerVersion?: undefined;
33
+ serverInfo?: undefined;
34
+ }>;
35
+ private getEngineEditionName;
36
+ private categorizeError;
37
+ }
38
+ //# sourceMappingURL=TestConnectionTool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TestConnectionTool.d.ts","sourceRoot":"","sources":["../../src/tools/TestConnectionTool.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAG1D,qBAAa,kBAAmB,YAAW,IAAI;IAC7C,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;IACnB,IAAI,SAAqB;IACzB,WAAW,SAAsG;IAEjH,WAAW,EAaN,GAAG,CAAC;IAEH,GAAG,CAAC,MAAM,EAAE,GAAG;;;;;;;;;;;;;;;;;;;;;;kBAyG6B,MAAM;wBAAc,MAAM;;;;;IAf5E,OAAO,CAAC,oBAAoB;IAe5B,OAAO,CAAC,eAAe;CA2CxB"}
@@ -0,0 +1,156 @@
1
+ import sql from "mssql";
2
+ import { getEnvironmentManager } from "../config/EnvironmentManager.js";
3
+ export class TestConnectionTool {
4
+ constructor() {
5
+ this.name = "test_connection";
6
+ this.description = "Tests connectivity to a database environment and returns status, latency, and basic server info.";
7
+ this.inputSchema = {
8
+ type: "object",
9
+ properties: {
10
+ environment: {
11
+ type: "string",
12
+ description: "Optional environment name to test. If not provided, tests the default environment.",
13
+ },
14
+ verbose: {
15
+ type: "boolean",
16
+ description: "If true, returns additional server info (version, edition, etc.)",
17
+ },
18
+ },
19
+ required: [],
20
+ };
21
+ }
22
+ async run(params) {
23
+ const startTime = Date.now();
24
+ const environmentName = params?.environment;
25
+ const verbose = params?.verbose ?? false;
26
+ try {
27
+ const envManager = getEnvironmentManager();
28
+ const env = envManager.getEnvironment(environmentName);
29
+ // Get connection
30
+ const pool = await envManager.getConnection(environmentName);
31
+ const connectionTime = Date.now() - startTime;
32
+ // Run a simple query to verify connectivity
33
+ const queryStart = Date.now();
34
+ const request = new sql.Request(pool);
35
+ const result = await request.query("SELECT 1 AS connected");
36
+ const queryTime = Date.now() - queryStart;
37
+ let serverInfo = {
38
+ environment: env.name,
39
+ server: env.server,
40
+ database: env.database,
41
+ authMode: env.authMode,
42
+ readonly: env.readonly ?? false,
43
+ };
44
+ // Get detailed server info if verbose
45
+ if (verbose) {
46
+ try {
47
+ const infoRequest = new sql.Request(pool);
48
+ const infoResult = await infoRequest.query(`
49
+ SELECT
50
+ SERVERPROPERTY('ProductVersion') AS version,
51
+ SERVERPROPERTY('ProductLevel') AS productLevel,
52
+ SERVERPROPERTY('Edition') AS edition,
53
+ SERVERPROPERTY('EngineEdition') AS engineEdition,
54
+ SERVERPROPERTY('MachineName') AS machineName,
55
+ SERVERPROPERTY('ServerName') AS serverName,
56
+ @@VERSION AS fullVersion
57
+ `);
58
+ if (infoResult.recordset.length > 0) {
59
+ const info = infoResult.recordset[0];
60
+ serverInfo = {
61
+ ...serverInfo,
62
+ version: info.version,
63
+ productLevel: info.productLevel,
64
+ edition: info.edition,
65
+ engineEdition: this.getEngineEditionName(info.engineEdition),
66
+ machineName: info.machineName,
67
+ serverName: info.serverName,
68
+ };
69
+ }
70
+ }
71
+ catch (infoError) {
72
+ // Non-fatal: some queries may not work on all SQL Server editions
73
+ serverInfo.versionInfo = "Unable to retrieve (may require elevated permissions)";
74
+ }
75
+ }
76
+ const totalTime = Date.now() - startTime;
77
+ return {
78
+ success: true,
79
+ message: `Successfully connected to '${env.name}' (${env.server}/${env.database})`,
80
+ connected: true,
81
+ mcpServerVersion: params?.mcpServerVersion,
82
+ latency: {
83
+ connectionMs: connectionTime,
84
+ queryMs: queryTime,
85
+ totalMs: totalTime,
86
+ },
87
+ serverInfo,
88
+ };
89
+ }
90
+ catch (error) {
91
+ const totalTime = Date.now() - startTime;
92
+ const errorMessage = error instanceof Error ? error.message : String(error);
93
+ return {
94
+ success: false,
95
+ message: `Failed to connect: ${errorMessage}`,
96
+ connected: false,
97
+ latency: {
98
+ totalMs: totalTime,
99
+ },
100
+ error: this.categorizeError(errorMessage),
101
+ };
102
+ }
103
+ }
104
+ getEngineEditionName(edition) {
105
+ const editions = {
106
+ 1: "Personal/Desktop Engine",
107
+ 2: "Standard",
108
+ 3: "Enterprise",
109
+ 4: "Express",
110
+ 5: "Azure SQL Database",
111
+ 6: "Azure Synapse Analytics",
112
+ 8: "Azure SQL Managed Instance",
113
+ 9: "Azure SQL Edge",
114
+ 11: "Azure Synapse Serverless",
115
+ };
116
+ return editions[edition] || `Unknown (${edition})`;
117
+ }
118
+ categorizeError(message) {
119
+ const lowerMessage = message.toLowerCase();
120
+ if (lowerMessage.includes("login failed") || lowerMessage.includes("authentication")) {
121
+ return {
122
+ code: "AUTH_FAILED",
123
+ suggestion: "Check username, password, and authentication mode. For AAD, ensure the browser auth completed.",
124
+ };
125
+ }
126
+ if (lowerMessage.includes("network") || lowerMessage.includes("enotfound") || lowerMessage.includes("econnrefused")) {
127
+ return {
128
+ code: "NETWORK_ERROR",
129
+ suggestion: "Check SERVER_NAME, SQL_PORT, and ensure the server is reachable. Verify firewall rules.",
130
+ };
131
+ }
132
+ if (lowerMessage.includes("timeout")) {
133
+ return {
134
+ code: "TIMEOUT",
135
+ suggestion: "Connection timed out. Check network latency and CONNECTION_TIMEOUT setting.",
136
+ };
137
+ }
138
+ if (lowerMessage.includes("certificate") || lowerMessage.includes("ssl")) {
139
+ return {
140
+ code: "CERTIFICATE_ERROR",
141
+ suggestion: "Set TRUST_SERVER_CERTIFICATE=true for self-signed certs, or verify the certificate chain.",
142
+ };
143
+ }
144
+ if (lowerMessage.includes("database") && lowerMessage.includes("not exist")) {
145
+ return {
146
+ code: "DATABASE_NOT_FOUND",
147
+ suggestion: "Check DATABASE_NAME. The specified database may not exist or the user lacks access.",
148
+ };
149
+ }
150
+ return {
151
+ code: "UNKNOWN",
152
+ suggestion: "Check all connection parameters and server logs for more details.",
153
+ };
154
+ }
155
+ }
156
+ //# sourceMappingURL=TestConnectionTool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TestConnectionTool.js","sourceRoot":"","sources":["../../src/tools/TestConnectionTool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ import sql from "mssql";
2
+ import { Tool } from "@modelcontextprotocol/sdk/types.js";
3
+ export declare class UpdateDataTool implements Tool {
4
+ [key: string]: any;
5
+ name: string;
6
+ description: string;
7
+ inputSchema: any;
8
+ private static readonly MAX_ROWS_DEFAULT;
9
+ run(params: any): Promise<{
10
+ success: boolean;
11
+ message: string;
12
+ error: string;
13
+ affectedRows?: undefined;
14
+ maxAllowed?: undefined;
15
+ needsConfirmation?: undefined;
16
+ preview?: undefined;
17
+ updates?: undefined;
18
+ rowsAffected?: undefined;
19
+ } | {
20
+ success: boolean;
21
+ message: string;
22
+ error: string;
23
+ affectedRows: number;
24
+ maxAllowed?: undefined;
25
+ needsConfirmation?: undefined;
26
+ preview?: undefined;
27
+ updates?: undefined;
28
+ rowsAffected?: undefined;
29
+ } | {
30
+ success: boolean;
31
+ message: string;
32
+ error: string;
33
+ affectedRows: any;
34
+ maxAllowed: any;
35
+ needsConfirmation?: undefined;
36
+ preview?: undefined;
37
+ updates?: undefined;
38
+ rowsAffected?: undefined;
39
+ } | {
40
+ success: boolean;
41
+ needsConfirmation: boolean;
42
+ message: string;
43
+ affectedRows: any;
44
+ preview: sql.IRecordSet<any>;
45
+ updates: any;
46
+ error: string;
47
+ maxAllowed?: undefined;
48
+ rowsAffected?: undefined;
49
+ } | {
50
+ success: boolean;
51
+ message: string;
52
+ rowsAffected: number;
53
+ updates: any;
54
+ error?: undefined;
55
+ affectedRows?: undefined;
56
+ maxAllowed?: undefined;
57
+ needsConfirmation?: undefined;
58
+ preview?: undefined;
59
+ }>;
60
+ }
61
+ //# sourceMappingURL=UpdateDataTool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UpdateDataTool.d.ts","sourceRoot":"","sources":["../../src/tools/UpdateDataTool.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,OAAO,CAAC;AACxB,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAE1D,qBAAa,cAAe,YAAW,IAAI;IACzC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;IACnB,IAAI,SAAiB;IACrB,WAAW,SAAqG;IAChH,WAAW,EA6BN,GAAG,CAAC;IAET,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAQ;IAE1C,GAAG,CAAC,MAAM,EAAE,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwFtB"}
@@ -0,0 +1,117 @@
1
+ import sql from "mssql";
2
+ export class UpdateDataTool {
3
+ constructor() {
4
+ this.name = "update_data";
5
+ this.description = "Updates rows in an MSSQL table with preview and confirmation. Requires WHERE clause for safety.";
6
+ this.inputSchema = {
7
+ type: "object",
8
+ properties: {
9
+ tableName: {
10
+ type: "string",
11
+ description: "Name of the table to update"
12
+ },
13
+ updates: {
14
+ type: "object",
15
+ description: "Key-value pairs of columns to update. Example: { 'status': 'active', 'last_updated': '2025-01-01' }",
16
+ },
17
+ whereClause: {
18
+ type: "string",
19
+ description: "WHERE clause to identify which records to update. Example: \"genre = 'comedy' AND created_date <= '2025-07-05'\""
20
+ },
21
+ confirmUpdate: {
22
+ type: "boolean",
23
+ description: "Set to true to confirm and execute the update after preview. First call without this to see preview.",
24
+ },
25
+ maxRows: {
26
+ type: "number",
27
+ description: "Maximum number of rows allowed to update. Defaults to 1000 for safety.",
28
+ },
29
+ environment: {
30
+ type: "string",
31
+ description: "Optional environment name to target",
32
+ },
33
+ },
34
+ required: ["tableName", "updates", "whereClause"],
35
+ };
36
+ }
37
+ async run(params) {
38
+ let query;
39
+ try {
40
+ const { tableName, updates, whereClause, confirmUpdate, maxRows, environment } = params;
41
+ // Basic validation: ensure whereClause is not empty
42
+ if (!whereClause || whereClause.trim() === '') {
43
+ return {
44
+ success: false,
45
+ message: "WHERE clause is required for security reasons. Use 'WHERE 1=1' to update all rows (not recommended).",
46
+ error: "MISSING_WHERE_CLAUSE",
47
+ };
48
+ }
49
+ const maxAllowed = maxRows || UpdateDataTool.MAX_ROWS_DEFAULT;
50
+ // Step 1: Get count of affected rows
51
+ const countQuery = `SELECT COUNT(*) as affectedRows FROM ${tableName} WHERE ${whereClause}`;
52
+ const countRequest = new sql.Request(params.pool);
53
+ const countResult = await countRequest.query(countQuery);
54
+ const affectedRows = countResult.recordset[0].affectedRows;
55
+ if (affectedRows === 0) {
56
+ return {
57
+ success: false,
58
+ message: "No rows match the WHERE clause. No update will be performed.",
59
+ error: "NO_ROWS_MATCHED",
60
+ affectedRows: 0,
61
+ };
62
+ }
63
+ if (affectedRows > maxAllowed) {
64
+ return {
65
+ success: false,
66
+ message: `Update would affect ${affectedRows} rows, which exceeds the maximum of ${maxAllowed}. Refine your WHERE clause or increase maxRows parameter.`,
67
+ error: "TOO_MANY_ROWS",
68
+ affectedRows,
69
+ maxAllowed,
70
+ };
71
+ }
72
+ // Step 2: Show preview if not confirmed
73
+ if (!confirmUpdate) {
74
+ const previewQuery = `SELECT TOP 10 * FROM ${tableName} WHERE ${whereClause}`;
75
+ const previewRequest = new sql.Request(params.pool);
76
+ const previewResult = await previewRequest.query(previewQuery);
77
+ return {
78
+ success: false,
79
+ needsConfirmation: true,
80
+ message: `Preview: ${affectedRows} row(s) will be updated. Review the preview below and re-run with confirmUpdate: true to proceed.`,
81
+ affectedRows,
82
+ preview: previewResult.recordset,
83
+ updates,
84
+ error: "CONFIRMATION_REQUIRED",
85
+ };
86
+ }
87
+ // Step 3: Execute the update
88
+ const request = new sql.Request(params.pool);
89
+ // Build SET clause with parameterized queries for security
90
+ const setClause = Object.keys(updates)
91
+ .map((key, index) => {
92
+ const paramName = `update_${index}`;
93
+ request.input(paramName, updates[key]);
94
+ return `[${key}] = @${paramName}`;
95
+ })
96
+ .join(", ");
97
+ query = `UPDATE ${tableName} SET ${setClause} WHERE ${whereClause}`;
98
+ const result = await request.query(query);
99
+ return {
100
+ success: true,
101
+ message: `Successfully updated ${result.rowsAffected[0]} row(s) in table '${tableName}'`,
102
+ rowsAffected: result.rowsAffected[0],
103
+ updates,
104
+ };
105
+ }
106
+ catch (error) {
107
+ console.error("Error updating data:", error);
108
+ return {
109
+ success: false,
110
+ message: `Failed to update data${query ? ` with '${query}'` : ''}: ${error}`,
111
+ error: "UPDATE_FAILED",
112
+ };
113
+ }
114
+ }
115
+ }
116
+ UpdateDataTool.MAX_ROWS_DEFAULT = 1000;
117
+ //# sourceMappingURL=UpdateDataTool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UpdateDataTool.js","sourceRoot":"","sources":["../../src/tools/UpdateDataTool.ts"],"names":[],"mappings":"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"}