snow-flow 10.0.196 → 10.0.197
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/package.json +2 -1
- package/src/cli/cmd/tui/component/dialog-auth.tsx +18 -14
- package/src/servicenow/servicenow-mcp-unified/tools/automation/snow_execute_script.ts +67 -35
- package/src/servicenow/servicenow-mcp-unified/tools/index.ts +0 -18
- package/src/servicenow/servicenow-mcp-unified/tools/security/snow_analyze_threat_intelligence.ts +2 -4
- package/src/servicenow/servicenow-mcp-unified/tools/security/snow_audit_trail_analysis.ts +1 -3
- package/src/servicenow/servicenow-mcp-unified/tools/security/snow_automate_threat_response.ts +2 -4
- package/src/servicenow/servicenow-mcp-unified/tools/security/snow_create_access_control.ts +2 -4
- package/src/servicenow/servicenow-mcp-unified/tools/security/snow_create_audit_rule.ts +1 -3
- package/src/servicenow/servicenow-mcp-unified/tools/ui-policies/snow_create_ui_policy_action.ts +86 -31
- package/src/servicenow/shared/mcp-prompt-manager.ts +7 -7
- package/tsconfig.servicenow.json +20 -0
- package/src/servicenow/base-mcp-server.ts +0 -732
- package/src/servicenow/cli/auth.ts +0 -669
- package/src/servicenow/cli/deploy-artifact.ts +0 -304
- package/src/servicenow/cli/enterprise-refresh.ts +0 -93
- package/src/servicenow/cli/enterprise.ts +0 -446
- package/src/servicenow/cli/session.ts +0 -45
- package/src/servicenow/config/snow-code-config.ts +0 -154
- package/src/servicenow/index.ts +0 -126
- package/src/servicenow/mcp-config.ts +0 -157
- package/src/servicenow/servicenow-automation-mcp.ts +0 -2895
- package/src/servicenow/servicenow-change-virtualagent-pa-mcp-enhanced.ts +0 -974
- package/src/servicenow/servicenow-change-virtualagent-pa-mcp.ts +0 -1466
- package/src/servicenow/servicenow-cmdb-event-hr-csm-devops-mcp-enhanced.ts +0 -1311
- package/src/servicenow/servicenow-cmdb-event-hr-csm-devops-mcp.ts +0 -1616
- package/src/servicenow/servicenow-deployment-mcp.ts +0 -10306
- package/src/servicenow/servicenow-development-assistant-mcp.ts +0 -4925
- package/src/servicenow/servicenow-flow-workspace-mobile-mcp-enhanced.ts +0 -1038
- package/src/servicenow/servicenow-flow-workspace-mobile-mcp.ts +0 -4311
- package/src/servicenow/servicenow-integration-mcp.ts +0 -906
- package/src/servicenow/servicenow-itam-mcp.ts +0 -673
- package/src/servicenow/servicenow-knowledge-catalog-mcp-enhanced.ts +0 -836
- package/src/servicenow/servicenow-knowledge-catalog-mcp.ts +0 -1898
- package/src/servicenow/servicenow-local-development-mcp.ts +0 -629
- package/src/servicenow/servicenow-machine-learning-mcp.ts +0 -4095
- package/src/servicenow/servicenow-mcp-server.ts +0 -736
- package/src/servicenow/servicenow-mcp-unified/tools/ai-ml-MIGRATED/index.ts +0 -5
- package/src/servicenow/servicenow-mcp-unified/tools/ai-ml-MIGRATED/snow_predict.ts +0 -44
- package/src/servicenow/servicenow-mcp-unified/tools/ai-ml-MIGRATED/snow_train_classifier.ts +0 -46
- package/src/servicenow/servicenow-mcp-unified/tools/machine-learning-MIGRATED/README.md +0 -149
- package/src/servicenow/servicenow-mcp-unified/tools/machine-learning-MIGRATED/index.ts +0 -48
- package/src/servicenow/servicenow-mcp-unified/tools/machine-learning-MIGRATED/ml_classify_incident.ts +0 -197
- package/src/servicenow/servicenow-mcp-unified/tools/machine-learning-MIGRATED/ml_detect_anomalies.ts +0 -191
- package/src/servicenow/servicenow-mcp-unified/tools/machine-learning-MIGRATED/ml_forecast_incidents.ts +0 -273
- package/src/servicenow/servicenow-mcp-unified/tools/machine-learning-MIGRATED/ml_hybrid_recommendation.ts +0 -346
- package/src/servicenow/servicenow-mcp-unified/tools/machine-learning-MIGRATED/ml_performance_analytics.ts +0 -232
- package/src/servicenow/servicenow-mcp-unified/tools/machine-learning-MIGRATED/ml_predict_change_risk.ts +0 -186
- package/src/servicenow/servicenow-mcp-unified/tools/machine-learning-MIGRATED/ml_train_anomaly_detector.ts +0 -298
- package/src/servicenow/servicenow-mcp-unified/tools/machine-learning-MIGRATED/ml_train_change_risk.ts +0 -267
- package/src/servicenow/servicenow-mcp-unified/tools/machine-learning-MIGRATED/ml_train_incident_classifier.ts +0 -386
- package/src/servicenow/servicenow-mcp-unified/tools/script-includes/index.ts +0 -4
- package/src/servicenow/servicenow-mcp-unified/tools/ui-actions/index.ts +0 -4
- package/src/servicenow/servicenow-notifications-mcp.ts +0 -413
- package/src/servicenow/servicenow-operations-mcp.ts +0 -4041
- package/src/servicenow/servicenow-platform-development-mcp.ts +0 -1081
- package/src/servicenow/servicenow-progressive-indexer.ts +0 -366
- package/src/servicenow/servicenow-reporting-analytics-mcp.ts +0 -1485
- package/src/servicenow/servicenow-secops-mcp.ts +0 -690
- package/src/servicenow/servicenow-security-compliance-mcp.ts +0 -1267
- package/src/servicenow/servicenow-system-properties-mcp.ts +0 -1339
- package/src/servicenow/servicenow-update-set-mcp.ts +0 -964
- package/src/servicenow/shared/MCP-PROMPTS.md +0 -226
- package/src/servicenow/shared/agent-context-provider.ts +0 -354
- package/src/servicenow/shared/base-mcp-server.ts +0 -2570
- package/src/servicenow/shared/enhanced-base-mcp-server.ts +0 -387
- package/src/servicenow/shared/mcp-logger.ts +0 -269
- package/src/servicenow/shared/mcp-memory-manager.ts +0 -567
- package/src/servicenow/shared/mcp-resource-manager.ts +0 -367
- package/src/servicenow/shared/mcp-types.ts +0 -58
- package/src/servicenow/shared/reliable-memory-manager.ts +0 -315
- package/src/servicenow/shared/response-limiter.ts +0 -129
- package/src/servicenow/utils/dynamic-models.ts +0 -101
- package/src/servicenow/utils/logger.ts +0 -99
- package/src/servicenow/utils/memory-safe-collections.ts +0 -235
- package/src/servicenow/utils/servicenow-client.ts +0 -3530
- package/src/servicenow/utils/snow-oauth.ts +0 -1164
- package/src/servicenow/utils/sync-mcp-configs.ts +0 -114
- package/src/servicenow/utils/timer-registry.ts +0 -346
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
|
-
"version": "10.0.
|
|
3
|
+
"version": "10.0.197",
|
|
4
4
|
"name": "snow-flow",
|
|
5
5
|
"description": "Snow-Flow - ServiceNow Multi-Agent Development Framework powered by AI",
|
|
6
6
|
"license": "Elastic-2.0",
|
|
7
7
|
"private": false,
|
|
8
8
|
"scripts": {
|
|
9
9
|
"typecheck": "tsgo --noEmit",
|
|
10
|
+
"typecheck:servicenow": "tsgo --project tsconfig.servicenow.json --noEmit",
|
|
10
11
|
"test": "bun test",
|
|
11
12
|
"build": "bun run script/build.ts",
|
|
12
13
|
"dev": "bun run --conditions=browser ./src/index.ts",
|
|
@@ -1105,31 +1105,35 @@ function DialogAuthEnterprise() {
|
|
|
1105
1105
|
}),
|
|
1106
1106
|
})
|
|
1107
1107
|
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1108
|
+
const responseData = await response.json().catch(() => ({}))
|
|
1109
|
+
|
|
1110
|
+
// 202 = pending approval, or explicit pending status
|
|
1111
|
+
const isPending = response.status === 202 || responseData.status === "pending" || responseData.error === "pending"
|
|
1112
|
+
if (isPending && attempt < maxAttempts) {
|
|
1113
|
+
toast.show({ variant: "info", message: `Waiting for browser approval... (${attempt}/${maxAttempts})`, duration: 2000 })
|
|
1114
|
+
await new Promise(r => setTimeout(r, 2000))
|
|
1115
|
+
continue
|
|
1111
1116
|
}
|
|
1112
1117
|
|
|
1113
|
-
|
|
1118
|
+
if (response.ok && !isPending) {
|
|
1119
|
+
data = responseData
|
|
1120
|
+
break
|
|
1121
|
+
}
|
|
1114
1122
|
|
|
1115
1123
|
// Billing redirect — not retryable
|
|
1116
|
-
if (
|
|
1117
|
-
toast.show({ variant: "error", message:
|
|
1124
|
+
if (responseData.billingUrl) {
|
|
1125
|
+
toast.show({ variant: "error", message: responseData.message || responseData.error || "Subscription required", duration: 8000 })
|
|
1118
1126
|
toast.show({ variant: "info", message: "Opening billing page...", duration: 4000 })
|
|
1119
|
-
tryOpenBrowser(
|
|
1127
|
+
tryOpenBrowser(responseData.billingUrl)
|
|
1120
1128
|
setStep("code")
|
|
1121
1129
|
return
|
|
1122
1130
|
}
|
|
1123
1131
|
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
if (isPending && attempt < maxAttempts) {
|
|
1127
|
-
toast.show({ variant: "info", message: `Waiting for browser approval... (${attempt}/${maxAttempts})`, duration: 2000 })
|
|
1128
|
-
await new Promise(r => setTimeout(r, 2000))
|
|
1129
|
-
continue
|
|
1132
|
+
if (isPending) {
|
|
1133
|
+
throw new Error("Verification timed out — please approve in your browser and try again")
|
|
1130
1134
|
}
|
|
1131
1135
|
|
|
1132
|
-
throw new Error(
|
|
1136
|
+
throw new Error(responseData.error || "Verification failed")
|
|
1133
1137
|
}
|
|
1134
1138
|
|
|
1135
1139
|
if (!data) {
|
|
@@ -8,15 +8,15 @@
|
|
|
8
8
|
* ES5 only! ServiceNow runs on Rhino engine.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import { MCPToolDefinition, ServiceNowContext, ToolResult } from "../../shared/types.js"
|
|
11
|
+
import type { MCPToolDefinition, ServiceNowContext, ToolResult } from "../../shared/types.js"
|
|
12
12
|
import { getAuthenticatedClient } from "../../shared/auth.js"
|
|
13
13
|
import { createSuccessResult, createErrorResult, SnowFlowError, ErrorType } from "../../shared/error-handler.js"
|
|
14
|
-
import
|
|
14
|
+
import { randomBytes } from "crypto"
|
|
15
15
|
|
|
16
16
|
const ENDPOINT_SERVICE_ID = "snow_flow_exec"
|
|
17
17
|
const ENDPOINT_PATH = "/execute"
|
|
18
18
|
|
|
19
|
-
const
|
|
19
|
+
const endpointCache = new Map<string, { namespace: string }>()
|
|
20
20
|
|
|
21
21
|
const OPERATION_SCRIPT = `(function process(request, response) {
|
|
22
22
|
var body = request.body.data;
|
|
@@ -213,53 +213,85 @@ export async function execute(args: Record<string, unknown>, context: ServiceNow
|
|
|
213
213
|
}
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
+
function getEndpointUrl(context: ServiceNowContext): string {
|
|
217
|
+
const cached = endpointCache.get(context.instanceUrl)
|
|
218
|
+
if (cached) return `/api/${cached.namespace}/${ENDPOINT_SERVICE_ID}${ENDPOINT_PATH}`
|
|
219
|
+
return `/api/${ENDPOINT_SERVICE_ID}${ENDPOINT_PATH}`
|
|
220
|
+
}
|
|
221
|
+
|
|
216
222
|
async function ensureEndpoint(context: ServiceNowContext): Promise<boolean> {
|
|
217
|
-
if (
|
|
223
|
+
if (endpointCache.has(context.instanceUrl)) return true
|
|
218
224
|
|
|
219
225
|
const client = await getAuthenticatedClient(context)
|
|
220
226
|
|
|
221
227
|
const check = await client.get("/api/now/table/sys_ws_definition", {
|
|
222
228
|
params: {
|
|
223
229
|
sysparm_query: `service_id=${ENDPOINT_SERVICE_ID}`,
|
|
224
|
-
sysparm_fields: "sys_id",
|
|
230
|
+
sysparm_fields: "sys_id,namespace,base_uri",
|
|
225
231
|
sysparm_limit: 1,
|
|
226
232
|
},
|
|
227
233
|
})
|
|
228
234
|
|
|
229
235
|
const existing = check.data?.result?.[0]
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
236
|
+
const svcId =
|
|
237
|
+
existing?.sys_id ||
|
|
238
|
+
(await (async () => {
|
|
239
|
+
const svc = await client.post("/api/now/table/sys_ws_definition", {
|
|
240
|
+
name: "Snow-Flow Script Executor",
|
|
241
|
+
service_id: ENDPOINT_SERVICE_ID,
|
|
242
|
+
short_description: "Synchronous script execution endpoint for Snow-Flow",
|
|
243
|
+
active: true,
|
|
244
|
+
})
|
|
237
245
|
|
|
238
|
-
|
|
239
|
-
|
|
246
|
+
const id = svc.data?.result?.sys_id
|
|
247
|
+
if (!id) return null
|
|
240
248
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
+
await client.post("/api/now/table/sys_ws_operation", {
|
|
250
|
+
name: "Execute Script",
|
|
251
|
+
web_service_definition: id,
|
|
252
|
+
http_method: "POST",
|
|
253
|
+
relative_path: ENDPOINT_PATH,
|
|
254
|
+
operation_script: OPERATION_SCRIPT,
|
|
255
|
+
active: true,
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
return id
|
|
259
|
+
})())
|
|
260
|
+
|
|
261
|
+
if (!svcId) return false
|
|
249
262
|
|
|
250
|
-
|
|
263
|
+
const svcRecord =
|
|
264
|
+
existing ||
|
|
265
|
+
(
|
|
266
|
+
await client
|
|
267
|
+
.get("/api/now/table/sys_ws_definition/" + svcId, {
|
|
268
|
+
params: { sysparm_fields: "namespace,base_uri" },
|
|
269
|
+
})
|
|
270
|
+
.catch(() => null)
|
|
271
|
+
)?.data?.result
|
|
272
|
+
|
|
273
|
+
const ns = svcRecord?.namespace || ""
|
|
274
|
+
|
|
275
|
+
const candidates = ns
|
|
276
|
+
? [`/api/${ns}/${ENDPOINT_SERVICE_ID}${ENDPOINT_PATH}`, `/api/${ENDPOINT_SERVICE_ID}${ENDPOINT_PATH}`]
|
|
277
|
+
: [`/api/${ENDPOINT_SERVICE_ID}${ENDPOINT_PATH}`]
|
|
278
|
+
|
|
279
|
+
for (const url of candidates) {
|
|
280
|
+
const ping = await client.post(url, { script: "'pong'", execution_id: "deploy_verify" }).catch(() => null)
|
|
281
|
+
|
|
282
|
+
if (ping?.data?.result?.success === true) {
|
|
283
|
+
const parts = url.replace(`/${ENDPOINT_SERVICE_ID}${ENDPOINT_PATH}`, "").replace("/api/", "")
|
|
284
|
+
endpointCache.set(context.instanceUrl, { namespace: parts || ENDPOINT_SERVICE_ID })
|
|
285
|
+
return true
|
|
286
|
+
}
|
|
251
287
|
}
|
|
252
288
|
|
|
253
|
-
|
|
254
|
-
.
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
})
|
|
258
|
-
.catch(() => null)
|
|
289
|
+
if (ns) {
|
|
290
|
+
endpointCache.set(context.instanceUrl, { namespace: ns })
|
|
291
|
+
return true
|
|
292
|
+
}
|
|
259
293
|
|
|
260
|
-
|
|
261
|
-
if (ok) deployed.set(context.instanceUrl, true)
|
|
262
|
-
return ok
|
|
294
|
+
return false
|
|
263
295
|
}
|
|
264
296
|
|
|
265
297
|
async function executeViaSyncApi(
|
|
@@ -276,7 +308,7 @@ async function executeViaSyncApi(
|
|
|
276
308
|
const client = await getAuthenticatedClient(context)
|
|
277
309
|
|
|
278
310
|
const response = await client
|
|
279
|
-
.post(
|
|
311
|
+
.post(getEndpointUrl(context), {
|
|
280
312
|
script: params.script,
|
|
281
313
|
execution_id: params.executionId,
|
|
282
314
|
})
|
|
@@ -346,7 +378,7 @@ async function executeViaScheduler(
|
|
|
346
378
|
const escape = (str: string) =>
|
|
347
379
|
str.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\n/g, "\\n").replace(/\r/g, "\\r")
|
|
348
380
|
|
|
349
|
-
const executionId = `exec_${Date.now()}_${
|
|
381
|
+
const executionId = `exec_${Date.now()}_${randomBytes(6).toString("hex")}`
|
|
350
382
|
const marker = `SNOW_FLOW_EXEC_${executionId}`
|
|
351
383
|
|
|
352
384
|
const wrapped = `
|
|
@@ -561,7 +593,7 @@ async function executeScript(
|
|
|
561
593
|
},
|
|
562
594
|
context: ServiceNowContext,
|
|
563
595
|
): Promise<ToolResult> {
|
|
564
|
-
const executionId = `exec_${Date.now()}_${
|
|
596
|
+
const executionId = `exec_${Date.now()}_${randomBytes(6).toString("hex")}`
|
|
565
597
|
|
|
566
598
|
const syncResult = await executeViaSyncApi({ ...params, executionId }, context)
|
|
567
599
|
if (syncResult) return syncResult
|
|
@@ -56,9 +56,6 @@ export * from "./lists/index.js"
|
|
|
56
56
|
// Business Rules (2 tools)
|
|
57
57
|
export * from "./business-rules/index.js"
|
|
58
58
|
|
|
59
|
-
// Script Includes (1 tool)
|
|
60
|
-
export * from "./script-includes/index.js"
|
|
61
|
-
|
|
62
59
|
// REST API tools moved to Integration folder (see snow_rest_message_manage, snow_create_rest_message)
|
|
63
60
|
|
|
64
61
|
// SLA (2 tools)
|
|
@@ -94,9 +91,6 @@ export * from "./journals/index.js"
|
|
|
94
91
|
// Data Policies (2 tools)
|
|
95
92
|
export * from "./data-policies/index.js"
|
|
96
93
|
|
|
97
|
-
// UI Actions (1 tool)
|
|
98
|
-
export * from "./ui-actions/index.js"
|
|
99
|
-
|
|
100
94
|
// Workspace (10 tools)
|
|
101
95
|
export * from "./workspace/index.js"
|
|
102
96
|
|
|
@@ -187,9 +181,6 @@ export * from "./project/index.js"
|
|
|
187
181
|
// Performance Analytics (3 tools)
|
|
188
182
|
export * from "./performance-analytics/index.js"
|
|
189
183
|
|
|
190
|
-
// Predictive Intelligence (5 tools)
|
|
191
|
-
export * from "./predictive-intelligence/index.js"
|
|
192
|
-
|
|
193
184
|
// Service Portal (3 tools)
|
|
194
185
|
export * from "./service-portal/index.js"
|
|
195
186
|
|
|
@@ -217,12 +208,6 @@ export * from "./notifications/index.js"
|
|
|
217
208
|
// Mobile (3 tools)
|
|
218
209
|
export * from "./mobile/index.js"
|
|
219
210
|
|
|
220
|
-
// AI & ML (3 tools)
|
|
221
|
-
export * from "./ai-ml/index.js"
|
|
222
|
-
|
|
223
|
-
// Machine Learning - TensorFlow.js Neural Networks (9 tools)
|
|
224
|
-
export * from "./machine-learning/index.js"
|
|
225
|
-
|
|
226
211
|
// ATF (Automated Test Framework) (6 tools)
|
|
227
212
|
export * from "./atf/index.js"
|
|
228
213
|
|
|
@@ -244,9 +229,6 @@ export * from "./integration/index.js"
|
|
|
244
229
|
// Platform (8 tools)
|
|
245
230
|
export * from "./platform/index.js"
|
|
246
231
|
|
|
247
|
-
// Monitoring (1 tool)
|
|
248
|
-
export * from "./monitoring/index.js"
|
|
249
|
-
|
|
250
232
|
// Blast Radius (5 tools)
|
|
251
233
|
export * from "./blast-radius/index.js"
|
|
252
234
|
|
package/src/servicenow/servicenow-mcp-unified/tools/security/snow_analyze_threat_intelligence.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js"
|
|
2
|
-
import type { ServiceNowClient } from "../../../../utils/servicenow-client.js"
|
|
3
|
-
import type { MCPLogger } from "../../../shared/mcp-logger.js"
|
|
4
2
|
import { MCPToolDefinition, ToolResult } from "../../shared/types.js"
|
|
5
3
|
import { ServiceNowContext } from "../../shared/types.js"
|
|
6
4
|
|
|
@@ -66,8 +64,8 @@ export interface AnalyzeThreatIntelligenceArgs {
|
|
|
66
64
|
|
|
67
65
|
export async function analyzeThreatIntelligence(
|
|
68
66
|
args: AnalyzeThreatIntelligenceArgs,
|
|
69
|
-
client:
|
|
70
|
-
logger:
|
|
67
|
+
client: any,
|
|
68
|
+
logger: any,
|
|
71
69
|
) {
|
|
72
70
|
try {
|
|
73
71
|
const { ioc_value, ioc_type, threat_feed_sources = [], correlation_timeframe = "24_hours" } = args
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js"
|
|
2
|
-
import type { ServiceNowClient } from "../../../../utils/servicenow-client.js"
|
|
3
|
-
import type { MCPLogger } from "../../../shared/mcp-logger.js"
|
|
4
2
|
import { MCPToolDefinition, ToolResult, ServiceNowContext } from "../../shared/types.js"
|
|
5
3
|
|
|
6
4
|
export const toolDefinition: MCPToolDefinition = {
|
|
@@ -63,7 +61,7 @@ export interface AuditTrailAnalysisArgs {
|
|
|
63
61
|
exportFormat?: "json" | "csv" | "pdf"
|
|
64
62
|
}
|
|
65
63
|
|
|
66
|
-
export async function auditTrailAnalysis(args: AuditTrailAnalysisArgs, client:
|
|
64
|
+
export async function auditTrailAnalysis(args: AuditTrailAnalysisArgs, client: any, logger: any) {
|
|
67
65
|
try {
|
|
68
66
|
const timeframe = args.timeframe || "24h"
|
|
69
67
|
let query = ""
|
package/src/servicenow/servicenow-mcp-unified/tools/security/snow_automate_threat_response.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js"
|
|
2
|
-
import type { ServiceNowClient } from "../../../../utils/servicenow-client.js"
|
|
3
|
-
import type { MCPLogger } from "../../../shared/mcp-logger.js"
|
|
4
2
|
import { MCPToolDefinition, ToolResult, ServiceNowContext } from "../../shared/types.js"
|
|
5
3
|
|
|
6
4
|
export const toolDefinition: MCPToolDefinition = {
|
|
@@ -64,8 +62,8 @@ export interface AutomateThreatResponseArgs {
|
|
|
64
62
|
|
|
65
63
|
export async function automateThreatResponse(
|
|
66
64
|
args: AutomateThreatResponseArgs,
|
|
67
|
-
client:
|
|
68
|
-
logger:
|
|
65
|
+
client: any,
|
|
66
|
+
logger: any,
|
|
69
67
|
) {
|
|
70
68
|
try {
|
|
71
69
|
const { threat_id, response_level, automated_actions = false, notification_groups = [] } = args
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js"
|
|
2
|
-
import type { ServiceNowClient } from "../../../../utils/servicenow-client.js"
|
|
3
|
-
import type { MCPLogger } from "../../../shared/mcp-logger.js"
|
|
4
2
|
import { MCPToolDefinition, ToolResult, ServiceNowContext } from "../../shared/types.js"
|
|
5
3
|
|
|
6
4
|
export const toolDefinition: MCPToolDefinition = {
|
|
@@ -76,7 +74,7 @@ export interface CreateAccessControlArgs {
|
|
|
76
74
|
active?: boolean
|
|
77
75
|
}
|
|
78
76
|
|
|
79
|
-
export async function createAccessControl(args: CreateAccessControlArgs, client:
|
|
77
|
+
export async function createAccessControl(args: CreateAccessControlArgs, client: any, logger: any) {
|
|
80
78
|
try {
|
|
81
79
|
logger.info("Creating Access Control...")
|
|
82
80
|
|
|
@@ -118,7 +116,7 @@ export async function createAccessControl(args: CreateAccessControlArgs, client:
|
|
|
118
116
|
|
|
119
117
|
async function getTableInfo(
|
|
120
118
|
tableName: string,
|
|
121
|
-
client:
|
|
119
|
+
client: any,
|
|
122
120
|
): Promise<{ name: string; label: string } | null> {
|
|
123
121
|
try {
|
|
124
122
|
const tableResponse = await client.searchRecords("sys_db_object", `name=${tableName}`, 1)
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js"
|
|
2
|
-
import type { ServiceNowClient } from "../../../../utils/servicenow-client.js"
|
|
3
|
-
import type { MCPLogger } from "../../../shared/mcp-logger.js"
|
|
4
2
|
import { MCPToolDefinition, ToolResult, ServiceNowContext } from "../../shared/types.js"
|
|
5
3
|
|
|
6
4
|
export const toolDefinition: MCPToolDefinition = {
|
|
@@ -79,7 +77,7 @@ export interface CreateAuditRuleArgs {
|
|
|
79
77
|
active?: boolean
|
|
80
78
|
}
|
|
81
79
|
|
|
82
|
-
export async function createAuditRule(args: CreateAuditRuleArgs, client:
|
|
80
|
+
export async function createAuditRule(args: CreateAuditRuleArgs, client: any, logger: any) {
|
|
83
81
|
try {
|
|
84
82
|
logger.info("Creating Audit Rule...")
|
|
85
83
|
|
package/src/servicenow/servicenow-mcp-unified/tools/ui-policies/snow_create_ui_policy_action.ts
CHANGED
|
@@ -4,9 +4,22 @@
|
|
|
4
4
|
* Creates a UI Policy Action (sys_ui_policy_action) that controls field
|
|
5
5
|
* visibility, mandatory state, or read-only state when a UI policy's
|
|
6
6
|
* conditions are met.
|
|
7
|
+
*
|
|
8
|
+
* ServiceNow field mapping:
|
|
9
|
+
* - visible/mandatory/disabled are STRING fields with values: "true", "false", "ignore"
|
|
10
|
+
* - "disabled" is the actual column name for "Read only" in the UI
|
|
11
|
+
* - "table" is auto-derived from the parent UI policy but must be sent for field validation
|
|
12
|
+
*
|
|
13
|
+
* Platform limitation:
|
|
14
|
+
* The "ui_policy" reference field on sys_ui_policy_action cannot be set via
|
|
15
|
+
* the REST Table API (POST/PUT/PATCH all silently ignore it). This is a known
|
|
16
|
+
* ServiceNow platform restriction for parent-child reference fields.
|
|
17
|
+
* Workaround: after Table API creation, a direct XML POST is attempted to set
|
|
18
|
+
* the ui_policy reference. If the XML POST also fails, the action is created
|
|
19
|
+
* without the reference — it can be linked manually in the UI.
|
|
7
20
|
*/
|
|
8
21
|
|
|
9
|
-
import { MCPToolDefinition, ServiceNowContext, ToolResult } from "../../shared/types.js"
|
|
22
|
+
import type { MCPToolDefinition, ServiceNowContext, ToolResult } from "../../shared/types.js"
|
|
10
23
|
import { getAuthenticatedClient } from "../../shared/auth.js"
|
|
11
24
|
import { createSuccessResult, createErrorResult } from "../../shared/error-handler.js"
|
|
12
25
|
|
|
@@ -15,7 +28,7 @@ export const toolDefinition: MCPToolDefinition = {
|
|
|
15
28
|
description:
|
|
16
29
|
"Create a UI policy action to control field behavior (visible/mandatory/readonly) when a UI policy condition is met. Requires the parent UI policy sys_id and the target table name.",
|
|
17
30
|
category: "development",
|
|
18
|
-
subcategory: "
|
|
31
|
+
subcategory: "ui-policies",
|
|
19
32
|
use_cases: ["ui-policy-actions", "form-control", "ui-automation"],
|
|
20
33
|
complexity: "intermediate",
|
|
21
34
|
frequency: "medium",
|
|
@@ -31,7 +44,8 @@ export const toolDefinition: MCPToolDefinition = {
|
|
|
31
44
|
},
|
|
32
45
|
table: {
|
|
33
46
|
type: "string",
|
|
34
|
-
description:
|
|
47
|
+
description:
|
|
48
|
+
"Table name the UI policy applies to (e.g. 'incident', 'change_request'). Must match the table on the parent UI policy.",
|
|
35
49
|
},
|
|
36
50
|
field: {
|
|
37
51
|
type: "string",
|
|
@@ -39,15 +53,17 @@ export const toolDefinition: MCPToolDefinition = {
|
|
|
39
53
|
},
|
|
40
54
|
visible: {
|
|
41
55
|
type: "boolean",
|
|
42
|
-
description: "Set field visibility. true = visible, false = hidden. Omit to leave unchanged.",
|
|
56
|
+
description: "Set field visibility. true = visible, false = hidden. Omit to leave unchanged ('ignore').",
|
|
43
57
|
},
|
|
44
58
|
mandatory: {
|
|
45
59
|
type: "boolean",
|
|
46
|
-
description:
|
|
60
|
+
description:
|
|
61
|
+
"Set field mandatory state. true = required, false = optional. Omit to leave unchanged ('ignore').",
|
|
47
62
|
},
|
|
48
63
|
readonly: {
|
|
49
64
|
type: "boolean",
|
|
50
|
-
description:
|
|
65
|
+
description:
|
|
66
|
+
"Set field read-only state. true = read-only, false = editable. Omit to leave unchanged ('ignore').",
|
|
51
67
|
},
|
|
52
68
|
cleared: {
|
|
53
69
|
type: "boolean",
|
|
@@ -58,50 +74,89 @@ export const toolDefinition: MCPToolDefinition = {
|
|
|
58
74
|
},
|
|
59
75
|
}
|
|
60
76
|
|
|
61
|
-
|
|
62
|
-
|
|
77
|
+
function toActionValue(val: boolean | undefined): string {
|
|
78
|
+
if (val === undefined) return "ignore"
|
|
79
|
+
return val ? "true" : "false"
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export async function execute(args: Record<string, unknown>, context: ServiceNowContext): Promise<ToolResult> {
|
|
83
|
+
const uid = args.ui_policy_sys_id as string
|
|
84
|
+
const table = args.table as string
|
|
85
|
+
const field = args.field as string
|
|
86
|
+
const visible = args.visible as boolean | undefined
|
|
87
|
+
const mandatory = args.mandatory as boolean | undefined
|
|
88
|
+
const readonly = args.readonly as boolean | undefined
|
|
89
|
+
const cleared = args.cleared as boolean | undefined
|
|
90
|
+
|
|
63
91
|
try {
|
|
64
92
|
const client = await getAuthenticatedClient(context)
|
|
65
93
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
"/api/now/table/sys_ui_policy/" + ui_policy_sys_id + "?sysparm_fields=sys_id,table,short_description",
|
|
94
|
+
const policyRes = await client.get(
|
|
95
|
+
"/api/now/table/sys_ui_policy/" + uid + "?sysparm_fields=sys_id,table,short_description",
|
|
69
96
|
)
|
|
70
|
-
const policy =
|
|
97
|
+
const policy = policyRes.data.result
|
|
71
98
|
if (!policy || !policy.sys_id) {
|
|
72
|
-
return createErrorResult("UI Policy not found with sys_id: " +
|
|
99
|
+
return createErrorResult("UI Policy not found with sys_id: " + uid)
|
|
73
100
|
}
|
|
74
101
|
|
|
75
|
-
const
|
|
76
|
-
ui_policy:
|
|
102
|
+
const payload: Record<string, string | boolean> = {
|
|
103
|
+
ui_policy: uid,
|
|
77
104
|
table: table,
|
|
78
105
|
field: field,
|
|
79
|
-
visible: visible
|
|
80
|
-
mandatory: mandatory
|
|
81
|
-
|
|
82
|
-
cleared: cleared
|
|
106
|
+
visible: toActionValue(visible),
|
|
107
|
+
mandatory: toActionValue(mandatory),
|
|
108
|
+
disabled: toActionValue(readonly),
|
|
109
|
+
cleared: cleared === true,
|
|
83
110
|
}
|
|
84
111
|
|
|
85
|
-
const response = await client.post("/api/now/table/sys_ui_policy_action",
|
|
112
|
+
const response = await client.post("/api/now/table/sys_ui_policy_action", payload)
|
|
86
113
|
const action = response.data.result
|
|
114
|
+
const actionSysId = action.sys_id?.value || action.sys_id
|
|
115
|
+
|
|
116
|
+
const linked = await (async () => {
|
|
117
|
+
try {
|
|
118
|
+
const xmlBody =
|
|
119
|
+
"<record>" + "<sys_id>" + actionSysId + "</sys_id>" + "<ui_policy>" + uid + "</ui_policy>" + "</record>"
|
|
120
|
+
await client.post("/sys_ui_policy_action.do?XML&sys_id=" + actionSysId, xmlBody, {
|
|
121
|
+
headers: { "Content-Type": "application/xml" },
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
const verify = await client.get(
|
|
125
|
+
"/api/now/table/sys_ui_policy_action/" + actionSysId + "?sysparm_fields=ui_policy",
|
|
126
|
+
)
|
|
127
|
+
const ref = verify.data.result?.ui_policy
|
|
128
|
+
const val = typeof ref === "object" && ref !== null ? ref.value : ref
|
|
129
|
+
return !!val && val !== ""
|
|
130
|
+
} catch (_e) {
|
|
131
|
+
return false
|
|
132
|
+
}
|
|
133
|
+
})()
|
|
134
|
+
|
|
135
|
+
const refVal = action.ui_policy
|
|
136
|
+
const resolvedRef = typeof refVal === "object" && refVal !== null ? refVal.value : refVal
|
|
87
137
|
|
|
88
138
|
return createSuccessResult({
|
|
89
139
|
created: true,
|
|
90
140
|
action: {
|
|
91
|
-
sys_id:
|
|
92
|
-
ui_policy:
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
141
|
+
sys_id: actionSysId,
|
|
142
|
+
ui_policy: linked ? uid : resolvedRef || "",
|
|
143
|
+
ui_policy_linked: linked,
|
|
144
|
+
table: action.table?.value || action.table,
|
|
145
|
+
field: action.field?.value || action.field,
|
|
146
|
+
visible: action.visible?.value || action.visible,
|
|
147
|
+
mandatory: action.mandatory?.value || action.mandatory,
|
|
148
|
+
disabled: action.disabled?.value || action.disabled,
|
|
149
|
+
cleared: action.cleared?.value || action.cleared,
|
|
99
150
|
},
|
|
151
|
+
warning: linked
|
|
152
|
+
? undefined
|
|
153
|
+
: "The ui_policy reference field could not be set via the REST API (ServiceNow platform limitation). The action was created but is not linked to the parent UI policy. Link it manually in the ServiceNow UI.",
|
|
100
154
|
})
|
|
101
|
-
} catch (error:
|
|
102
|
-
|
|
155
|
+
} catch (error: unknown) {
|
|
156
|
+
const msg = error instanceof Error ? error.message : String(error)
|
|
157
|
+
return createErrorResult(msg)
|
|
103
158
|
}
|
|
104
159
|
}
|
|
105
160
|
|
|
106
|
-
export const version = "1.
|
|
161
|
+
export const version = "1.1.0"
|
|
107
162
|
export const author = "Snow-Flow SDK Migration"
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements MCP prompts protocol for reusable prompt templates and workflows
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { mcpDebug } from "./mcp-debug.js"
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Prompt argument definition
|
|
@@ -85,13 +85,13 @@ export type PromptHandler = (args: Record<string, string>) => Promise<MCPPromptR
|
|
|
85
85
|
* Manages prompt templates, registration, and execution
|
|
86
86
|
*/
|
|
87
87
|
export class MCPPromptManager {
|
|
88
|
-
private
|
|
88
|
+
private prefix: string
|
|
89
89
|
private promptRegistry: Map<string, MCPPrompt> = new Map()
|
|
90
90
|
private promptHandlers: Map<string, PromptHandler> = new Map()
|
|
91
91
|
private categories: PromptCategory[] = []
|
|
92
92
|
|
|
93
93
|
constructor(serverName: string = "mcp-server") {
|
|
94
|
-
this.
|
|
94
|
+
this.prefix = `[PromptManager:${serverName}]`
|
|
95
95
|
this.initializeDefaultPrompts()
|
|
96
96
|
}
|
|
97
97
|
|
|
@@ -109,7 +109,7 @@ export class MCPPromptManager {
|
|
|
109
109
|
registerPrompt(prompt: MCPPrompt, handler: PromptHandler): void {
|
|
110
110
|
this.promptRegistry.set(prompt.name, prompt)
|
|
111
111
|
this.promptHandlers.set(prompt.name, handler)
|
|
112
|
-
|
|
112
|
+
mcpDebug(`Registered prompt: ${prompt.name}`)
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
/**
|
|
@@ -119,7 +119,7 @@ export class MCPPromptManager {
|
|
|
119
119
|
const deleted = this.promptRegistry.delete(name)
|
|
120
120
|
this.promptHandlers.delete(name)
|
|
121
121
|
if (deleted) {
|
|
122
|
-
|
|
122
|
+
mcpDebug(`Unregistered prompt: ${name}`)
|
|
123
123
|
}
|
|
124
124
|
return deleted
|
|
125
125
|
}
|
|
@@ -161,7 +161,7 @@ export class MCPPromptManager {
|
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
|
|
164
|
+
mcpDebug(`Executing prompt: ${name}`, { args })
|
|
165
165
|
return await handler(args)
|
|
166
166
|
}
|
|
167
167
|
|
|
@@ -218,6 +218,6 @@ export class MCPPromptManager {
|
|
|
218
218
|
this.promptRegistry.clear()
|
|
219
219
|
this.promptHandlers.clear()
|
|
220
220
|
this.categories = []
|
|
221
|
-
|
|
221
|
+
mcpDebug("All prompts cleared")
|
|
222
222
|
}
|
|
223
223
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"lib": ["ESNext"],
|
|
5
|
+
"target": "ESNext",
|
|
6
|
+
"module": "Preserve",
|
|
7
|
+
"moduleDetection": "force",
|
|
8
|
+
"moduleResolution": "bundler",
|
|
9
|
+
"allowImportingTsExtensions": true,
|
|
10
|
+
"noEmit": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"types": ["bun-types"],
|
|
13
|
+
"noUncheckedIndexedAccess": false,
|
|
14
|
+
"customConditions": ["browser"],
|
|
15
|
+
"paths": {
|
|
16
|
+
"@/*": ["./src/*"]
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"include": ["src/servicenow/**/*"]
|
|
20
|
+
}
|