@eamonboyle/mssql-mcp 1.1.0 → 1.2.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/README.md +134 -22
  2. package/dist/__tests__/ExplainQueryTool.test.d.ts +2 -0
  3. package/dist/__tests__/ExplainQueryTool.test.d.ts.map +1 -0
  4. package/dist/__tests__/ExplainQueryTool.test.js +96 -0
  5. package/dist/__tests__/ExplainQueryTool.test.js.map +1 -0
  6. package/dist/__tests__/config.test.d.ts +2 -0
  7. package/dist/__tests__/config.test.d.ts.map +1 -0
  8. package/dist/__tests__/config.test.js +29 -0
  9. package/dist/__tests__/config.test.js.map +1 -0
  10. package/dist/__tests__/db.test.d.ts +1 -1
  11. package/dist/__tests__/db.test.js +203 -203
  12. package/dist/__tests__/promptRegistry.test.d.ts +2 -0
  13. package/dist/__tests__/promptRegistry.test.d.ts.map +1 -0
  14. package/dist/__tests__/promptRegistry.test.js +40 -0
  15. package/dist/__tests__/promptRegistry.test.js.map +1 -0
  16. package/dist/__tests__/resourceRegistry.test.d.ts +2 -0
  17. package/dist/__tests__/resourceRegistry.test.d.ts.map +1 -0
  18. package/dist/__tests__/resourceRegistry.test.js +40 -0
  19. package/dist/__tests__/resourceRegistry.test.js.map +1 -0
  20. package/dist/__tests__/schema.test.d.ts +2 -0
  21. package/dist/__tests__/schema.test.d.ts.map +1 -0
  22. package/dist/__tests__/schema.test.js +130 -0
  23. package/dist/__tests__/schema.test.js.map +1 -0
  24. package/dist/__tests__/sql.test.d.ts +2 -0
  25. package/dist/__tests__/sql.test.d.ts.map +1 -0
  26. package/dist/__tests__/sql.test.js +35 -0
  27. package/dist/__tests__/sql.test.js.map +1 -0
  28. package/dist/__tests__/toolRegistry.test.d.ts +2 -0
  29. package/dist/__tests__/toolRegistry.test.d.ts.map +1 -0
  30. package/dist/__tests__/toolRegistry.test.js +47 -0
  31. package/dist/__tests__/toolRegistry.test.js.map +1 -0
  32. package/dist/__tests__/validation.test.d.ts +1 -1
  33. package/dist/__tests__/validation.test.js +110 -110
  34. package/dist/__tests__/validation.test.js.map +1 -1
  35. package/dist/__tests__/writeTools.test.d.ts +2 -0
  36. package/dist/__tests__/writeTools.test.d.ts.map +1 -0
  37. package/dist/__tests__/writeTools.test.js +115 -0
  38. package/dist/__tests__/writeTools.test.js.map +1 -0
  39. package/dist/config.d.ts +5 -0
  40. package/dist/config.d.ts.map +1 -0
  41. package/dist/config.js +34 -0
  42. package/dist/config.js.map +1 -0
  43. package/dist/db.d.ts +28 -24
  44. package/dist/db.d.ts.map +1 -1
  45. package/dist/db.js +144 -112
  46. package/dist/db.js.map +1 -1
  47. package/dist/index.d.ts +2 -2
  48. package/dist/index.js +70 -122
  49. package/dist/index.js.map +1 -1
  50. package/dist/promptRegistry.d.ts +16 -0
  51. package/dist/promptRegistry.d.ts.map +1 -0
  52. package/dist/promptRegistry.js +107 -0
  53. package/dist/promptRegistry.js.map +1 -0
  54. package/dist/resourceRegistry.d.ts +12 -0
  55. package/dist/resourceRegistry.d.ts.map +1 -0
  56. package/dist/resourceRegistry.js +172 -0
  57. package/dist/resourceRegistry.js.map +1 -0
  58. package/dist/schema.d.ts +41 -0
  59. package/dist/schema.d.ts.map +1 -0
  60. package/dist/schema.js +211 -0
  61. package/dist/schema.js.map +1 -0
  62. package/dist/sql.d.ts +7 -0
  63. package/dist/sql.d.ts.map +1 -0
  64. package/dist/sql.js +73 -0
  65. package/dist/sql.js.map +1 -0
  66. package/dist/toolRegistry.d.ts +16 -0
  67. package/dist/toolRegistry.d.ts.map +1 -0
  68. package/dist/toolRegistry.js +401 -0
  69. package/dist/toolRegistry.js.map +1 -0
  70. package/dist/tools/CreateIndexTool.d.ts +30 -23
  71. package/dist/tools/CreateIndexTool.d.ts.map +1 -1
  72. package/dist/tools/CreateIndexTool.js +47 -77
  73. package/dist/tools/CreateIndexTool.js.map +1 -1
  74. package/dist/tools/CreateTableTool.d.ts +18 -11
  75. package/dist/tools/CreateTableTool.d.ts.map +1 -1
  76. package/dist/tools/CreateTableTool.js +37 -61
  77. package/dist/tools/CreateTableTool.js.map +1 -1
  78. package/dist/tools/DeleteDataTool.d.ts +22 -0
  79. package/dist/tools/DeleteDataTool.d.ts.map +1 -0
  80. package/dist/tools/DeleteDataTool.js +35 -0
  81. package/dist/tools/DeleteDataTool.js.map +1 -0
  82. package/dist/tools/DescribeObjectTool.d.ts +21 -0
  83. package/dist/tools/DescribeObjectTool.d.ts.map +1 -0
  84. package/dist/tools/DescribeObjectTool.js +31 -0
  85. package/dist/tools/DescribeObjectTool.js.map +1 -0
  86. package/dist/tools/DescribeTableTool.d.ts +19 -20
  87. package/dist/tools/DescribeTableTool.d.ts.map +1 -1
  88. package/dist/tools/DescribeTableTool.js +23 -44
  89. package/dist/tools/DescribeTableTool.js.map +1 -1
  90. package/dist/tools/DropTableTool.d.ts +13 -11
  91. package/dist/tools/DropTableTool.d.ts.map +1 -1
  92. package/dist/tools/DropTableTool.js +30 -44
  93. package/dist/tools/DropTableTool.js.map +1 -1
  94. package/dist/tools/ExplainQueryTool.d.ts +32 -0
  95. package/dist/tools/ExplainQueryTool.d.ts.map +1 -0
  96. package/dist/tools/ExplainQueryTool.js +102 -0
  97. package/dist/tools/ExplainQueryTool.js.map +1 -0
  98. package/dist/tools/InsertDataTool.d.ts +20 -16
  99. package/dist/tools/InsertDataTool.d.ts.map +1 -1
  100. package/dist/tools/InsertDataTool.js +91 -108
  101. package/dist/tools/InsertDataTool.js.map +1 -1
  102. package/dist/tools/ListObjectsTool.d.ts +20 -0
  103. package/dist/tools/ListObjectsTool.d.ts.map +1 -0
  104. package/dist/tools/ListObjectsTool.js +26 -0
  105. package/dist/tools/ListObjectsTool.js.map +1 -0
  106. package/dist/tools/ListTableTool.d.ts +20 -16
  107. package/dist/tools/ListTableTool.d.ts.map +1 -1
  108. package/dist/tools/ListTableTool.js +32 -51
  109. package/dist/tools/ListTableTool.js.map +1 -1
  110. package/dist/tools/ReadDataTool.d.ts +35 -33
  111. package/dist/tools/ReadDataTool.d.ts.map +1 -1
  112. package/dist/tools/ReadDataTool.js +92 -105
  113. package/dist/tools/ReadDataTool.js.map +1 -1
  114. package/dist/tools/SearchDataTool.d.ts +27 -0
  115. package/dist/tools/SearchDataTool.d.ts.map +1 -0
  116. package/dist/tools/SearchDataTool.js +61 -0
  117. package/dist/tools/SearchDataTool.js.map +1 -0
  118. package/dist/tools/UpdateDataTool.d.ts +21 -16
  119. package/dist/tools/UpdateDataTool.d.ts.map +1 -1
  120. package/dist/tools/UpdateDataTool.js +45 -65
  121. package/dist/tools/UpdateDataTool.js.map +1 -1
  122. package/dist/validation.d.ts +13 -13
  123. package/dist/validation.js +133 -133
  124. package/dist/validation.js.map +1 -1
  125. package/dist/writeSafety.d.ts +21 -0
  126. package/dist/writeSafety.d.ts.map +1 -0
  127. package/dist/writeSafety.js +169 -0
  128. package/dist/writeSafety.js.map +1 -0
  129. package/package.json +5 -4
@@ -1,106 +1,93 @@
1
- import { getSqlRequest } from "../db.js";
2
- import { validateReadQuery } from "../validation.js";
3
- export class ReadDataTool {
4
- constructor() {
5
- this.name = "read_data";
6
- this.description = "Executes a SELECT query on an MSSQL Database table. The query must start with SELECT and cannot contain any destructive SQL operations for security reasons.";
7
- this.inputSchema = {
8
- type: "object",
9
- properties: {
10
- query: {
11
- type: "string",
12
- description: "SQL SELECT query to execute (must start with SELECT and cannot contain destructive operations). Example: SELECT * FROM movies WHERE genre = 'comedy'",
13
- },
14
- databaseName: {
15
- type: "string",
16
- description: "Name of the database to query (optional). Omit to use the default configured database.",
17
- },
18
- },
19
- required: ["query"],
20
- };
21
- }
22
- /**
23
- * Sanitizes the query result to prevent any potential security issues
24
- * @param data The query result data
25
- * @returns Sanitized data
26
- */
27
- sanitizeResult(data) {
28
- if (!Array.isArray(data)) {
29
- return [];
30
- }
31
- // Limit the number of returned records to prevent memory issues
32
- const maxRecords = 10000;
33
- if (data.length > maxRecords) {
34
- console.warn(`Query returned ${data.length} records, limiting to ${maxRecords}`);
35
- return data.slice(0, maxRecords);
36
- }
37
- return data.map((record) => {
38
- if (typeof record === "object" && record !== null) {
39
- const sanitized = {};
40
- for (const [key, value] of Object.entries(record)) {
41
- // Sanitize column names (remove any suspicious characters)
42
- const sanitizedKey = key.replace(/[^\w\s-_.]/g, "");
43
- if (sanitizedKey !== key) {
44
- console.warn(`Column name sanitized: ${key} -> ${sanitizedKey}`);
45
- }
46
- sanitized[sanitizedKey] = value;
47
- }
48
- return sanitized;
49
- }
50
- return record;
51
- });
52
- }
53
- /**
54
- * Executes the validated SQL query
55
- * @param params Query parameters
56
- * @returns Query execution result
57
- */
58
- async run(params) {
59
- try {
60
- const { query, databaseName } = params;
61
- const { request, error } = await getSqlRequest(databaseName);
62
- if (error) {
63
- return { success: false, message: error, error: "INVALID_DATABASE" };
64
- }
65
- // Validate the query for security issues
66
- const validation = validateReadQuery(query);
67
- if (!validation.isValid) {
68
- console.warn(`Security validation failed for query: ${query.substring(0, 100)}...`);
69
- return {
70
- success: false,
71
- message: `Security validation failed: ${validation.error}`,
72
- error: "SECURITY_VALIDATION_FAILED",
73
- };
74
- }
75
- // Log the query for audit purposes (in production, consider more secure logging)
76
- console.log(`Executing validated SELECT query: ${query.substring(0, 200)}${query.length > 200 ? "..." : ""}`);
77
- // Execute the query
78
- const result = await request.query(query);
79
- // Sanitize the result
80
- const sanitizedData = this.sanitizeResult(result.recordset);
81
- return {
82
- success: true,
83
- message: `Query executed successfully. Retrieved ${sanitizedData.length} record(s)${result.recordset.length !== sanitizedData.length
84
- ? ` (limited from ${result.recordset.length} total records)`
85
- : ""}`,
86
- data: sanitizedData,
87
- recordCount: sanitizedData.length,
88
- totalRecords: result.recordset.length,
89
- };
90
- }
91
- catch (error) {
92
- console.error("Error executing query:", error);
93
- // Don't expose internal error details to prevent information leakage
94
- const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
95
- const safeErrorMessage = errorMessage.includes("Invalid object name")
96
- ? errorMessage
97
- : "Database query execution failed";
98
- return {
99
- success: false,
100
- message: `Failed to execute query: ${safeErrorMessage}`,
101
- error: "QUERY_EXECUTION_FAILED",
102
- };
103
- }
104
- }
105
- }
1
+ import { getMaxRows } from "../config.js";
2
+ import { getSqlRequest } from "../db.js";
3
+ import { validateReadQuery } from "../validation.js";
4
+ export class ReadDataTool {
5
+ constructor() {
6
+ this.name = "read_data";
7
+ this.description = "Executes a SELECT query on an MSSQL Database table. The query must start with SELECT and cannot contain any destructive SQL operations for security reasons.";
8
+ }
9
+ /**
10
+ * Sanitizes the query result to prevent any potential security issues
11
+ * @param data The query result data
12
+ * @returns Sanitized data
13
+ */
14
+ sanitizeResult(data) {
15
+ if (!Array.isArray(data)) {
16
+ return [];
17
+ }
18
+ // Limit the number of returned records to prevent memory issues
19
+ const maxRecords = getMaxRows();
20
+ if (data.length > maxRecords) {
21
+ console.warn(`Query returned ${data.length} records, limiting to ${maxRecords}`);
22
+ return data.slice(0, maxRecords);
23
+ }
24
+ return data.map((record) => {
25
+ if (typeof record === "object" && record !== null) {
26
+ const sanitized = {};
27
+ for (const [key, value] of Object.entries(record)) {
28
+ // Sanitize column names (remove any suspicious characters)
29
+ const sanitizedKey = key.replace(/[^\w\s-_.]/g, "");
30
+ if (sanitizedKey !== key) {
31
+ console.warn(`Column name sanitized: ${key} -> ${sanitizedKey}`);
32
+ }
33
+ sanitized[sanitizedKey] = value;
34
+ }
35
+ return sanitized;
36
+ }
37
+ return record;
38
+ });
39
+ }
40
+ /**
41
+ * Executes the validated SQL query
42
+ * @param params Query parameters
43
+ * @returns Query execution result
44
+ */
45
+ async run(params) {
46
+ try {
47
+ const { query, databaseName } = params;
48
+ const { request, error } = await getSqlRequest(databaseName);
49
+ if (error) {
50
+ return { success: false, message: error, error: "INVALID_DATABASE" };
51
+ }
52
+ // Validate the query for security issues
53
+ const validation = validateReadQuery(query);
54
+ if (!validation.isValid) {
55
+ console.warn(`Security validation failed for query: ${query.substring(0, 100)}...`);
56
+ return {
57
+ success: false,
58
+ message: `Security validation failed: ${validation.error}`,
59
+ error: "SECURITY_VALIDATION_FAILED",
60
+ };
61
+ }
62
+ // Log the query for audit purposes (in production, consider more secure logging)
63
+ console.log(`Executing validated SELECT query: ${query.substring(0, 200)}${query.length > 200 ? "..." : ""}`);
64
+ // Execute the query
65
+ const result = await request.query(query);
66
+ // Sanitize the result
67
+ const sanitizedData = this.sanitizeResult(result.recordset);
68
+ return {
69
+ success: true,
70
+ message: `Query executed successfully. Retrieved ${sanitizedData.length} record(s)${result.recordset.length !== sanitizedData.length
71
+ ? ` (limited from ${result.recordset.length} total records)`
72
+ : ""}`,
73
+ data: sanitizedData,
74
+ recordCount: sanitizedData.length,
75
+ totalRecords: result.recordset.length,
76
+ };
77
+ }
78
+ catch (error) {
79
+ console.error("Error executing query:", error);
80
+ // Don't expose internal error details to prevent information leakage
81
+ const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
82
+ const safeErrorMessage = errorMessage.includes("Invalid object name")
83
+ ? errorMessage
84
+ : "Database query execution failed";
85
+ return {
86
+ success: false,
87
+ message: `Failed to execute query: ${safeErrorMessage}`,
88
+ error: "QUERY_EXECUTION_FAILED",
89
+ };
90
+ }
91
+ }
92
+ }
106
93
  //# sourceMappingURL=ReadDataTool.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ReadDataTool.js","sourceRoot":"","sources":["../../src/tools/ReadDataTool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ReadDataTool.js","sourceRoot":"","sources":["../../src/tools/ReadDataTool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ interface SearchDataParams {
2
+ tableName: string;
3
+ schemaName?: string;
4
+ columns: string[];
5
+ searchTerm: string;
6
+ limit?: number;
7
+ databaseName?: string;
8
+ }
9
+ export declare class SearchDataTool {
10
+ name: string;
11
+ description: string;
12
+ run(params: SearchDataParams): Promise<{
13
+ success: boolean;
14
+ message: string;
15
+ data?: undefined;
16
+ recordCount?: undefined;
17
+ limit?: undefined;
18
+ } | {
19
+ success: boolean;
20
+ message: string;
21
+ data: import("mssql").IRecordSet<any>;
22
+ recordCount: number;
23
+ limit: number;
24
+ }>;
25
+ }
26
+ export {};
27
+ //# sourceMappingURL=SearchDataTool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchDataTool.d.ts","sourceRoot":"","sources":["../../src/tools/SearchDataTool.ts"],"names":[],"mappings":"AAIA,UAAU,gBAAgB;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,cAAc;IACzB,IAAI,SAAiB;IACrB,WAAW,SACsF;IAE3F,GAAG,CAAC,MAAM,EAAE,gBAAgB;;;;;;;;;;;;;CA+DnC"}
@@ -0,0 +1,61 @@
1
+ import { clampRowLimit, getDefaultSearchLimit } from "../config.js";
2
+ import { getSqlRequest } from "../db.js";
3
+ import { buildQualifiedName, quoteIdentifier } from "../sql.js";
4
+ export class SearchDataTool {
5
+ constructor() {
6
+ this.name = "search_data";
7
+ this.description = "Searches rows in a table by applying a parameterized LIKE filter across one or more columns.";
8
+ }
9
+ async run(params) {
10
+ try {
11
+ const { tableName, schemaName, columns, searchTerm, limit, databaseName, } = params;
12
+ if (!Array.isArray(columns) || columns.length === 0) {
13
+ return {
14
+ success: false,
15
+ message: "The 'columns' field must be a non-empty array.",
16
+ };
17
+ }
18
+ if (typeof searchTerm !== "string" || searchTerm.trim() === "") {
19
+ return {
20
+ success: false,
21
+ message: "The 'searchTerm' field must be a non-empty string.",
22
+ };
23
+ }
24
+ const { request, error } = await getSqlRequest(databaseName);
25
+ if (error) {
26
+ return { success: false, message: error };
27
+ }
28
+ const qualifiedTableName = buildQualifiedName(tableName, schemaName);
29
+ const safeColumns = columns.map((column) => quoteIdentifier(column));
30
+ const top = clampRowLimit(limit, getDefaultSearchLimit());
31
+ const whereClause = safeColumns
32
+ .map((columnName, index) => {
33
+ const parameterName = `search_${index}`;
34
+ request.input(parameterName, `%${searchTerm.trim()}%`);
35
+ return `${columnName} LIKE @${parameterName}`;
36
+ })
37
+ .join(" OR ");
38
+ const query = `
39
+ SELECT TOP (${top}) *
40
+ FROM ${qualifiedTableName}
41
+ WHERE ${whereClause}
42
+ `;
43
+ const result = await request.query(query);
44
+ return {
45
+ success: true,
46
+ message: `Search completed successfully. Retrieved ${result.recordset.length} row(s).`,
47
+ data: result.recordset,
48
+ recordCount: result.recordset.length,
49
+ limit: top,
50
+ };
51
+ }
52
+ catch (error) {
53
+ console.error("Error searching data:", error);
54
+ return {
55
+ success: false,
56
+ message: `Failed to search data: ${error}`,
57
+ };
58
+ }
59
+ }
60
+ }
61
+ //# sourceMappingURL=SearchDataTool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchDataTool.js","sourceRoot":"","sources":["../../src/tools/SearchDataTool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAWhE,MAAM,OAAO,cAAc;IAA3B;QACE,SAAI,GAAG,aAAa,CAAC;QACrB,gBAAW,GACT,8FAA8F,CAAC;IAiEnG,CAAC;IA/DC,KAAK,CAAC,GAAG,CAAC,MAAwB;QAChC,IAAI,CAAC;YACH,MAAM,EACJ,SAAS,EACT,UAAU,EACV,OAAO,EACP,UAAU,EACV,KAAK,EACL,YAAY,GACb,GAAG,MAAM,CAAC;YAEX,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACpD,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,OAAO,EAAE,gDAAgD;iBAC1D,CAAC;YACJ,CAAC;YAED,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBAC/D,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,OAAO,EAAE,oDAAoD;iBAC9D,CAAC;YACJ,CAAC;YAED,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,aAAa,CAAC,YAAY,CAAC,CAAC;YAC7D,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;YAC5C,CAAC;YAED,MAAM,kBAAkB,GAAG,kBAAkB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;YACrE,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAc,EAAE,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;YAC7E,MAAM,GAAG,GAAG,aAAa,CAAC,KAAK,EAAE,qBAAqB,EAAE,CAAC,CAAC;YAC1D,MAAM,WAAW,GAAG,WAAW;iBAC5B,GAAG,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,EAAE;gBACzB,MAAM,aAAa,GAAG,UAAU,KAAK,EAAE,CAAC;gBACxC,OAAO,CAAC,KAAK,CAAC,aAAa,EAAE,IAAI,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;gBACvD,OAAO,GAAG,UAAU,UAAU,aAAa,EAAE,CAAC;YAChD,CAAC,CAAC;iBACD,IAAI,CAAC,MAAM,CAAC,CAAC;YAEhB,MAAM,KAAK,GAAG;sBACE,GAAG;eACV,kBAAkB;gBACjB,WAAW;OACpB,CAAC;YACF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAE1C,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,4CAA4C,MAAM,CAAC,SAAS,CAAC,MAAM,UAAU;gBACtF,IAAI,EAAE,MAAM,CAAC,SAAS;gBACtB,WAAW,EAAE,MAAM,CAAC,SAAS,CAAC,MAAM;gBACpC,KAAK,EAAE,GAAG;aACX,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;YAC9C,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,0BAA0B,KAAK,EAAE;aAC3C,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
@@ -1,17 +1,22 @@
1
- import { Tool } from "@modelcontextprotocol/sdk/types.js";
2
- export declare class UpdateDataTool 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
- rowsAffected?: undefined;
11
- } | {
12
- success: boolean;
13
- message: string;
14
- rowsAffected: number;
15
- }>;
16
- }
1
+ import { type SqlFilter } from "../writeSafety.js";
2
+ interface UpdateDataParams {
3
+ tableName: string;
4
+ updates: Record<string, unknown>;
5
+ filters: SqlFilter[];
6
+ databaseName?: string;
7
+ }
8
+ export declare class UpdateDataTool {
9
+ name: string;
10
+ description: string;
11
+ run(params: UpdateDataParams): Promise<{
12
+ success: boolean;
13
+ message: string;
14
+ rowsAffected?: undefined;
15
+ } | {
16
+ success: boolean;
17
+ message: string;
18
+ rowsAffected: number;
19
+ }>;
20
+ }
21
+ export {};
17
22
  //# sourceMappingURL=UpdateDataTool.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"UpdateDataTool.d.ts","sourceRoot":"","sources":["../../src/tools/UpdateDataTool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAG1D,qBAAa,cAAe,YAAW,IAAI;IACzC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;IACnB,IAAI,SAAiB;IACrB,WAAW,SACuG;IAClH,WAAW,MAwBF;IAEH,GAAG,CAAC,MAAM,EAAE,GAAG;;;;;;;;;CAwCtB"}
1
+ {"version":3,"file":"UpdateDataTool.d.ts","sourceRoot":"","sources":["../../src/tools/UpdateDataTool.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiC,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAElF,UAAU,gBAAgB;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,cAAc;IACzB,IAAI,SAAiB;IACrB,WAAW,SACoE;IAEzE,GAAG,CAAC,MAAM,EAAE,gBAAgB;;;;;;;;;CA6CnC"}
@@ -1,66 +1,46 @@
1
- import { getSqlRequest } from "../db.js";
2
- export class UpdateDataTool {
3
- constructor() {
4
- this.name = "update_data";
5
- this.description = "Updates data in an MSSQL Database table using a WHERE clause. The WHERE clause must be provided for security.";
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
- databaseName: {
22
- type: "string",
23
- description: "Name of the database to use (optional). Omit to use the default configured database.",
24
- },
25
- },
26
- required: ["tableName", "updates", "whereClause"],
27
- };
28
- }
29
- async run(params) {
30
- let query;
31
- try {
32
- const { tableName, updates, whereClause, databaseName } = params;
33
- const { request, error } = await getSqlRequest(databaseName);
34
- if (error) {
35
- return { success: false, message: error };
36
- }
37
- // Basic validation: ensure whereClause is not empty
38
- if (!whereClause || whereClause.trim() === "") {
39
- throw new Error("WHERE clause is required for security reasons");
40
- }
41
- // Build SET clause with parameterized queries for security
42
- const setClause = Object.keys(updates)
43
- .map((key, index) => {
44
- const paramName = `update_${index}`;
45
- request.input(paramName, updates[key]);
46
- return `[${key}] = @${paramName}`;
47
- })
48
- .join(", ");
49
- query = `UPDATE ${tableName} SET ${setClause} WHERE ${whereClause}`;
50
- const result = await request.query(query);
51
- return {
52
- success: true,
53
- message: `Update completed successfully. ${result.rowsAffected[0]} row(s) affected`,
54
- rowsAffected: result.rowsAffected[0],
55
- };
56
- }
57
- catch (error) {
58
- console.error("Error updating data:", error);
59
- return {
60
- success: false,
61
- message: `Failed to update data ${query ? ` with '${query}'` : ""}: ${error}`,
62
- };
63
- }
64
- }
65
- }
1
+ import { getSqlRequest } from "../db.js";
2
+ import { buildQualifiedName, quoteIdentifier } from "../sql.js";
3
+ import { buildParameterizedWhereClause } from "../writeSafety.js";
4
+ export class UpdateDataTool {
5
+ constructor() {
6
+ this.name = "update_data";
7
+ this.description = "Updates data in an MSSQL Database table using required structured filters.";
8
+ }
9
+ async run(params) {
10
+ let query;
11
+ try {
12
+ const { tableName, updates, filters, databaseName } = params;
13
+ const { request, error } = await getSqlRequest(databaseName);
14
+ if (error) {
15
+ return { success: false, message: error };
16
+ }
17
+ const updateColumns = Object.keys(updates);
18
+ if (updateColumns.length === 0) {
19
+ throw new Error("At least one column update is required.");
20
+ }
21
+ const setClause = updateColumns
22
+ .map((key, index) => {
23
+ const paramName = `update_${index}`;
24
+ request.input(paramName, updates[key]);
25
+ return `${quoteIdentifier(key)} = @${paramName}`;
26
+ })
27
+ .join(", ");
28
+ const whereClause = buildParameterizedWhereClause(filters, (name, value) => request.input(name, value), "update_filter");
29
+ query = `UPDATE ${buildQualifiedName(tableName)} SET ${setClause} WHERE ${whereClause}`;
30
+ const result = await request.query(query);
31
+ return {
32
+ success: true,
33
+ message: `Update completed successfully. ${result.rowsAffected[0]} row(s) affected`,
34
+ rowsAffected: result.rowsAffected[0],
35
+ };
36
+ }
37
+ catch (error) {
38
+ console.error("Error updating data:", error);
39
+ return {
40
+ success: false,
41
+ message: `Failed to update data ${query ? ` with '${query}'` : ""}: ${error}`,
42
+ };
43
+ }
44
+ }
45
+ }
66
46
  //# sourceMappingURL=UpdateDataTool.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"UpdateDataTool.js","sourceRoot":"","sources":["../../src/tools/UpdateDataTool.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,OAAO,cAAc;IAA3B;QAEE,SAAI,GAAG,aAAa,CAAC;QACrB,gBAAW,GACT,+GAA+G,CAAC;QAClH,gBAAW,GAAG;YACZ,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,SAAS,EAAE;oBACT,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,6BAA6B;iBAC3C;gBACD,OAAO,EAAE;oBACP,IAAI,EAAE,QAAQ;oBACd,WAAW,EACT,qGAAqG;iBACxG;gBACD,WAAW,EAAE;oBACX,IAAI,EAAE,QAAQ;oBACd,WAAW,EACT,kHAAkH;iBACrH;gBACD,YAAY,EAAE;oBACZ,IAAI,EAAE,QAAQ;oBACd,WAAW,EACT,sFAAsF;iBACzF;aACF;YACD,QAAQ,EAAE,CAAC,WAAW,EAAE,SAAS,EAAE,aAAa,CAAC;SAC3C,CAAC;IA0CX,CAAC;IAxCC,KAAK,CAAC,GAAG,CAAC,MAAW;QACnB,IAAI,KAAyB,CAAC;QAC9B,IAAI;YACF,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;YAEjE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,aAAa,CAAC,YAAY,CAAC,CAAC;YAC7D,IAAI,KAAK,EAAE;gBACT,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;aAC3C;YAED,oDAAoD;YACpD,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;gBAC7C,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;aAClE;YAED,2DAA2D;YAC3D,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;iBACnC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;gBAClB,MAAM,SAAS,GAAG,UAAU,KAAK,EAAE,CAAC;gBACpC,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;gBACvC,OAAO,IAAI,GAAG,QAAQ,SAAS,EAAE,CAAC;YACpC,CAAC,CAAC;iBACD,IAAI,CAAC,IAAI,CAAC,CAAC;YAEd,KAAK,GAAG,UAAU,SAAS,QAAQ,SAAS,UAAU,WAAW,EAAE,CAAC;YACpE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAE1C,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,kCAAkC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,kBAAkB;gBACnF,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;aACrC,CAAC;SACH;QAAC,OAAO,KAAK,EAAE;YACd,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;YAC7C,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,yBAAyB,KAAK,CAAC,CAAC,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,EAAE;aAC9E,CAAC;SACH;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"UpdateDataTool.js","sourceRoot":"","sources":["../../src/tools/UpdateDataTool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,6BAA6B,EAAkB,MAAM,mBAAmB,CAAC;AASlF,MAAM,OAAO,cAAc;IAA3B;QACE,SAAI,GAAG,aAAa,CAAC;QACrB,gBAAW,GACT,4EAA4E,CAAC;IA+CjF,CAAC;IA7CC,KAAK,CAAC,GAAG,CAAC,MAAwB;QAChC,IAAI,KAAyB,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;YAE7D,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,aAAa,CAAC,YAAY,CAAC,CAAC;YAC7D,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;YAC5C,CAAC;YAED,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC3C,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC/B,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;YAC7D,CAAC;YAED,MAAM,SAAS,GAAG,aAAa;iBAC5B,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;gBAClB,MAAM,SAAS,GAAG,UAAU,KAAK,EAAE,CAAC;gBACpC,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;gBACvC,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,OAAO,SAAS,EAAE,CAAC;YACnD,CAAC,CAAC;iBACD,IAAI,CAAC,IAAI,CAAC,CAAC;YAEd,MAAM,WAAW,GAAG,6BAA6B,CAC/C,OAAO,EACP,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,EAC3C,eAAe,CAChB,CAAC;YAEF,KAAK,GAAG,UAAU,kBAAkB,CAAC,SAAS,CAAC,QAAQ,SAAS,UAAU,WAAW,EAAE,CAAC;YACxF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAE1C,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,kCAAkC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,kBAAkB;gBACnF,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;aACrC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;YAC7C,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,yBAAyB,KAAK,CAAC,CAAC,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,EAAE;aAC9E,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
@@ -1,14 +1,14 @@
1
- /**
2
- * SQL query validation for read-only operations.
3
- * Extracted for testability and reuse.
4
- */
5
- export interface ValidationResult {
6
- isValid: boolean;
7
- error?: string;
8
- }
9
- /**
10
- * Validates a SQL query for read-only (SELECT) operations.
11
- * Rejects dangerous keywords, injection patterns, and multi-statement queries.
12
- */
13
- export declare function validateReadQuery(query: string): ValidationResult;
1
+ /**
2
+ * SQL query validation for read-only operations.
3
+ * Extracted for testability and reuse.
4
+ */
5
+ export interface ValidationResult {
6
+ isValid: boolean;
7
+ error?: string;
8
+ }
9
+ /**
10
+ * Validates a SQL query for read-only (SELECT) operations.
11
+ * Rejects dangerous keywords, injection patterns, and multi-statement queries.
12
+ */
13
+ export declare function validateReadQuery(query: string): ValidationResult;
14
14
  //# sourceMappingURL=validation.d.ts.map