@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.
- package/dist/audit/AuditLogger.d.ts +37 -0
- package/dist/audit/AuditLogger.d.ts.map +1 -0
- package/dist/audit/AuditLogger.js +145 -0
- package/dist/audit/AuditLogger.js.map +1 -0
- package/dist/config/EnvironmentManager.d.ts +75 -0
- package/dist/config/EnvironmentManager.d.ts.map +1 -0
- package/dist/config/EnvironmentManager.js +305 -0
- package/dist/config/EnvironmentManager.js.map +1 -0
- package/dist/config/ScriptManager.d.ts +69 -0
- package/dist/config/ScriptManager.d.ts.map +1 -0
- package/dist/config/ScriptManager.js +166 -0
- package/dist/config/ScriptManager.js.map +1 -0
- package/dist/config/SecretResolver.d.ts +66 -0
- package/dist/config/SecretResolver.d.ts.map +1 -0
- package/dist/config/SecretResolver.js +230 -0
- package/dist/config/SecretResolver.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/routing/IntentRouter.d.ts +17 -0
- package/dist/routing/IntentRouter.d.ts.map +1 -0
- package/dist/routing/IntentRouter.js +243 -0
- package/dist/routing/IntentRouter.js.map +1 -0
- package/dist/server/createMcpServer.d.ts +7 -0
- package/dist/server/createMcpServer.d.ts.map +1 -0
- package/dist/server/createMcpServer.js +100 -0
- package/dist/server/createMcpServer.js.map +1 -0
- package/dist/server/toolsets.d.ts +42 -0
- package/dist/server/toolsets.d.ts.map +1 -0
- package/dist/server/toolsets.js +303 -0
- package/dist/server/toolsets.js.map +1 -0
- package/dist/server/wrapToolRun.d.ts +13 -0
- package/dist/server/wrapToolRun.d.ts.map +1 -0
- package/dist/server/wrapToolRun.js +102 -0
- package/dist/server/wrapToolRun.js.map +1 -0
- package/dist/shims.d.ts +2 -0
- package/dist/shims.d.ts.map +1 -0
- package/dist/shims.js +15 -0
- package/dist/shims.js.map +1 -0
- package/dist/tools/CreateIndexTool.d.ts +24 -0
- package/dist/tools/CreateIndexTool.d.ts.map +1 -0
- package/dist/tools/CreateIndexTool.js +64 -0
- package/dist/tools/CreateIndexTool.js.map +1 -0
- package/dist/tools/CreateTableTool.d.ts +12 -0
- package/dist/tools/CreateTableTool.d.ts.map +1 -0
- package/dist/tools/CreateTableTool.js +49 -0
- package/dist/tools/CreateTableTool.js.map +1 -0
- package/dist/tools/DeleteDataTool.d.ts +56 -0
- package/dist/tools/DeleteDataTool.d.ts.map +1 -0
- package/dist/tools/DeleteDataTool.js +103 -0
- package/dist/tools/DeleteDataTool.js.map +1 -0
- package/dist/tools/DescribeTableTool.d.ts +32 -0
- package/dist/tools/DescribeTableTool.d.ts.map +1 -0
- package/dist/tools/DescribeTableTool.js +116 -0
- package/dist/tools/DescribeTableTool.js.map +1 -0
- package/dist/tools/DropTableTool.d.ts +12 -0
- package/dist/tools/DropTableTool.d.ts.map +1 -0
- package/dist/tools/DropTableTool.js +37 -0
- package/dist/tools/DropTableTool.js.map +1 -0
- package/dist/tools/ExplainQueryTool.d.ts +24 -0
- package/dist/tools/ExplainQueryTool.d.ts.map +1 -0
- package/dist/tools/ExplainQueryTool.js +98 -0
- package/dist/tools/ExplainQueryTool.js.map +1 -0
- package/dist/tools/InsertDataTool.d.ts +17 -0
- package/dist/tools/InsertDataTool.d.ts.map +1 -0
- package/dist/tools/InsertDataTool.js +102 -0
- package/dist/tools/InsertDataTool.js.map +1 -0
- package/dist/tools/InspectDependenciesTool.d.ts +46 -0
- package/dist/tools/InspectDependenciesTool.d.ts.map +1 -0
- package/dist/tools/InspectDependenciesTool.js +215 -0
- package/dist/tools/InspectDependenciesTool.js.map +1 -0
- package/dist/tools/ListDatabasesTool.d.ts +27 -0
- package/dist/tools/ListDatabasesTool.d.ts.map +1 -0
- package/dist/tools/ListDatabasesTool.js +107 -0
- package/dist/tools/ListDatabasesTool.js.map +1 -0
- package/dist/tools/ListEnvironmentsTool.d.ts +49 -0
- package/dist/tools/ListEnvironmentsTool.d.ts.map +1 -0
- package/dist/tools/ListEnvironmentsTool.js +73 -0
- package/dist/tools/ListEnvironmentsTool.js.map +1 -0
- package/dist/tools/ListScriptsTool.d.ts +41 -0
- package/dist/tools/ListScriptsTool.d.ts.map +1 -0
- package/dist/tools/ListScriptsTool.js +86 -0
- package/dist/tools/ListScriptsTool.js.map +1 -0
- package/dist/tools/ListTableTool.d.ts +24 -0
- package/dist/tools/ListTableTool.d.ts.map +1 -0
- package/dist/tools/ListTableTool.js +85 -0
- package/dist/tools/ListTableTool.js.map +1 -0
- package/dist/tools/ProfileTableTool.d.ts +78 -0
- package/dist/tools/ProfileTableTool.d.ts.map +1 -0
- package/dist/tools/ProfileTableTool.js +373 -0
- package/dist/tools/ProfileTableTool.js.map +1 -0
- package/dist/tools/ReadDataTool.d.ts +61 -0
- package/dist/tools/ReadDataTool.d.ts.map +1 -0
- package/dist/tools/ReadDataTool.js +299 -0
- package/dist/tools/ReadDataTool.js.map +1 -0
- package/dist/tools/RelationshipInspectorTool.d.ts +46 -0
- package/dist/tools/RelationshipInspectorTool.d.ts.map +1 -0
- package/dist/tools/RelationshipInspectorTool.js +156 -0
- package/dist/tools/RelationshipInspectorTool.js.map +1 -0
- package/dist/tools/RunScriptTool.d.ts +214 -0
- package/dist/tools/RunScriptTool.d.ts.map +1 -0
- package/dist/tools/RunScriptTool.js +186 -0
- package/dist/tools/RunScriptTool.js.map +1 -0
- package/dist/tools/SearchSchemaTool.d.ts +88 -0
- package/dist/tools/SearchSchemaTool.d.ts.map +1 -0
- package/dist/tools/SearchSchemaTool.js +237 -0
- package/dist/tools/SearchSchemaTool.js.map +1 -0
- package/dist/tools/TestConnectionTool.d.ts +38 -0
- package/dist/tools/TestConnectionTool.d.ts.map +1 -0
- package/dist/tools/TestConnectionTool.js +156 -0
- package/dist/tools/TestConnectionTool.js.map +1 -0
- package/dist/tools/UpdateDataTool.d.ts +61 -0
- package/dist/tools/UpdateDataTool.d.ts.map +1 -0
- package/dist/tools/UpdateDataTool.js +117 -0
- package/dist/tools/UpdateDataTool.js.map +1 -0
- package/dist/tools/ValidateEnvironmentConfigTool.d.ts +51 -0
- package/dist/tools/ValidateEnvironmentConfigTool.d.ts.map +1 -0
- package/dist/tools/ValidateEnvironmentConfigTool.js +320 -0
- package/dist/tools/ValidateEnvironmentConfigTool.js.map +1 -0
- package/dist/tools/index.d.ts +21 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +22 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types.d.ts +60 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
export declare class RunScriptTool implements Tool {
|
|
3
|
+
[key: string]: any;
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
inputSchema: any;
|
|
7
|
+
run(params: {
|
|
8
|
+
scriptName: string;
|
|
9
|
+
parameters?: Record<string, any>;
|
|
10
|
+
preview?: boolean;
|
|
11
|
+
confirm?: boolean;
|
|
12
|
+
environment?: string;
|
|
13
|
+
environmentPolicy?: any;
|
|
14
|
+
}): Promise<{
|
|
15
|
+
success: boolean;
|
|
16
|
+
error: string;
|
|
17
|
+
message: string;
|
|
18
|
+
availableScripts: string[];
|
|
19
|
+
script?: undefined;
|
|
20
|
+
environment?: undefined;
|
|
21
|
+
requiredTier?: undefined;
|
|
22
|
+
environmentTier?: undefined;
|
|
23
|
+
hint?: undefined;
|
|
24
|
+
errors?: undefined;
|
|
25
|
+
expectedParameters?: undefined;
|
|
26
|
+
providedParameters?: undefined;
|
|
27
|
+
preview?: undefined;
|
|
28
|
+
description?: undefined;
|
|
29
|
+
resolvedSql?: undefined;
|
|
30
|
+
parameters?: undefined;
|
|
31
|
+
requiresApproval?: undefined;
|
|
32
|
+
rowsAffected?: undefined;
|
|
33
|
+
recordCount?: undefined;
|
|
34
|
+
data?: undefined;
|
|
35
|
+
sqlError?: undefined;
|
|
36
|
+
} | {
|
|
37
|
+
success: boolean;
|
|
38
|
+
error: string;
|
|
39
|
+
message: string | undefined;
|
|
40
|
+
script: string;
|
|
41
|
+
environment: string;
|
|
42
|
+
availableScripts?: undefined;
|
|
43
|
+
requiredTier?: undefined;
|
|
44
|
+
environmentTier?: undefined;
|
|
45
|
+
hint?: undefined;
|
|
46
|
+
errors?: undefined;
|
|
47
|
+
expectedParameters?: undefined;
|
|
48
|
+
providedParameters?: undefined;
|
|
49
|
+
preview?: undefined;
|
|
50
|
+
description?: undefined;
|
|
51
|
+
resolvedSql?: undefined;
|
|
52
|
+
parameters?: undefined;
|
|
53
|
+
requiresApproval?: undefined;
|
|
54
|
+
rowsAffected?: undefined;
|
|
55
|
+
recordCount?: undefined;
|
|
56
|
+
data?: undefined;
|
|
57
|
+
sqlError?: undefined;
|
|
58
|
+
} | {
|
|
59
|
+
success: boolean;
|
|
60
|
+
error: string;
|
|
61
|
+
message: string;
|
|
62
|
+
script: string;
|
|
63
|
+
requiredTier: import("../config/EnvironmentManager.js").TierLevel;
|
|
64
|
+
environmentTier: import("../config/EnvironmentManager.js").TierLevel | undefined;
|
|
65
|
+
availableScripts?: undefined;
|
|
66
|
+
environment?: undefined;
|
|
67
|
+
hint?: undefined;
|
|
68
|
+
errors?: undefined;
|
|
69
|
+
expectedParameters?: undefined;
|
|
70
|
+
providedParameters?: undefined;
|
|
71
|
+
preview?: undefined;
|
|
72
|
+
description?: undefined;
|
|
73
|
+
resolvedSql?: undefined;
|
|
74
|
+
parameters?: undefined;
|
|
75
|
+
requiresApproval?: undefined;
|
|
76
|
+
rowsAffected?: undefined;
|
|
77
|
+
recordCount?: undefined;
|
|
78
|
+
data?: undefined;
|
|
79
|
+
sqlError?: undefined;
|
|
80
|
+
} | {
|
|
81
|
+
success: boolean;
|
|
82
|
+
error: string;
|
|
83
|
+
message: string;
|
|
84
|
+
hint: string;
|
|
85
|
+
availableScripts?: undefined;
|
|
86
|
+
script?: undefined;
|
|
87
|
+
environment?: undefined;
|
|
88
|
+
requiredTier?: undefined;
|
|
89
|
+
environmentTier?: undefined;
|
|
90
|
+
errors?: undefined;
|
|
91
|
+
expectedParameters?: undefined;
|
|
92
|
+
providedParameters?: undefined;
|
|
93
|
+
preview?: undefined;
|
|
94
|
+
description?: undefined;
|
|
95
|
+
resolvedSql?: undefined;
|
|
96
|
+
parameters?: undefined;
|
|
97
|
+
requiresApproval?: undefined;
|
|
98
|
+
rowsAffected?: undefined;
|
|
99
|
+
recordCount?: undefined;
|
|
100
|
+
data?: undefined;
|
|
101
|
+
sqlError?: undefined;
|
|
102
|
+
} | {
|
|
103
|
+
success: boolean;
|
|
104
|
+
error: string;
|
|
105
|
+
message: string;
|
|
106
|
+
errors: string[];
|
|
107
|
+
script: string;
|
|
108
|
+
expectedParameters: import("../config/ScriptManager.js").ScriptParameter[] | undefined;
|
|
109
|
+
providedParameters: Record<string, any>;
|
|
110
|
+
availableScripts?: undefined;
|
|
111
|
+
environment?: undefined;
|
|
112
|
+
requiredTier?: undefined;
|
|
113
|
+
environmentTier?: undefined;
|
|
114
|
+
hint?: undefined;
|
|
115
|
+
preview?: undefined;
|
|
116
|
+
description?: undefined;
|
|
117
|
+
resolvedSql?: undefined;
|
|
118
|
+
parameters?: undefined;
|
|
119
|
+
requiresApproval?: undefined;
|
|
120
|
+
rowsAffected?: undefined;
|
|
121
|
+
recordCount?: undefined;
|
|
122
|
+
data?: undefined;
|
|
123
|
+
sqlError?: undefined;
|
|
124
|
+
} | {
|
|
125
|
+
success: boolean;
|
|
126
|
+
preview: boolean;
|
|
127
|
+
script: string;
|
|
128
|
+
description: string;
|
|
129
|
+
environment: string;
|
|
130
|
+
resolvedSql: string;
|
|
131
|
+
parameters: Record<string, any>;
|
|
132
|
+
requiresApproval: boolean | undefined;
|
|
133
|
+
hint: string;
|
|
134
|
+
error?: undefined;
|
|
135
|
+
message?: undefined;
|
|
136
|
+
availableScripts?: undefined;
|
|
137
|
+
requiredTier?: undefined;
|
|
138
|
+
environmentTier?: undefined;
|
|
139
|
+
errors?: undefined;
|
|
140
|
+
expectedParameters?: undefined;
|
|
141
|
+
providedParameters?: undefined;
|
|
142
|
+
rowsAffected?: undefined;
|
|
143
|
+
recordCount?: undefined;
|
|
144
|
+
data?: undefined;
|
|
145
|
+
sqlError?: undefined;
|
|
146
|
+
} | {
|
|
147
|
+
success: boolean;
|
|
148
|
+
error: string;
|
|
149
|
+
requiresApproval: boolean;
|
|
150
|
+
script: string;
|
|
151
|
+
environment: string;
|
|
152
|
+
resolvedSql: string;
|
|
153
|
+
message: string;
|
|
154
|
+
availableScripts?: undefined;
|
|
155
|
+
requiredTier?: undefined;
|
|
156
|
+
environmentTier?: undefined;
|
|
157
|
+
hint?: undefined;
|
|
158
|
+
errors?: undefined;
|
|
159
|
+
expectedParameters?: undefined;
|
|
160
|
+
providedParameters?: undefined;
|
|
161
|
+
preview?: undefined;
|
|
162
|
+
description?: undefined;
|
|
163
|
+
parameters?: undefined;
|
|
164
|
+
rowsAffected?: undefined;
|
|
165
|
+
recordCount?: undefined;
|
|
166
|
+
data?: undefined;
|
|
167
|
+
sqlError?: undefined;
|
|
168
|
+
} | {
|
|
169
|
+
success: boolean;
|
|
170
|
+
script: string;
|
|
171
|
+
environment: string;
|
|
172
|
+
rowsAffected: any;
|
|
173
|
+
recordCount: any;
|
|
174
|
+
data: any;
|
|
175
|
+
message: string;
|
|
176
|
+
error?: undefined;
|
|
177
|
+
availableScripts?: undefined;
|
|
178
|
+
requiredTier?: undefined;
|
|
179
|
+
environmentTier?: undefined;
|
|
180
|
+
hint?: undefined;
|
|
181
|
+
errors?: undefined;
|
|
182
|
+
expectedParameters?: undefined;
|
|
183
|
+
providedParameters?: undefined;
|
|
184
|
+
preview?: undefined;
|
|
185
|
+
description?: undefined;
|
|
186
|
+
resolvedSql?: undefined;
|
|
187
|
+
parameters?: undefined;
|
|
188
|
+
requiresApproval?: undefined;
|
|
189
|
+
sqlError?: undefined;
|
|
190
|
+
} | {
|
|
191
|
+
success: boolean;
|
|
192
|
+
error: string;
|
|
193
|
+
script: string;
|
|
194
|
+
environment: string;
|
|
195
|
+
message: string;
|
|
196
|
+
sqlError: any;
|
|
197
|
+
availableScripts?: undefined;
|
|
198
|
+
requiredTier?: undefined;
|
|
199
|
+
environmentTier?: undefined;
|
|
200
|
+
hint?: undefined;
|
|
201
|
+
errors?: undefined;
|
|
202
|
+
expectedParameters?: undefined;
|
|
203
|
+
providedParameters?: undefined;
|
|
204
|
+
preview?: undefined;
|
|
205
|
+
description?: undefined;
|
|
206
|
+
resolvedSql?: undefined;
|
|
207
|
+
parameters?: undefined;
|
|
208
|
+
requiresApproval?: undefined;
|
|
209
|
+
rowsAffected?: undefined;
|
|
210
|
+
recordCount?: undefined;
|
|
211
|
+
data?: undefined;
|
|
212
|
+
}>;
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=RunScriptTool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RunScriptTool.d.ts","sourceRoot":"","sources":["../../src/tools/RunScriptTool.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAI1D,qBAAa,aAAc,YAAW,IAAI;IACxC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;IACnB,IAAI,SAAgB;IACpB,WAAW,SAAqI;IAEhJ,WAAW,EA0BN,GAAG,CAAC;IAEH,GAAG,CAAC,MAAM,EAAE;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACjC,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,iBAAiB,CAAC,EAAE,GAAG,CAAC;KACzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkKF"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import sql from "mssql";
|
|
2
|
+
import { getScriptManager } from "../config/ScriptManager.js";
|
|
3
|
+
import { getEnvironmentManager } from "../config/EnvironmentManager.js";
|
|
4
|
+
export class RunScriptTool {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.name = "run_script";
|
|
7
|
+
this.description = "Executes a named SQL script with parameters. Scripts are pre-approved SQL templates. Use list_scripts to see available scripts.";
|
|
8
|
+
this.inputSchema = {
|
|
9
|
+
type: "object",
|
|
10
|
+
properties: {
|
|
11
|
+
scriptName: {
|
|
12
|
+
type: "string",
|
|
13
|
+
description: "Name of the script to execute (from list_scripts)",
|
|
14
|
+
},
|
|
15
|
+
parameters: {
|
|
16
|
+
type: "object",
|
|
17
|
+
description: "Parameter values for the script (key-value pairs)",
|
|
18
|
+
additionalProperties: true,
|
|
19
|
+
},
|
|
20
|
+
preview: {
|
|
21
|
+
type: "boolean",
|
|
22
|
+
description: "If true, shows the resolved SQL without executing. Default: false",
|
|
23
|
+
},
|
|
24
|
+
confirm: {
|
|
25
|
+
type: "boolean",
|
|
26
|
+
description: "Required for scripts with requiresApproval or in environments with requireApproval. Set to true after reviewing preview.",
|
|
27
|
+
},
|
|
28
|
+
environment: {
|
|
29
|
+
type: "string",
|
|
30
|
+
description: "Target environment (optional, uses default if not specified)",
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
required: ["scriptName"],
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
async run(params) {
|
|
37
|
+
const { scriptName, parameters = {}, preview = false, confirm = false, environment } = params;
|
|
38
|
+
const scriptManager = getScriptManager();
|
|
39
|
+
const envManager = getEnvironmentManager();
|
|
40
|
+
// Get the script
|
|
41
|
+
const script = scriptManager.getScript(scriptName);
|
|
42
|
+
if (!script) {
|
|
43
|
+
const available = scriptManager.listScripts().map((s) => s.name);
|
|
44
|
+
return {
|
|
45
|
+
success: false,
|
|
46
|
+
error: "SCRIPT_NOT_FOUND",
|
|
47
|
+
message: `Script '${scriptName}' not found.`,
|
|
48
|
+
availableScripts: available,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
// Get environment config
|
|
52
|
+
const envConfig = envManager.getEnvironment(environment);
|
|
53
|
+
const envName = envConfig.name;
|
|
54
|
+
// Check if script can run in this environment
|
|
55
|
+
const envCheck = scriptManager.canRunInEnvironment(scriptName, envName);
|
|
56
|
+
if (!envCheck.allowed) {
|
|
57
|
+
return {
|
|
58
|
+
success: false,
|
|
59
|
+
error: "SCRIPT_NOT_ALLOWED",
|
|
60
|
+
message: envCheck.reason,
|
|
61
|
+
script: scriptName,
|
|
62
|
+
environment: envName,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
// Check tier compatibility
|
|
66
|
+
if (script.tier) {
|
|
67
|
+
const tierOrder = ["reader", "writer", "admin"];
|
|
68
|
+
const scriptTierIndex = tierOrder.indexOf(script.tier);
|
|
69
|
+
const envTierIndex = envConfig.tier ? tierOrder.indexOf(envConfig.tier) : 2; // default to admin
|
|
70
|
+
if (envTierIndex < scriptTierIndex) {
|
|
71
|
+
return {
|
|
72
|
+
success: false,
|
|
73
|
+
error: "INSUFFICIENT_TIER",
|
|
74
|
+
message: `Script '${scriptName}' requires tier '${script.tier}' but environment '${envName}' is tier '${envConfig.tier}'.`,
|
|
75
|
+
script: scriptName,
|
|
76
|
+
requiredTier: script.tier,
|
|
77
|
+
environmentTier: envConfig.tier,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Check readonly constraints
|
|
82
|
+
if (envConfig.readonly && !script.readonly) {
|
|
83
|
+
return {
|
|
84
|
+
success: false,
|
|
85
|
+
error: "ENVIRONMENT_READONLY",
|
|
86
|
+
message: `Environment '${envName}' is read-only. Script '${scriptName}' is not marked as readonly.`,
|
|
87
|
+
hint: "Mark the script as readonly: true in scripts.json if it only performs SELECT operations.",
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
// Resolve parameters
|
|
91
|
+
const { sql: resolvedSql, errors } = scriptManager.resolveParameters(script, parameters);
|
|
92
|
+
if (errors.length > 0) {
|
|
93
|
+
return {
|
|
94
|
+
success: false,
|
|
95
|
+
error: "PARAMETER_ERROR",
|
|
96
|
+
message: "Failed to resolve script parameters.",
|
|
97
|
+
errors,
|
|
98
|
+
script: scriptName,
|
|
99
|
+
expectedParameters: script.parameters,
|
|
100
|
+
providedParameters: parameters,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
// Preview mode - just return the resolved SQL
|
|
104
|
+
if (preview) {
|
|
105
|
+
return {
|
|
106
|
+
success: true,
|
|
107
|
+
preview: true,
|
|
108
|
+
script: scriptName,
|
|
109
|
+
description: script.description,
|
|
110
|
+
environment: envName,
|
|
111
|
+
resolvedSql,
|
|
112
|
+
parameters: parameters,
|
|
113
|
+
requiresApproval: script.requiresApproval || envConfig.requireApproval,
|
|
114
|
+
hint: script.requiresApproval || envConfig.requireApproval
|
|
115
|
+
? "This script requires confirmation. Run again with confirm: true to execute."
|
|
116
|
+
: "Run again with preview: false to execute.",
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
// Check approval requirements
|
|
120
|
+
const needsApproval = script.requiresApproval || envConfig.requireApproval;
|
|
121
|
+
if (needsApproval && !confirm) {
|
|
122
|
+
return {
|
|
123
|
+
success: false,
|
|
124
|
+
error: "APPROVAL_REQUIRED",
|
|
125
|
+
requiresApproval: true,
|
|
126
|
+
script: scriptName,
|
|
127
|
+
environment: envName,
|
|
128
|
+
resolvedSql,
|
|
129
|
+
message: `Script '${scriptName}' requires explicit approval. Review the SQL and run again with confirm: true.`,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
// Execute the script
|
|
133
|
+
try {
|
|
134
|
+
const pool = params.pool;
|
|
135
|
+
if (!pool) {
|
|
136
|
+
return {
|
|
137
|
+
success: false,
|
|
138
|
+
error: "NO_CONNECTION",
|
|
139
|
+
message: "No database connection available.",
|
|
140
|
+
script: scriptName,
|
|
141
|
+
environment: envName,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
const request = pool.request();
|
|
145
|
+
// For actual execution, we use parameterized queries for safety
|
|
146
|
+
// Add parameters to the request
|
|
147
|
+
for (const param of script.parameters || []) {
|
|
148
|
+
const value = parameters[param.name] ?? param.default;
|
|
149
|
+
if (value !== undefined) {
|
|
150
|
+
// Map our types to SQL types
|
|
151
|
+
switch (param.type) {
|
|
152
|
+
case "number":
|
|
153
|
+
request.input(param.name, sql.Float, value);
|
|
154
|
+
break;
|
|
155
|
+
case "boolean":
|
|
156
|
+
request.input(param.name, sql.Bit, value);
|
|
157
|
+
break;
|
|
158
|
+
default:
|
|
159
|
+
request.input(param.name, sql.NVarChar(sql.MAX), value);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
const result = await request.query(script.sql);
|
|
164
|
+
return {
|
|
165
|
+
success: true,
|
|
166
|
+
script: scriptName,
|
|
167
|
+
environment: envName,
|
|
168
|
+
rowsAffected: result.rowsAffected.reduce((a, b) => a + b, 0),
|
|
169
|
+
recordCount: result.recordset?.length,
|
|
170
|
+
data: result.recordset,
|
|
171
|
+
message: `Script '${scriptName}' executed successfully.`,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
return {
|
|
176
|
+
success: false,
|
|
177
|
+
error: "EXECUTION_ERROR",
|
|
178
|
+
script: scriptName,
|
|
179
|
+
environment: envName,
|
|
180
|
+
message: `Script execution failed: ${error.message}`,
|
|
181
|
+
sqlError: error.message,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=RunScriptTool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RunScriptTool.js","sourceRoot":"","sources":["../../src/tools/RunScriptTool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
type SearchParams = {
|
|
3
|
+
tablePattern?: string;
|
|
4
|
+
columnPattern?: string;
|
|
5
|
+
limit?: number;
|
|
6
|
+
tableLimit?: number;
|
|
7
|
+
columnLimit?: number;
|
|
8
|
+
tableOffset?: number;
|
|
9
|
+
columnOffset?: number;
|
|
10
|
+
};
|
|
11
|
+
type PaginationInfo = {
|
|
12
|
+
offset: number;
|
|
13
|
+
limit: number;
|
|
14
|
+
total: number;
|
|
15
|
+
hasMore: boolean;
|
|
16
|
+
};
|
|
17
|
+
type SearchResult = {
|
|
18
|
+
success: boolean;
|
|
19
|
+
message?: string;
|
|
20
|
+
totalTables?: number;
|
|
21
|
+
totalColumns?: number;
|
|
22
|
+
tables?: Array<{
|
|
23
|
+
schemaName: string;
|
|
24
|
+
tableName: string;
|
|
25
|
+
}>;
|
|
26
|
+
columns?: Array<{
|
|
27
|
+
schemaName: string;
|
|
28
|
+
tableName: string;
|
|
29
|
+
columnName: string;
|
|
30
|
+
dataType: string;
|
|
31
|
+
}>;
|
|
32
|
+
fuzzySuggestions?: Array<{
|
|
33
|
+
schemaName: string;
|
|
34
|
+
tableName: string;
|
|
35
|
+
similarity: number;
|
|
36
|
+
}>;
|
|
37
|
+
fuzzySearchTerm?: string;
|
|
38
|
+
tablesPage?: PaginationInfo;
|
|
39
|
+
columnsPage?: PaginationInfo;
|
|
40
|
+
};
|
|
41
|
+
export declare class SearchSchemaTool implements Tool {
|
|
42
|
+
[key: string]: any;
|
|
43
|
+
name: string;
|
|
44
|
+
description: string;
|
|
45
|
+
inputSchema: {
|
|
46
|
+
readonly type: "object";
|
|
47
|
+
readonly properties: {
|
|
48
|
+
readonly tablePattern: {
|
|
49
|
+
readonly type: "string";
|
|
50
|
+
readonly description: "Wildcard pattern for table names (e.g. 'doc%').";
|
|
51
|
+
};
|
|
52
|
+
readonly columnPattern: {
|
|
53
|
+
readonly type: "string";
|
|
54
|
+
readonly description: "Wildcard pattern for column names (e.g. '%id').";
|
|
55
|
+
};
|
|
56
|
+
readonly limit: {
|
|
57
|
+
readonly type: "number";
|
|
58
|
+
readonly description: "Maximum rows to return per section (default 50, max 200).";
|
|
59
|
+
};
|
|
60
|
+
readonly tableLimit: {
|
|
61
|
+
readonly type: "number";
|
|
62
|
+
readonly description: "Override for table section limit (defaults to limit).";
|
|
63
|
+
};
|
|
64
|
+
readonly columnLimit: {
|
|
65
|
+
readonly type: "number";
|
|
66
|
+
readonly description: "Override for column section limit (defaults to limit).";
|
|
67
|
+
};
|
|
68
|
+
readonly tableOffset: {
|
|
69
|
+
readonly type: "number";
|
|
70
|
+
readonly description: "Number of table rows to skip (for pagination).";
|
|
71
|
+
};
|
|
72
|
+
readonly columnOffset: {
|
|
73
|
+
readonly type: "number";
|
|
74
|
+
readonly description: "Number of column rows to skip (for pagination).";
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
private normalizePattern;
|
|
79
|
+
private stripWildcards;
|
|
80
|
+
private normalizeLimit;
|
|
81
|
+
private normalizeOffset;
|
|
82
|
+
private levenshteinDistance;
|
|
83
|
+
private calculateSimilarity;
|
|
84
|
+
private findSimilarTables;
|
|
85
|
+
run(params: SearchParams): Promise<SearchResult>;
|
|
86
|
+
}
|
|
87
|
+
export {};
|
|
88
|
+
//# sourceMappingURL=SearchSchemaTool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SearchSchemaTool.d.ts","sourceRoot":"","sources":["../../src/tools/SearchSchemaTool.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAe1D,KAAK,YAAY,GAAG;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1D,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjG,gBAAgB,CAAC,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,WAAW,CAAC,EAAE,cAAc,CAAC;CAC9B,CAAC;AAEF,qBAAa,gBAAiB,YAAW,IAAI;IAC3C,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;IACnB,IAAI,SAAmB;IACvB,WAAW,SAAmF;IAC9F,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAgCA;IAEX,OAAO,CAAC,gBAAgB;IAWxB,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,mBAAmB;IA0B3B,OAAO,CAAC,mBAAmB;YAWb,iBAAiB;IAwBzB,GAAG,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;CA0HvD"}
|