@eamonboyle/mssql-mcp 1.2.0 → 1.3.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 (118) hide show
  1. package/README.md +42 -7
  2. package/dist/config.d.ts +8 -0
  3. package/dist/config.d.ts.map +1 -1
  4. package/dist/config.js +40 -0
  5. package/dist/config.js.map +1 -1
  6. package/dist/db.d.ts +1 -0
  7. package/dist/db.d.ts.map +1 -1
  8. package/dist/db.js +1 -1
  9. package/dist/db.js.map +1 -1
  10. package/dist/index.js +356 -44
  11. package/dist/index.js.map +1 -1
  12. package/dist/mcpResults.d.ts +49 -0
  13. package/dist/mcpResults.d.ts.map +1 -0
  14. package/dist/mcpResults.js +246 -0
  15. package/dist/mcpResults.js.map +1 -0
  16. package/dist/promptRegistry.d.ts.map +1 -1
  17. package/dist/promptRegistry.js +6 -1
  18. package/dist/promptRegistry.js.map +1 -1
  19. package/dist/resourceRegistry.d.ts +2 -0
  20. package/dist/resourceRegistry.d.ts.map +1 -1
  21. package/dist/resourceRegistry.js +149 -10
  22. package/dist/resourceRegistry.js.map +1 -1
  23. package/dist/schema.d.ts +16 -0
  24. package/dist/schema.d.ts.map +1 -1
  25. package/dist/schema.js +180 -1
  26. package/dist/schema.js.map +1 -1
  27. package/dist/serverState.d.ts +28 -0
  28. package/dist/serverState.d.ts.map +1 -0
  29. package/dist/serverState.js +99 -0
  30. package/dist/serverState.js.map +1 -0
  31. package/dist/toolRegistry.d.ts +4 -0
  32. package/dist/toolRegistry.d.ts.map +1 -1
  33. package/dist/toolRegistry.js +210 -64
  34. package/dist/toolRegistry.js.map +1 -1
  35. package/dist/tools/AnalyzeTableTool.d.ts +37 -0
  36. package/dist/tools/AnalyzeTableTool.d.ts.map +1 -0
  37. package/dist/tools/AnalyzeTableTool.js +81 -0
  38. package/dist/tools/AnalyzeTableTool.js.map +1 -0
  39. package/dist/tools/DeleteDataTool.d.ts.map +1 -1
  40. package/dist/tools/DeleteDataTool.js +4 -1
  41. package/dist/tools/DeleteDataTool.js.map +1 -1
  42. package/dist/tools/DescribeRelationshipsTool.d.ts +20 -0
  43. package/dist/tools/DescribeRelationshipsTool.d.ts.map +1 -0
  44. package/dist/tools/DescribeRelationshipsTool.js +24 -0
  45. package/dist/tools/DescribeRelationshipsTool.js.map +1 -0
  46. package/dist/tools/ListDatabasesTool.d.ts +16 -0
  47. package/dist/tools/ListDatabasesTool.d.ts.map +1 -0
  48. package/dist/tools/ListDatabasesTool.js +26 -0
  49. package/dist/tools/ListDatabasesTool.js.map +1 -0
  50. package/dist/tools/ListForeignKeysTool.d.ts +19 -0
  51. package/dist/tools/ListForeignKeysTool.d.ts.map +1 -0
  52. package/dist/tools/ListForeignKeysTool.js +24 -0
  53. package/dist/tools/ListForeignKeysTool.js.map +1 -0
  54. package/dist/tools/PreviewDeleteTool.d.ts +28 -0
  55. package/dist/tools/PreviewDeleteTool.d.ts.map +1 -0
  56. package/dist/tools/PreviewDeleteTool.js +31 -0
  57. package/dist/tools/PreviewDeleteTool.js.map +1 -0
  58. package/dist/tools/PreviewUpdateTool.d.ts +30 -0
  59. package/dist/tools/PreviewUpdateTool.d.ts.map +1 -0
  60. package/dist/tools/PreviewUpdateTool.js +34 -0
  61. package/dist/tools/PreviewUpdateTool.js.map +1 -0
  62. package/dist/tools/UpdateDataTool.d.ts +1 -0
  63. package/dist/tools/UpdateDataTool.d.ts.map +1 -1
  64. package/dist/tools/UpdateDataTool.js +6 -3
  65. package/dist/tools/UpdateDataTool.js.map +1 -1
  66. package/dist/writePreview.d.ts +20 -0
  67. package/dist/writePreview.d.ts.map +1 -0
  68. package/dist/writePreview.js +27 -0
  69. package/dist/writePreview.js.map +1 -0
  70. package/dist/writePreviewGrant.d.ts +18 -0
  71. package/dist/writePreviewGrant.d.ts.map +1 -0
  72. package/dist/writePreviewGrant.js +71 -0
  73. package/dist/writePreviewGrant.js.map +1 -0
  74. package/dist/writePreviewGrantStore.d.ts +10 -0
  75. package/dist/writePreviewGrantStore.d.ts.map +1 -0
  76. package/dist/writePreviewGrantStore.js +47 -0
  77. package/dist/writePreviewGrantStore.js.map +1 -0
  78. package/package.json +2 -2
  79. package/dist/__tests__/ExplainQueryTool.test.d.ts +0 -2
  80. package/dist/__tests__/ExplainQueryTool.test.d.ts.map +0 -1
  81. package/dist/__tests__/ExplainQueryTool.test.js +0 -96
  82. package/dist/__tests__/ExplainQueryTool.test.js.map +0 -1
  83. package/dist/__tests__/config.test.d.ts +0 -2
  84. package/dist/__tests__/config.test.d.ts.map +0 -1
  85. package/dist/__tests__/config.test.js +0 -29
  86. package/dist/__tests__/config.test.js.map +0 -1
  87. package/dist/__tests__/db.test.d.ts +0 -2
  88. package/dist/__tests__/db.test.d.ts.map +0 -1
  89. package/dist/__tests__/db.test.js +0 -204
  90. package/dist/__tests__/db.test.js.map +0 -1
  91. package/dist/__tests__/promptRegistry.test.d.ts +0 -2
  92. package/dist/__tests__/promptRegistry.test.d.ts.map +0 -1
  93. package/dist/__tests__/promptRegistry.test.js +0 -40
  94. package/dist/__tests__/promptRegistry.test.js.map +0 -1
  95. package/dist/__tests__/resourceRegistry.test.d.ts +0 -2
  96. package/dist/__tests__/resourceRegistry.test.d.ts.map +0 -1
  97. package/dist/__tests__/resourceRegistry.test.js +0 -40
  98. package/dist/__tests__/resourceRegistry.test.js.map +0 -1
  99. package/dist/__tests__/schema.test.d.ts +0 -2
  100. package/dist/__tests__/schema.test.d.ts.map +0 -1
  101. package/dist/__tests__/schema.test.js +0 -130
  102. package/dist/__tests__/schema.test.js.map +0 -1
  103. package/dist/__tests__/sql.test.d.ts +0 -2
  104. package/dist/__tests__/sql.test.d.ts.map +0 -1
  105. package/dist/__tests__/sql.test.js +0 -35
  106. package/dist/__tests__/sql.test.js.map +0 -1
  107. package/dist/__tests__/toolRegistry.test.d.ts +0 -2
  108. package/dist/__tests__/toolRegistry.test.d.ts.map +0 -1
  109. package/dist/__tests__/toolRegistry.test.js +0 -47
  110. package/dist/__tests__/toolRegistry.test.js.map +0 -1
  111. package/dist/__tests__/validation.test.d.ts +0 -2
  112. package/dist/__tests__/validation.test.d.ts.map +0 -1
  113. package/dist/__tests__/validation.test.js +0 -111
  114. package/dist/__tests__/validation.test.js.map +0 -1
  115. package/dist/__tests__/writeTools.test.d.ts +0 -2
  116. package/dist/__tests__/writeTools.test.d.ts.map +0 -1
  117. package/dist/__tests__/writeTools.test.js +0 -115
  118. package/dist/__tests__/writeTools.test.js.map +0 -1
@@ -0,0 +1,81 @@
1
+ import { analyzeTable } from "../schema.js";
2
+ function formatScalar(value) {
3
+ if (value === null || value === undefined) {
4
+ return "n/a";
5
+ }
6
+ if (typeof value === "bigint") {
7
+ return value.toString();
8
+ }
9
+ if (typeof value === "number" && Number.isFinite(value)) {
10
+ return Number.isInteger(value)
11
+ ? String(value)
12
+ : value.toLocaleString(undefined, { maximumFractionDigits: 4 });
13
+ }
14
+ return String(value);
15
+ }
16
+ export function formatAnalyzeTableText(data) {
17
+ const s = data.summary;
18
+ if (!s) {
19
+ return "";
20
+ }
21
+ const schema = formatScalar(s.schemaName);
22
+ const table = formatScalar(s.tableName);
23
+ const lines = [
24
+ `Table: ${schema}.${table}`,
25
+ `Estimated rows: ${formatScalar(s.rowCount)}`,
26
+ `Reserved: ${formatScalar(s.reservedMB)} MB`,
27
+ `Used: ${formatScalar(s.usedMB)} MB`,
28
+ "",
29
+ "Indexes:",
30
+ ];
31
+ if (data.indexes.length === 0) {
32
+ lines.push(" (none)");
33
+ }
34
+ else {
35
+ for (const idx of data.indexes) {
36
+ const name = idx.name != null ? formatScalar(idx.name) : "(unnamed)";
37
+ const type = idx.type != null ? formatScalar(idx.type) : "?";
38
+ const tags = [];
39
+ if (idx.isPrimaryKey === true || idx.isPrimaryKey === 1) {
40
+ tags.push("primary key");
41
+ }
42
+ if (idx.isUnique === true || idx.isUnique === 1) {
43
+ tags.push("unique");
44
+ }
45
+ const tagPart = tags.length > 0 ? ` (${tags.join(", ")})` : "";
46
+ lines.push(` - ${name}: ${type}${tagPart}`);
47
+ }
48
+ }
49
+ return lines.join("\n");
50
+ }
51
+ export class AnalyzeTableTool {
52
+ constructor() {
53
+ this.name = "analyze_table";
54
+ this.description = "Summarizes row counts, storage, and indexes for a table.";
55
+ }
56
+ async run(params) {
57
+ try {
58
+ const data = await analyzeTable(params.tableName, params.databaseName, params.schemaName);
59
+ if (!data.summary) {
60
+ return {
61
+ success: true,
62
+ message: `No table named '${params.tableName}' was found.`,
63
+ data,
64
+ };
65
+ }
66
+ const detail = formatAnalyzeTableText(data);
67
+ return {
68
+ success: true,
69
+ message: `Analyzed ${params.tableName} successfully.\n\n${detail}`,
70
+ data,
71
+ };
72
+ }
73
+ catch (error) {
74
+ return {
75
+ success: false,
76
+ message: `Failed to analyze table: ${error}`,
77
+ };
78
+ }
79
+ }
80
+ }
81
+ //# sourceMappingURL=AnalyzeTableTool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnalyzeTableTool.js","sourceRoot":"","sources":["../../src/tools/AnalyzeTableTool.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"DeleteDataTool.d.ts","sourceRoot":"","sources":["../../src/tools/DeleteDataTool.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiC,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAElF,UAAU,gBAAgB;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,cAAc;IACzB,IAAI,SAAiB;IACrB,WAAW,SAC6D;IAElE,GAAG,CAAC,MAAM,EAAE,gBAAgB;;;;;;;;;CAiCnC"}
1
+ {"version":3,"file":"DeleteDataTool.d.ts","sourceRoot":"","sources":["../../src/tools/DeleteDataTool.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiC,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAElF,UAAU,gBAAgB;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,cAAc;IACzB,IAAI,SAAiB;IACrB,WAAW,SAC6D;IAElE,GAAG,CAAC,MAAM,EAAE,gBAAgB;;;;;;;;;CAqCnC"}
@@ -1,3 +1,4 @@
1
+ import { getMaxWriteRows } from "../config.js";
1
2
  import { getSqlRequest } from "../db.js";
2
3
  import { buildQualifiedName } from "../sql.js";
3
4
  import { buildParameterizedWhereClause } from "../writeSafety.js";
@@ -16,7 +17,9 @@ export class DeleteDataTool {
16
17
  }
17
18
  const whereClause = buildParameterizedWhereClause(filters, (name, value) => request.input(name, value), "delete_filter");
18
19
  query = `DELETE FROM ${buildQualifiedName(tableName, schemaName)} WHERE ${whereClause}`;
19
- const result = await request.query(query);
20
+ const maxRows = getMaxWriteRows();
21
+ request.input("mcp_rowcap", maxRows);
22
+ const result = await request.query(`SET ROWCOUNT @mcp_rowcap;\n${query}\nSET ROWCOUNT 0;`);
20
23
  return {
21
24
  success: true,
22
25
  message: `Delete completed successfully. ${result.rowsAffected[0]} row(s) affected`,
@@ -1 +1 @@
1
- {"version":3,"file":"DeleteDataTool.js","sourceRoot":"","sources":["../../src/tools/DeleteDataTool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,6BAA6B,EAAkB,MAAM,mBAAmB,CAAC;AASlF,MAAM,OAAO,cAAc;IAA3B;QACE,SAAI,GAAG,aAAa,CAAC;QACrB,gBAAW,GACT,qEAAqE,CAAC;IAmC1E,CAAC;IAjCC,KAAK,CAAC,GAAG,CAAC,MAAwB;QAChC,IAAI,KAAyB,CAAC;QAE9B,IAAI,CAAC;YACH,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;YAEhE,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,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,eAAe,kBAAkB,CAAC,SAAS,EAAE,UAAU,CAAC,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,wBAAwB,KAAK,CAAC,CAAC,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,EAAE;aAC7E,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"DeleteDataTool.js","sourceRoot":"","sources":["../../src/tools/DeleteDataTool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,6BAA6B,EAAkB,MAAM,mBAAmB,CAAC;AASlF,MAAM,OAAO,cAAc;IAA3B;QACE,SAAI,GAAG,aAAa,CAAC;QACrB,gBAAW,GACT,qEAAqE,CAAC;IAuC1E,CAAC;IArCC,KAAK,CAAC,GAAG,CAAC,MAAwB;QAChC,IAAI,KAAyB,CAAC;QAE9B,IAAI,CAAC;YACH,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;YAEhE,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,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,eAAe,kBAAkB,CAAC,SAAS,EAAE,UAAU,CAAC,UAAU,WAAW,EAAE,CAAC;YACxF,MAAM,OAAO,GAAG,eAAe,EAAE,CAAC;YAClC,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YACrC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAChC,8BAA8B,KAAK,mBAAmB,CACvD,CAAC;YAEF,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,wBAAwB,KAAK,CAAC,CAAC,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,EAAE;aAC7E,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,20 @@
1
+ interface DescribeRelationshipsParams {
2
+ tableName: string;
3
+ schemaName?: string;
4
+ databaseName?: string;
5
+ }
6
+ export declare class DescribeRelationshipsTool {
7
+ name: string;
8
+ description: string;
9
+ run(params: DescribeRelationshipsParams): Promise<{
10
+ success: boolean;
11
+ message: string;
12
+ data: any[];
13
+ } | {
14
+ success: boolean;
15
+ message: string;
16
+ data?: undefined;
17
+ }>;
18
+ }
19
+ export {};
20
+ //# sourceMappingURL=DescribeRelationshipsTool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DescribeRelationshipsTool.d.ts","sourceRoot":"","sources":["../../src/tools/DescribeRelationshipsTool.ts"],"names":[],"mappings":"AAEA,UAAU,2BAA2B;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,yBAAyB;IACpC,IAAI,SAA4B;IAChC,WAAW,SACgE;IAErE,GAAG,CAAC,MAAM,EAAE,2BAA2B;;;;;;;;;CAmB9C"}
@@ -0,0 +1,24 @@
1
+ import { describeRelationships } from "../schema.js";
2
+ export class DescribeRelationshipsTool {
3
+ constructor() {
4
+ this.name = "describe_relationships";
5
+ this.description = "Describes incoming and outgoing foreign key relationships for a table.";
6
+ }
7
+ async run(params) {
8
+ try {
9
+ const data = await describeRelationships(params.tableName, params.databaseName, params.schemaName);
10
+ return {
11
+ success: true,
12
+ message: `Found ${data.length} relationship row(s) for ${params.tableName}.`,
13
+ data,
14
+ };
15
+ }
16
+ catch (error) {
17
+ return {
18
+ success: false,
19
+ message: `Failed to describe relationships: ${error}`,
20
+ };
21
+ }
22
+ }
23
+ }
24
+ //# sourceMappingURL=DescribeRelationshipsTool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DescribeRelationshipsTool.js","sourceRoot":"","sources":["../../src/tools/DescribeRelationshipsTool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAQrD,MAAM,OAAO,yBAAyB;IAAtC;QACE,SAAI,GAAG,wBAAwB,CAAC;QAChC,gBAAW,GACT,wEAAwE,CAAC;IAqB7E,CAAC;IAnBC,KAAK,CAAC,GAAG,CAAC,MAAmC;QAC3C,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,qBAAqB,CACtC,MAAM,CAAC,SAAS,EAChB,MAAM,CAAC,YAAY,EACnB,MAAM,CAAC,UAAU,CAClB,CAAC;YACF,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,SAAS,IAAI,CAAC,MAAM,4BAA4B,MAAM,CAAC,SAAS,GAAG;gBAC5E,IAAI;aACL,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,qCAAqC,KAAK,EAAE;aACtD,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,16 @@
1
+ export declare class ListDatabasesTool {
2
+ name: string;
3
+ description: string;
4
+ run(): Promise<{
5
+ success: boolean;
6
+ message: string;
7
+ data: {
8
+ name: string;
9
+ isDefault: boolean;
10
+ }[];
11
+ meta: {
12
+ count: number;
13
+ };
14
+ }>;
15
+ }
16
+ //# sourceMappingURL=ListDatabasesTool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ListDatabasesTool.d.ts","sourceRoot":"","sources":["../../src/tools/ListDatabasesTool.ts"],"names":[],"mappings":"AAeA,qBAAa,iBAAiB;IAC5B,IAAI,SAAoB;IACxB,WAAW,SACsD;IAE3D,GAAG;;;;;;;;;;;CAWV"}
@@ -0,0 +1,26 @@
1
+ import { listConfiguredDatabases } from "../schema.js";
2
+ function formatConfiguredDatabasesMessage(databases) {
3
+ if (databases.length === 0) {
4
+ return "No databases are configured. Set DATABASE_NAME or DATABASES in the environment.";
5
+ }
6
+ const labels = databases.map((d) => d.isDefault ? `${d.name} (default)` : d.name);
7
+ return `Configured databases (${databases.length}): ${labels.join(", ")}.`;
8
+ }
9
+ export class ListDatabasesTool {
10
+ constructor() {
11
+ this.name = "list_databases";
12
+ this.description = "Lists the databases this MCP server is configured to access.";
13
+ }
14
+ async run() {
15
+ const databases = listConfiguredDatabases();
16
+ return {
17
+ success: true,
18
+ message: formatConfiguredDatabasesMessage(databases),
19
+ data: databases,
20
+ meta: {
21
+ count: databases.length,
22
+ },
23
+ };
24
+ }
25
+ }
26
+ //# sourceMappingURL=ListDatabasesTool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ListDatabasesTool.js","sourceRoot":"","sources":["../../src/tools/ListDatabasesTool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAEvD,SAAS,gCAAgC,CACvC,SAAsD;IAEtD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,iFAAiF,CAAC;IAC3F,CAAC;IAED,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACjC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAC7C,CAAC;IACF,OAAO,yBAAyB,SAAS,CAAC,MAAM,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;AAC7E,CAAC;AAED,MAAM,OAAO,iBAAiB;IAA9B;QACE,SAAI,GAAG,gBAAgB,CAAC;QACxB,gBAAW,GACT,8DAA8D,CAAC;IAanE,CAAC;IAXC,KAAK,CAAC,GAAG;QACP,MAAM,SAAS,GAAG,uBAAuB,EAAE,CAAC;QAC5C,OAAO;YACL,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,gCAAgC,CAAC,SAAS,CAAC;YACpD,IAAI,EAAE,SAAS;YACf,IAAI,EAAE;gBACJ,KAAK,EAAE,SAAS,CAAC,MAAM;aACxB;SACF,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,19 @@
1
+ interface ListForeignKeysParams {
2
+ databaseName?: string;
3
+ schemaName?: string;
4
+ }
5
+ export declare class ListForeignKeysTool {
6
+ name: string;
7
+ description: string;
8
+ run(params?: ListForeignKeysParams): Promise<{
9
+ success: boolean;
10
+ message: string;
11
+ data: import("mssql").IRecordSet<any>;
12
+ } | {
13
+ success: boolean;
14
+ message: string;
15
+ data?: undefined;
16
+ }>;
17
+ }
18
+ export {};
19
+ //# sourceMappingURL=ListForeignKeysTool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ListForeignKeysTool.d.ts","sourceRoot":"","sources":["../../src/tools/ListForeignKeysTool.ts"],"names":[],"mappings":"AAEA,UAAU,qBAAqB;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,mBAAmB;IAC9B,IAAI,SAAuB;IAC3B,WAAW,SAC8D;IAEnE,GAAG,CAAC,MAAM,GAAE,qBAA0B;;;;;;;;;CAe7C"}
@@ -0,0 +1,24 @@
1
+ import { listForeignKeys } from "../schema.js";
2
+ export class ListForeignKeysTool {
3
+ constructor() {
4
+ this.name = "list_foreign_keys";
5
+ this.description = "Lists foreign key relationships for the selected database or schema.";
6
+ }
7
+ async run(params = {}) {
8
+ try {
9
+ const rows = await listForeignKeys(params.databaseName, params.schemaName);
10
+ return {
11
+ success: true,
12
+ message: `Found ${rows.length} foreign key relationship(s).`,
13
+ data: rows,
14
+ };
15
+ }
16
+ catch (error) {
17
+ return {
18
+ success: false,
19
+ message: `Failed to list foreign keys: ${error}`,
20
+ };
21
+ }
22
+ }
23
+ }
24
+ //# sourceMappingURL=ListForeignKeysTool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ListForeignKeysTool.js","sourceRoot":"","sources":["../../src/tools/ListForeignKeysTool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAO/C,MAAM,OAAO,mBAAmB;IAAhC;QACE,SAAI,GAAG,mBAAmB,CAAC;QAC3B,gBAAW,GACT,sEAAsE,CAAC;IAiB3E,CAAC;IAfC,KAAK,CAAC,GAAG,CAAC,SAAgC,EAAE;QAC1C,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;YAC3E,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,SAAS,IAAI,CAAC,MAAM,+BAA+B;gBAC5D,IAAI,EAAE,IAAI;aACX,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,gCAAgC,KAAK,EAAE;aACjD,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,28 @@
1
+ import type { SqlFilter } from "../writeSafety.js";
2
+ interface PreviewDeleteParams {
3
+ tableName: string;
4
+ schemaName?: string;
5
+ filters: SqlFilter[];
6
+ previewLimit?: number;
7
+ databaseName?: string;
8
+ }
9
+ export declare class PreviewDeleteTool {
10
+ name: string;
11
+ description: string;
12
+ run(params: PreviewDeleteParams): Promise<{
13
+ success: boolean;
14
+ message: string;
15
+ data: {
16
+ query: string;
17
+ countQuery: string;
18
+ rows: import("mssql").IRecordSet<any>;
19
+ affectedRowCount: any;
20
+ };
21
+ } | {
22
+ success: boolean;
23
+ message: string;
24
+ data?: undefined;
25
+ }>;
26
+ }
27
+ export {};
28
+ //# sourceMappingURL=PreviewDeleteTool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PreviewDeleteTool.d.ts","sourceRoot":"","sources":["../../src/tools/PreviewDeleteTool.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD,UAAU,mBAAmB;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,iBAAiB;IAC5B,IAAI,SAAoB;IACxB,WAAW,SAC0D;IAE/D,GAAG,CAAC,MAAM,EAAE,mBAAmB;;;;;;;;;;;;;;CAsBtC"}
@@ -0,0 +1,31 @@
1
+ import { clampRowLimit } from "../config.js";
2
+ import { previewFilteredRows } from "../writePreview.js";
3
+ export class PreviewDeleteTool {
4
+ constructor() {
5
+ this.name = "preview_delete";
6
+ this.description = "Previews which rows would be deleted before running delete_data.";
7
+ }
8
+ async run(params) {
9
+ try {
10
+ const preview = await previewFilteredRows({
11
+ tableName: params.tableName,
12
+ schemaName: params.schemaName,
13
+ filters: params.filters,
14
+ databaseName: params.databaseName,
15
+ limit: clampRowLimit(params.previewLimit, 25),
16
+ });
17
+ return {
18
+ success: true,
19
+ message: `Previewed ${preview.rows.length} row(s) for delete; ${preview.affectedRowCount} row(s) would be affected.`,
20
+ data: preview,
21
+ };
22
+ }
23
+ catch (error) {
24
+ return {
25
+ success: false,
26
+ message: `Failed to preview delete: ${error}`,
27
+ };
28
+ }
29
+ }
30
+ }
31
+ //# sourceMappingURL=PreviewDeleteTool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PreviewDeleteTool.js","sourceRoot":"","sources":["../../src/tools/PreviewDeleteTool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAWzD,MAAM,OAAO,iBAAiB;IAA9B;QACE,SAAI,GAAG,gBAAgB,CAAC;QACxB,gBAAW,GACT,kEAAkE,CAAC;IAwBvE,CAAC;IAtBC,KAAK,CAAC,GAAG,CAAC,MAA2B;QACnC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC;gBACxC,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,YAAY,EAAE,MAAM,CAAC,YAAY;gBACjC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,CAAC;aAC9C,CAAC,CAAC;YAEH,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,aAAa,OAAO,CAAC,IAAI,CAAC,MAAM,uBAAuB,OAAO,CAAC,gBAAgB,4BAA4B;gBACpH,IAAI,EAAE,OAAO;aACd,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,6BAA6B,KAAK,EAAE;aAC9C,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,30 @@
1
+ import type { SqlFilter } from "../writeSafety.js";
2
+ interface PreviewUpdateParams {
3
+ tableName: string;
4
+ schemaName?: string;
5
+ filters: SqlFilter[];
6
+ updates: Record<string, unknown>;
7
+ previewLimit?: number;
8
+ databaseName?: string;
9
+ }
10
+ export declare class PreviewUpdateTool {
11
+ name: string;
12
+ description: string;
13
+ run(params: PreviewUpdateParams): Promise<{
14
+ success: boolean;
15
+ message: string;
16
+ data: {
17
+ updates: Record<string, unknown>;
18
+ query: string;
19
+ countQuery: string;
20
+ rows: import("mssql").IRecordSet<any>;
21
+ affectedRowCount: any;
22
+ };
23
+ } | {
24
+ success: boolean;
25
+ message: string;
26
+ data?: undefined;
27
+ }>;
28
+ }
29
+ export {};
30
+ //# sourceMappingURL=PreviewUpdateTool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PreviewUpdateTool.d.ts","sourceRoot":"","sources":["../../src/tools/PreviewUpdateTool.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD,UAAU,mBAAmB;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,iBAAiB;IAC5B,IAAI,SAAoB;IACxB,WAAW,SAC0D;IAE/D,GAAG,CAAC,MAAM,EAAE,mBAAmB;;;;;;;;;;;;;;;CAyBtC"}
@@ -0,0 +1,34 @@
1
+ import { clampRowLimit } from "../config.js";
2
+ import { previewFilteredRows } from "../writePreview.js";
3
+ export class PreviewUpdateTool {
4
+ constructor() {
5
+ this.name = "preview_update";
6
+ this.description = "Previews which rows would be updated before running update_data.";
7
+ }
8
+ async run(params) {
9
+ try {
10
+ const preview = await previewFilteredRows({
11
+ tableName: params.tableName,
12
+ schemaName: params.schemaName,
13
+ filters: params.filters,
14
+ databaseName: params.databaseName,
15
+ limit: clampRowLimit(params.previewLimit, 25),
16
+ });
17
+ return {
18
+ success: true,
19
+ message: `Previewed ${preview.rows.length} row(s) for update; ${preview.affectedRowCount} row(s) would be affected.`,
20
+ data: {
21
+ ...preview,
22
+ updates: params.updates,
23
+ },
24
+ };
25
+ }
26
+ catch (error) {
27
+ return {
28
+ success: false,
29
+ message: `Failed to preview update: ${error}`,
30
+ };
31
+ }
32
+ }
33
+ }
34
+ //# sourceMappingURL=PreviewUpdateTool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PreviewUpdateTool.js","sourceRoot":"","sources":["../../src/tools/PreviewUpdateTool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAYzD,MAAM,OAAO,iBAAiB;IAA9B;QACE,SAAI,GAAG,gBAAgB,CAAC;QACxB,gBAAW,GACT,kEAAkE,CAAC;IA2BvE,CAAC;IAzBC,KAAK,CAAC,GAAG,CAAC,MAA2B;QACnC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC;gBACxC,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,YAAY,EAAE,MAAM,CAAC,YAAY;gBACjC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,CAAC;aAC9C,CAAC,CAAC;YAEH,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,aAAa,OAAO,CAAC,IAAI,CAAC,MAAM,uBAAuB,OAAO,CAAC,gBAAgB,4BAA4B;gBACpH,IAAI,EAAE;oBACJ,GAAG,OAAO;oBACV,OAAO,EAAE,MAAM,CAAC,OAAO;iBACxB;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,6BAA6B,KAAK,EAAE;aAC9C,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
@@ -1,6 +1,7 @@
1
1
  import { type SqlFilter } from "../writeSafety.js";
2
2
  interface UpdateDataParams {
3
3
  tableName: string;
4
+ schemaName?: string;
4
5
  updates: Record<string, unknown>;
5
6
  filters: SqlFilter[];
6
7
  databaseName?: string;
@@ -1 +1 @@
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
+ {"version":3,"file":"UpdateDataTool.d.ts","sourceRoot":"","sources":["../../src/tools/UpdateDataTool.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiC,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAElF,UAAU,gBAAgB;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,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;;;;;;;;;CAiDnC"}
@@ -1,3 +1,4 @@
1
+ import { getMaxWriteRows } from "../config.js";
1
2
  import { getSqlRequest } from "../db.js";
2
3
  import { buildQualifiedName, quoteIdentifier } from "../sql.js";
3
4
  import { buildParameterizedWhereClause } from "../writeSafety.js";
@@ -9,7 +10,7 @@ export class UpdateDataTool {
9
10
  async run(params) {
10
11
  let query;
11
12
  try {
12
- const { tableName, updates, filters, databaseName } = params;
13
+ const { tableName, schemaName, updates, filters, databaseName } = params;
13
14
  const { request, error } = await getSqlRequest(databaseName);
14
15
  if (error) {
15
16
  return { success: false, message: error };
@@ -26,8 +27,10 @@ export class UpdateDataTool {
26
27
  })
27
28
  .join(", ");
28
29
  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);
30
+ query = `UPDATE ${buildQualifiedName(tableName, schemaName)} SET ${setClause} WHERE ${whereClause}`;
31
+ const maxRows = getMaxWriteRows();
32
+ request.input("mcp_rowcap", maxRows);
33
+ const result = await request.query(`SET ROWCOUNT @mcp_rowcap;\n${query}\nSET ROWCOUNT 0;`);
31
34
  return {
32
35
  success: true,
33
36
  message: `Update completed successfully. ${result.rowsAffected[0]} row(s) affected`,
@@ -1 +1 @@
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
+ {"version":3,"file":"UpdateDataTool.js","sourceRoot":"","sources":["../../src/tools/UpdateDataTool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,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;AAUlF,MAAM,OAAO,cAAc;IAA3B;QACE,SAAI,GAAG,aAAa,CAAC;QACrB,gBAAW,GACT,4EAA4E,CAAC;IAmDjF,CAAC;IAjDC,KAAK,CAAC,GAAG,CAAC,MAAwB;QAChC,IAAI,KAAyB,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;YAEzE,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,EAAE,UAAU,CAAC,QAAQ,SAAS,UAAU,WAAW,EAAE,CAAC;YACpG,MAAM,OAAO,GAAG,eAAe,EAAE,CAAC;YAClC,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YACrC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAChC,8BAA8B,KAAK,mBAAmB,CACvD,CAAC;YAEF,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"}
@@ -0,0 +1,20 @@
1
+ import { type SqlFilter } from "./writeSafety.js";
2
+ export interface WritePreviewResult {
3
+ query: string;
4
+ countQuery: string;
5
+ rows: unknown[];
6
+ affectedRowCount: number;
7
+ }
8
+ export declare function previewFilteredRows(params: {
9
+ tableName: string;
10
+ schemaName?: string;
11
+ filters: SqlFilter[];
12
+ databaseName?: string;
13
+ limit: number;
14
+ }): Promise<{
15
+ query: string;
16
+ countQuery: string;
17
+ rows: import("mssql").IRecordSet<any>;
18
+ affectedRowCount: any;
19
+ }>;
20
+ //# sourceMappingURL=writePreview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writePreview.d.ts","sourceRoot":"","sources":["../src/writePreview.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiC,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAEjF,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAsB,mBAAmB,CAAC,MAAM,EAAE;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;;;;;GA6BA"}
@@ -0,0 +1,27 @@
1
+ import { getSqlRequest } from "./db.js";
2
+ import { buildQualifiedName } from "./sql.js";
3
+ import { buildParameterizedWhereClause } from "./writeSafety.js";
4
+ export async function previewFilteredRows(params) {
5
+ const { tableName, schemaName, filters, databaseName, limit } = params;
6
+ const { request, error } = await getSqlRequest(databaseName);
7
+ if (error) {
8
+ throw new Error(error);
9
+ }
10
+ request.input("previewLimit", limit);
11
+ const whereClause = buildParameterizedWhereClause(filters, (name, value) => request.input(name, value), "preview_filter");
12
+ const tableRef = buildQualifiedName(tableName, schemaName);
13
+ const query = `SELECT TOP (@previewLimit) * FROM ${tableRef} WHERE ${whereClause}`;
14
+ const countQuery = `SELECT COUNT(*) AS affectedRowCount FROM ${tableRef} WHERE ${whereClause}`;
15
+ const result = await request.query(`
16
+ ${query};
17
+ ${countQuery};
18
+ `);
19
+ const recordsets = Array.isArray(result.recordsets) ? result.recordsets : [];
20
+ return {
21
+ query,
22
+ countQuery,
23
+ rows: recordsets[0] ?? [],
24
+ affectedRowCount: recordsets[1]?.[0]?.affectedRowCount ?? 0,
25
+ };
26
+ }
27
+ //# sourceMappingURL=writePreview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writePreview.js","sourceRoot":"","sources":["../src/writePreview.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,6BAA6B,EAAkB,MAAM,kBAAkB,CAAC;AASjF,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,MAMzC;IACC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;IACvE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,aAAa,CAAC,YAAY,CAAC,CAAC;IAC7D,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,MAAM,WAAW,GAAG,6BAA6B,CAC/C,OAAO,EACP,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,EAC3C,gBAAgB,CACjB,CAAC;IACF,MAAM,QAAQ,GAAG,kBAAkB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAC3D,MAAM,KAAK,GAAG,qCAAqC,QAAQ,UAAU,WAAW,EAAE,CAAC;IACnF,MAAM,UAAU,GAAG,4CAA4C,QAAQ,UAAU,WAAW,EAAE,CAAC;IAE/F,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC;MAC/B,KAAK;MACL,UAAU;GACb,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IAE7E,OAAO;QACL,KAAK;QACL,UAAU;QACV,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE;QACzB,gBAAgB,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,gBAAgB,IAAI,CAAC;KAC/B,CAAC;AACjC,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { SqlFilter } from "./writeSafety.js";
2
+ export type WriteDataToolName = "update_data" | "delete_data";
3
+ export declare function fingerprintForUpdateOp(params: {
4
+ databaseName?: string;
5
+ schemaName?: string;
6
+ tableName: string;
7
+ filters: SqlFilter[];
8
+ updates: Record<string, unknown>;
9
+ }): string;
10
+ export declare function fingerprintForDeleteOp(params: {
11
+ databaseName?: string;
12
+ schemaName?: string;
13
+ tableName: string;
14
+ filters: SqlFilter[];
15
+ }): string;
16
+ export type PreviewOrWriteName = "preview_update" | "preview_delete" | "update_data" | "delete_data";
17
+ export declare function fingerprintForWriteTool(toolName: PreviewOrWriteName, requestArgs: Record<string, unknown>): string;
18
+ //# sourceMappingURL=writePreviewGrant.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writePreviewGrant.d.ts","sourceRoot":"","sources":["../src/writePreviewGrant.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,aAAa,CAAC;AAqC9D,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,GAAG,MAAM,CAUT;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,SAAS,EAAE,CAAC;CACtB,GAAG,MAAM,CAST;AAED,MAAM,MAAM,kBAAkB,GAC1B,gBAAgB,GAChB,gBAAgB,GAChB,aAAa,GACb,aAAa,CAAC;AAElB,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,kBAAkB,EAC5B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,MAAM,CAiBR"}
@@ -0,0 +1,71 @@
1
+ import { createHash } from "node:crypto";
2
+ function stableStringify(value) {
3
+ return JSON.stringify(value, (_key, v) => {
4
+ if (v instanceof Date) {
5
+ return v.toISOString();
6
+ }
7
+ return v;
8
+ });
9
+ }
10
+ function normalizeFilters(filters) {
11
+ return [...filters]
12
+ .map((f) => ({
13
+ column: f.column,
14
+ operator: f.operator,
15
+ value: f.value,
16
+ values: f.values ? [...f.values] : undefined,
17
+ }))
18
+ .sort((a, b) => {
19
+ const byCol = a.column.localeCompare(b.column);
20
+ if (byCol !== 0) {
21
+ return byCol;
22
+ }
23
+ return a.operator.localeCompare(b.operator);
24
+ });
25
+ }
26
+ function normalizeUpdates(updates) {
27
+ const keys = Object.keys(updates).sort((a, b) => a.localeCompare(b));
28
+ const out = {};
29
+ for (const key of keys) {
30
+ out[key] = updates[key];
31
+ }
32
+ return out;
33
+ }
34
+ export function fingerprintForUpdateOp(params) {
35
+ const payload = {
36
+ kind: "update",
37
+ database: params.databaseName ?? "",
38
+ schema: params.schemaName ?? "",
39
+ table: params.tableName,
40
+ filters: normalizeFilters(params.filters),
41
+ updates: normalizeUpdates(params.updates),
42
+ };
43
+ return createHash("sha256").update(stableStringify(payload)).digest("hex");
44
+ }
45
+ export function fingerprintForDeleteOp(params) {
46
+ const payload = {
47
+ kind: "delete",
48
+ database: params.databaseName ?? "",
49
+ schema: params.schemaName ?? "",
50
+ table: params.tableName,
51
+ filters: normalizeFilters(params.filters),
52
+ };
53
+ return createHash("sha256").update(stableStringify(payload)).digest("hex");
54
+ }
55
+ export function fingerprintForWriteTool(toolName, requestArgs) {
56
+ const filters = requestArgs.filters ?? [];
57
+ const databaseName = typeof requestArgs.databaseName === "string" ? requestArgs.databaseName : undefined;
58
+ const schemaName = typeof requestArgs.schemaName === "string" ? requestArgs.schemaName : undefined;
59
+ const tableName = String(requestArgs.tableName ?? "");
60
+ if (toolName === "preview_delete" || toolName === "delete_data") {
61
+ return fingerprintForDeleteOp({ databaseName, schemaName, tableName, filters });
62
+ }
63
+ return fingerprintForUpdateOp({
64
+ databaseName,
65
+ schemaName,
66
+ tableName,
67
+ filters,
68
+ updates: requestArgs.updates ?? {},
69
+ });
70
+ }
71
+ //# sourceMappingURL=writePreviewGrant.js.map