snow-flow 3.4.19 → 3.4.20
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.
|
@@ -870,7 +870,7 @@ class ServiceNowOperationsMCP {
|
|
|
870
870
|
query?.toLowerCase().includes('onboard') ||
|
|
871
871
|
(fields && fields.length <= 2); // Minimal fields = analytics
|
|
872
872
|
if (isAnalyticsContext) {
|
|
873
|
-
logger.info(`📊 Analytics context detected - NO LIMIT applied for complete analysis`);
|
|
873
|
+
this.logger.info(`📊 Analytics context detected - NO LIMIT applied for complete analysis`);
|
|
874
874
|
return undefined; // No limit - get ALL records
|
|
875
875
|
}
|
|
876
876
|
// 🤖 ML Training context
|
|
@@ -878,21 +878,21 @@ class ServiceNowOperationsMCP {
|
|
|
878
878
|
query?.toLowerCase().includes('ml') ||
|
|
879
879
|
table?.toLowerCase().includes('train');
|
|
880
880
|
if (isMLContext) {
|
|
881
|
-
logger.info(`🧠 ML context detected - using ML-optimized limit: 5000`);
|
|
881
|
+
this.logger.info(`🧠 ML context detected - using ML-optimized limit: 5000`);
|
|
882
882
|
return 5000; // ML training needs substantial data
|
|
883
883
|
}
|
|
884
884
|
// 📈 Count-only queries - efficient
|
|
885
885
|
if (!includeContent) {
|
|
886
|
-
logger.info(`📈 Count-only query - can handle large datasets efficiently`);
|
|
886
|
+
this.logger.info(`📈 Count-only query - can handle large datasets efficiently`);
|
|
887
887
|
return 10000; // Count queries are very memory-efficient
|
|
888
888
|
}
|
|
889
889
|
// 🖥️ Display context - limited data needed
|
|
890
890
|
if (includeContent && fields && fields.length > 5) {
|
|
891
|
-
logger.info(`🖥️ Display context detected - limiting to viewable records`);
|
|
891
|
+
this.logger.info(`🖥️ Display context detected - limiting to viewable records`);
|
|
892
892
|
return 100; // Display queries need less data
|
|
893
893
|
}
|
|
894
894
|
// Default: moderate limit
|
|
895
|
-
logger.info(`⚠️ No specific context detected - using conservative limit. Consider specifying limit for your use case!`);
|
|
895
|
+
this.logger.info(`⚠️ No specific context detected - using conservative limit. Consider specifying limit for your use case!`);
|
|
896
896
|
return 500; // Conservative default
|
|
897
897
|
};
|
|
898
898
|
const { table, query = '', include_content = false, fields, include_display_values = false, group_by, order_by, offset = 0 // ✅ NEW: Support pagination!
|
|
@@ -910,9 +910,9 @@ class ServiceNowOperationsMCP {
|
|
|
910
910
|
query?.toLowerCase().includes('ml') ||
|
|
911
911
|
args.limit !== undefined && args.limit < 1000;
|
|
912
912
|
if (isMLTrainingContext && limit < 1000) {
|
|
913
|
-
logger.warn(`⚠️ ML Training detected with low limit (${limit}). Consider setting limit=5000+ for better training data!`);
|
|
913
|
+
this.logger.warn(`⚠️ ML Training detected with low limit (${limit}). Consider setting limit=5000+ for better training data!`);
|
|
914
914
|
}
|
|
915
|
-
logger.info(`Universal query on table '${table}' with: ${query} (limit: ${limit === undefined ? 'UNLIMITED' : limit}, offset: ${offset}, include_content: ${include_content})`);
|
|
915
|
+
this.logger.info(`Universal query on table '${table}' with: ${query} (limit: ${limit === undefined ? 'UNLIMITED' : limit}, offset: ${offset}, include_content: ${include_content})`);
|
|
916
916
|
try {
|
|
917
917
|
// Convert natural language to ServiceNow query if needed
|
|
918
918
|
const processedQuery = this.processNaturalLanguageQuery(query || '', table);
|
|
@@ -957,7 +957,7 @@ class ServiceNowOperationsMCP {
|
|
|
957
957
|
const exists = sampleRecord.hasOwnProperty(field) ||
|
|
958
958
|
sampleRecord.hasOwnProperty(`${field}_display_value`);
|
|
959
959
|
if (!exists) {
|
|
960
|
-
logger.warn(`⚠️ Field '${field}' not found in table '${table}'`);
|
|
960
|
+
this.logger.warn(`⚠️ Field '${field}' not found in table '${table}'`);
|
|
961
961
|
}
|
|
962
962
|
return exists;
|
|
963
963
|
});
|
|
@@ -1040,7 +1040,7 @@ class ServiceNowOperationsMCP {
|
|
|
1040
1040
|
}
|
|
1041
1041
|
catch (error) {
|
|
1042
1042
|
// ✅ IMPROVED: Better error messages
|
|
1043
|
-
logger.error(`Error querying ${table}:`, error);
|
|
1043
|
+
this.logger.error(`Error querying ${table}:`, error);
|
|
1044
1044
|
if (error.code === 'ECONNREFUSED') {
|
|
1045
1045
|
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Cannot connect to ServiceNow. Please check your instance URL and network connection.`);
|
|
1046
1046
|
}
|
|
@@ -1079,7 +1079,7 @@ class ServiceNowOperationsMCP {
|
|
|
1079
1079
|
async handleQueryIncidents(args) {
|
|
1080
1080
|
const { query, limit = 10, include__analysis = false, fields, include_content = false // 🎯 NEW: Explicit control over returning full incident data
|
|
1081
1081
|
} = args;
|
|
1082
|
-
logger.info(`Querying incidents with: ${query} (include_content: ${include_content})`);
|
|
1082
|
+
this.logger.info(`Querying incidents with: ${query} (include_content: ${include_content})`);
|
|
1083
1083
|
try {
|
|
1084
1084
|
// Convert natural language to ServiceNow query if needed
|
|
1085
1085
|
const processedQuery = this.processNaturalLanguageQuery(query, 'incident');
|
|
@@ -1137,13 +1137,13 @@ class ServiceNowOperationsMCP {
|
|
|
1137
1137
|
};
|
|
1138
1138
|
}
|
|
1139
1139
|
catch (error) {
|
|
1140
|
-
logger.error('Error querying incidents:', error);
|
|
1140
|
+
this.logger.error('Error querying incidents:', error);
|
|
1141
1141
|
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to query incidents: ${error}`);
|
|
1142
1142
|
}
|
|
1143
1143
|
}
|
|
1144
1144
|
async handleAnalyzeIncident(args) {
|
|
1145
1145
|
const { incident_id, include_similar = true, suggest_resolution = true } = args;
|
|
1146
|
-
logger.info(`Analyzing incident: ${incident_id}`);
|
|
1146
|
+
this.logger.info(`Analyzing incident: ${incident_id}`);
|
|
1147
1147
|
try {
|
|
1148
1148
|
// Get incident details
|
|
1149
1149
|
const incident = await this.getIncidentDetails(incident_id);
|
|
@@ -1162,13 +1162,13 @@ class ServiceNowOperationsMCP {
|
|
|
1162
1162
|
};
|
|
1163
1163
|
}
|
|
1164
1164
|
catch (error) {
|
|
1165
|
-
logger.error('Error analyzing incident:', error);
|
|
1165
|
+
this.logger.error('Error analyzing incident:', error);
|
|
1166
1166
|
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to analyze incident: ${error}`);
|
|
1167
1167
|
}
|
|
1168
1168
|
}
|
|
1169
1169
|
async handleAutoResolveIncident(args) {
|
|
1170
1170
|
const { incident_id, dry_run = true } = args;
|
|
1171
|
-
logger.info(`Auto-resolving incident: ${incident_id} (dry_run: ${dry_run})`);
|
|
1171
|
+
this.logger.info(`Auto-resolving incident: ${incident_id} (dry_run: ${dry_run})`);
|
|
1172
1172
|
try {
|
|
1173
1173
|
// Get incident details
|
|
1174
1174
|
const incident = await this.getIncidentDetails(incident_id);
|
|
@@ -1200,13 +1200,13 @@ class ServiceNowOperationsMCP {
|
|
|
1200
1200
|
};
|
|
1201
1201
|
}
|
|
1202
1202
|
catch (error) {
|
|
1203
|
-
logger.error('Error auto-resolving incident:', error);
|
|
1203
|
+
this.logger.error('Error auto-resolving incident:', error);
|
|
1204
1204
|
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to auto-resolve incident: ${error}`);
|
|
1205
1205
|
}
|
|
1206
1206
|
}
|
|
1207
1207
|
async handleQueryRequests(args) {
|
|
1208
1208
|
const { query, limit = 10, include_items = false } = args;
|
|
1209
|
-
logger.info(`Querying requests with: ${query}`);
|
|
1209
|
+
this.logger.info(`Querying requests with: ${query}`);
|
|
1210
1210
|
try {
|
|
1211
1211
|
const processedQuery = this.processNaturalLanguageQuery(query, 'request');
|
|
1212
1212
|
const requests = await this.client.searchRecords('sc_request', processedQuery, limit);
|
|
@@ -1229,13 +1229,13 @@ class ServiceNowOperationsMCP {
|
|
|
1229
1229
|
};
|
|
1230
1230
|
}
|
|
1231
1231
|
catch (error) {
|
|
1232
|
-
logger.error('Error querying requests:', error);
|
|
1232
|
+
this.logger.error('Error querying requests:', error);
|
|
1233
1233
|
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to query requests: ${error}`);
|
|
1234
1234
|
}
|
|
1235
1235
|
}
|
|
1236
1236
|
async handleQueryProblems(args) {
|
|
1237
1237
|
const { query, limit = 10, include_incidents = false } = args;
|
|
1238
|
-
logger.info(`Querying problems with: ${query}`);
|
|
1238
|
+
this.logger.info(`Querying problems with: ${query}`);
|
|
1239
1239
|
try {
|
|
1240
1240
|
const processedQuery = this.processNaturalLanguageQuery(query, 'problem');
|
|
1241
1241
|
const problems = await this.client.searchRecords('problem', processedQuery, limit);
|
|
@@ -1258,13 +1258,13 @@ class ServiceNowOperationsMCP {
|
|
|
1258
1258
|
};
|
|
1259
1259
|
}
|
|
1260
1260
|
catch (error) {
|
|
1261
|
-
logger.error('Error querying problems:', error);
|
|
1261
|
+
this.logger.error('Error querying problems:', error);
|
|
1262
1262
|
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to query problems: ${error}`);
|
|
1263
1263
|
}
|
|
1264
1264
|
}
|
|
1265
1265
|
async handleCMDBSearch(args) {
|
|
1266
1266
|
const { query, ci_type = 'any', limit = 10, include_relationships = false } = args;
|
|
1267
|
-
logger.info(`Searching CMDB with: ${query}, type: ${ci_type}`);
|
|
1267
|
+
this.logger.info(`Searching CMDB with: ${query}, type: ${ci_type}`);
|
|
1268
1268
|
try {
|
|
1269
1269
|
const ciTable = ci_type === 'any' ? 'cmdb_ci' : operationalTableMapping[ci_type] || 'cmdb_ci';
|
|
1270
1270
|
const processedQuery = this.processNaturalLanguageQuery(query, 'cmdb');
|
|
@@ -1289,13 +1289,13 @@ class ServiceNowOperationsMCP {
|
|
|
1289
1289
|
};
|
|
1290
1290
|
}
|
|
1291
1291
|
catch (error) {
|
|
1292
|
-
logger.error('Error searching CMDB:', error);
|
|
1292
|
+
this.logger.error('Error searching CMDB:', error);
|
|
1293
1293
|
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to search CMDB: ${error}`);
|
|
1294
1294
|
}
|
|
1295
1295
|
}
|
|
1296
1296
|
async handleUserLookup(args) {
|
|
1297
1297
|
const { identifier, include_roles = true, include_groups = true } = args;
|
|
1298
|
-
logger.info(`Looking up user: ${identifier}`);
|
|
1298
|
+
this.logger.info(`Looking up user: ${identifier}`);
|
|
1299
1299
|
try {
|
|
1300
1300
|
// Try different user lookup strategies
|
|
1301
1301
|
let userQuery = '';
|
|
@@ -1338,13 +1338,13 @@ class ServiceNowOperationsMCP {
|
|
|
1338
1338
|
};
|
|
1339
1339
|
}
|
|
1340
1340
|
catch (error) {
|
|
1341
|
-
logger.error('Error looking up user:', error);
|
|
1341
|
+
this.logger.error('Error looking up user:', error);
|
|
1342
1342
|
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to lookup user: ${error}`);
|
|
1343
1343
|
}
|
|
1344
1344
|
}
|
|
1345
1345
|
async handleOperationalMetrics(args) {
|
|
1346
1346
|
const { timeframe = 'week', metric_types = [] } = args;
|
|
1347
|
-
logger.info(`Getting operational metrics for timeframe: ${timeframe}`);
|
|
1347
|
+
this.logger.info(`Getting operational metrics for timeframe: ${timeframe}`);
|
|
1348
1348
|
try {
|
|
1349
1349
|
const metrics = await this.calculateOperationalMetrics(timeframe, metric_types);
|
|
1350
1350
|
return {
|
|
@@ -1357,13 +1357,13 @@ class ServiceNowOperationsMCP {
|
|
|
1357
1357
|
};
|
|
1358
1358
|
}
|
|
1359
1359
|
catch (error) {
|
|
1360
|
-
logger.error('Error getting operational metrics:', error);
|
|
1360
|
+
this.logger.error('Error getting operational metrics:', error);
|
|
1361
1361
|
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to get operational metrics: ${error}`);
|
|
1362
1362
|
}
|
|
1363
1363
|
}
|
|
1364
1364
|
async handlePatternAnalysis(args) {
|
|
1365
1365
|
const { analysis_type, timeframe = 'week' } = args;
|
|
1366
|
-
logger.info(`Performing pattern _analysis: ${analysis_type} for ${timeframe}`);
|
|
1366
|
+
this.logger.info(`Performing pattern _analysis: ${analysis_type} for ${timeframe}`);
|
|
1367
1367
|
try {
|
|
1368
1368
|
const patterns = await this.analyzePatterns(analysis_type, timeframe);
|
|
1369
1369
|
return {
|
|
@@ -1376,13 +1376,13 @@ class ServiceNowOperationsMCP {
|
|
|
1376
1376
|
};
|
|
1377
1377
|
}
|
|
1378
1378
|
catch (error) {
|
|
1379
|
-
logger.error('Error analyzing patterns:', error);
|
|
1379
|
+
this.logger.error('Error analyzing patterns:', error);
|
|
1380
1380
|
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to analyze patterns: ${error}`);
|
|
1381
1381
|
}
|
|
1382
1382
|
}
|
|
1383
1383
|
async handleKnowledgeSearch(args) {
|
|
1384
1384
|
const { query, match_incident, limit = 5 } = args;
|
|
1385
|
-
logger.info(`Searching knowledge base with: ${query}`);
|
|
1385
|
+
this.logger.info(`Searching knowledge base with: ${query}`);
|
|
1386
1386
|
try {
|
|
1387
1387
|
const processedQuery = this.processNaturalLanguageQuery(query, 'knowledge');
|
|
1388
1388
|
const articles = await this.client.searchRecords('kb_knowledge', processedQuery, limit);
|
|
@@ -1408,13 +1408,13 @@ class ServiceNowOperationsMCP {
|
|
|
1408
1408
|
};
|
|
1409
1409
|
}
|
|
1410
1410
|
catch (error) {
|
|
1411
|
-
logger.error('Error searching knowledge base:', error);
|
|
1411
|
+
this.logger.error('Error searching knowledge base:', error);
|
|
1412
1412
|
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to search knowledge base: ${error}`);
|
|
1413
1413
|
}
|
|
1414
1414
|
}
|
|
1415
1415
|
async handlePredictiveAnalysis(args) {
|
|
1416
1416
|
const { prediction_type, timeframe = 'week' } = args;
|
|
1417
|
-
logger.info(`Performing predictive _analysis: ${prediction_type} for ${timeframe}`);
|
|
1417
|
+
this.logger.info(`Performing predictive _analysis: ${prediction_type} for ${timeframe}`);
|
|
1418
1418
|
try {
|
|
1419
1419
|
const predictions = await this.performPredictiveAnalysis(prediction_type, timeframe);
|
|
1420
1420
|
return {
|
|
@@ -1427,7 +1427,7 @@ class ServiceNowOperationsMCP {
|
|
|
1427
1427
|
};
|
|
1428
1428
|
}
|
|
1429
1429
|
catch (error) {
|
|
1430
|
-
logger.error('Error performing predictive _analysis:', error);
|
|
1430
|
+
this.logger.error('Error performing predictive _analysis:', error);
|
|
1431
1431
|
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to perform predictive _analysis: ${error}`);
|
|
1432
1432
|
}
|
|
1433
1433
|
}
|
|
@@ -1437,7 +1437,7 @@ class ServiceNowOperationsMCP {
|
|
|
1437
1437
|
const lowerQuery = query.toLowerCase();
|
|
1438
1438
|
// If already a ServiceNow encoded query, return as-is
|
|
1439
1439
|
if (query.includes('=') || query.includes('!=') || query.includes('^') || query.includes('LIKE')) {
|
|
1440
|
-
logger.info(`Using raw ServiceNow query: ${query}`);
|
|
1440
|
+
this.logger.info(`Using raw ServiceNow query: ${query}`);
|
|
1441
1441
|
return query;
|
|
1442
1442
|
}
|
|
1443
1443
|
// Common ServiceNow query patterns
|
|
@@ -1610,7 +1610,7 @@ class ServiceNowOperationsMCP {
|
|
|
1610
1610
|
for (const action of actions) {
|
|
1611
1611
|
try {
|
|
1612
1612
|
// This would integrate with actual automation systems
|
|
1613
|
-
logger.info(`Executing action: ${action} for incident ${incident_id}`);
|
|
1613
|
+
this.logger.info(`Executing action: ${action} for incident ${incident_id}`);
|
|
1614
1614
|
executed.push(`✅ ${action}`);
|
|
1615
1615
|
}
|
|
1616
1616
|
catch (error) {
|
|
@@ -1651,7 +1651,7 @@ class ServiceNowOperationsMCP {
|
|
|
1651
1651
|
});
|
|
1652
1652
|
}
|
|
1653
1653
|
catch (error) {
|
|
1654
|
-
logger.error(`Error getting relationships for CI ${ci.sys_id}:`, error);
|
|
1654
|
+
this.logger.error(`Error getting relationships for CI ${ci.sys_id}:`, error);
|
|
1655
1655
|
}
|
|
1656
1656
|
}
|
|
1657
1657
|
return relationships;
|
|
@@ -1700,7 +1700,7 @@ class ServiceNowOperationsMCP {
|
|
|
1700
1700
|
.map(([category, count]) => `${category}: ${count}`);
|
|
1701
1701
|
}
|
|
1702
1702
|
catch (error) {
|
|
1703
|
-
logger.error('Error calculating operational metrics:', error);
|
|
1703
|
+
this.logger.error('Error calculating operational metrics:', error);
|
|
1704
1704
|
}
|
|
1705
1705
|
return metrics;
|
|
1706
1706
|
}
|
|
@@ -2109,7 +2109,7 @@ class ServiceNowOperationsMCP {
|
|
|
2109
2109
|
}
|
|
2110
2110
|
async handleCatalogItemManager(args) {
|
|
2111
2111
|
const { action, item_id, ...params } = args;
|
|
2112
|
-
logger.info(`Catalog item manager action: ${action}`, { item_id, params });
|
|
2112
|
+
this.logger.info(`Catalog item manager action: ${action}`, { item_id, params });
|
|
2113
2113
|
try {
|
|
2114
2114
|
switch (action) {
|
|
2115
2115
|
case 'create': {
|
|
@@ -2121,13 +2121,13 @@ class ServiceNowOperationsMCP {
|
|
|
2121
2121
|
const defaultCatalogResult = await this.client.searchRecords('sc_catalog', 'active=true^ORDERBYsys_created_on', 1);
|
|
2122
2122
|
if (defaultCatalogResult.success && defaultCatalogResult.data?.result?.length > 0) {
|
|
2123
2123
|
catalogId = defaultCatalogResult.data.result[0].sys_id;
|
|
2124
|
-
logger.info('Using default catalog:', {
|
|
2124
|
+
this.logger.info('Using default catalog:', {
|
|
2125
2125
|
catalogId,
|
|
2126
2126
|
catalogName: defaultCatalogResult.data.result[0].title
|
|
2127
2127
|
});
|
|
2128
2128
|
}
|
|
2129
2129
|
else {
|
|
2130
|
-
logger.warn('No catalogs found, catalog item may not be visible');
|
|
2130
|
+
this.logger.warn('No catalogs found, catalog item may not be visible');
|
|
2131
2131
|
}
|
|
2132
2132
|
}
|
|
2133
2133
|
if (!categoryId) {
|
|
@@ -2135,7 +2135,7 @@ class ServiceNowOperationsMCP {
|
|
|
2135
2135
|
const defaultCategoryResult = await this.client.searchRecords('sc_category', 'active=true^titleLIKEHardware^ORtitleLIKEGeneral^ORtitleLIKEIT^ORDERBYsys_created_on', 1);
|
|
2136
2136
|
if (defaultCategoryResult.success && defaultCategoryResult.data?.result?.length > 0) {
|
|
2137
2137
|
categoryId = defaultCategoryResult.data.result[0].sys_id;
|
|
2138
|
-
logger.info('Using default category:', {
|
|
2138
|
+
this.logger.info('Using default category:', {
|
|
2139
2139
|
categoryId,
|
|
2140
2140
|
categoryName: defaultCategoryResult.data.result[0].title
|
|
2141
2141
|
});
|
|
@@ -2323,7 +2323,7 @@ class ServiceNowOperationsMCP {
|
|
|
2323
2323
|
}
|
|
2324
2324
|
}
|
|
2325
2325
|
catch (error) {
|
|
2326
|
-
logger.error('Error in catalog item manager:', error);
|
|
2326
|
+
this.logger.error('Error in catalog item manager:', error);
|
|
2327
2327
|
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Catalog item manager error: ${error}`);
|
|
2328
2328
|
}
|
|
2329
2329
|
}
|
|
@@ -2358,7 +2358,7 @@ class ServiceNowOperationsMCP {
|
|
|
2358
2358
|
}
|
|
2359
2359
|
async handleCatalogItemSearch(args) {
|
|
2360
2360
|
const { query, include_inactive = false, fuzzy_match = true, category_filter, limit = 50, include_variables = false } = args;
|
|
2361
|
-
logger.info(`Searching catalog items for: ${query}`, { fuzzy_match, category_filter, limit });
|
|
2361
|
+
this.logger.info(`Searching catalog items for: ${query}`, { fuzzy_match, category_filter, limit });
|
|
2362
2362
|
try {
|
|
2363
2363
|
// Build search queries
|
|
2364
2364
|
const searchQueries = [];
|
|
@@ -2497,7 +2497,7 @@ class ServiceNowOperationsMCP {
|
|
|
2497
2497
|
};
|
|
2498
2498
|
}
|
|
2499
2499
|
catch (error) {
|
|
2500
|
-
logger.error('Error searching catalog items:', error);
|
|
2500
|
+
this.logger.error('Error searching catalog items:', error);
|
|
2501
2501
|
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Catalog search error: ${error}`);
|
|
2502
2502
|
}
|
|
2503
2503
|
}
|
|
@@ -2628,7 +2628,7 @@ class ServiceNowOperationsMCP {
|
|
|
2628
2628
|
}
|
|
2629
2629
|
async handleCleanupTestArtifacts(args) {
|
|
2630
2630
|
const { artifact_types = ['catalog_items', 'flows', 'users'], test_patterns = ['Test%', 'Mock%', 'Demo%', '%_test_%', '%test', '%mock'], max_age_hours = 1, dry_run = false, preserve_update_set_entries = true, update_set_filter } = args;
|
|
2631
|
-
logger.info('Starting test artifact cleanup', {
|
|
2631
|
+
this.logger.info('Starting test artifact cleanup', {
|
|
2632
2632
|
artifact_types,
|
|
2633
2633
|
test_patterns,
|
|
2634
2634
|
max_age_hours,
|
|
@@ -2737,7 +2737,7 @@ class ServiceNowOperationsMCP {
|
|
|
2737
2737
|
};
|
|
2738
2738
|
}
|
|
2739
2739
|
catch (error) {
|
|
2740
|
-
logger.error('Error during test artifact cleanup:', error);
|
|
2740
|
+
this.logger.error('Error during test artifact cleanup:', error);
|
|
2741
2741
|
return {
|
|
2742
2742
|
content: [{
|
|
2743
2743
|
type: 'text',
|
|
@@ -2868,7 +2868,7 @@ class ServiceNowOperationsMCP {
|
|
|
2868
2868
|
}
|
|
2869
2869
|
async handleCreateUserGroup(args) {
|
|
2870
2870
|
const { name, description, email, manager, parent, type, active = true } = args;
|
|
2871
|
-
logger.info(`Creating user group: ${name}`);
|
|
2871
|
+
this.logger.info(`Creating user group: ${name}`);
|
|
2872
2872
|
try {
|
|
2873
2873
|
// Check if group already exists
|
|
2874
2874
|
const existingGroup = await this.client.get('/api/now/table/sys_user_group', {
|
|
@@ -2901,7 +2901,7 @@ class ServiceNowOperationsMCP {
|
|
|
2901
2901
|
groupData.manager = managerUser.sys_id;
|
|
2902
2902
|
}
|
|
2903
2903
|
else {
|
|
2904
|
-
logger.warn(`Manager "${manager}" not found, creating group without manager`);
|
|
2904
|
+
this.logger.warn(`Manager "${manager}" not found, creating group without manager`);
|
|
2905
2905
|
}
|
|
2906
2906
|
}
|
|
2907
2907
|
// Handle parent group lookup
|
|
@@ -2911,7 +2911,7 @@ class ServiceNowOperationsMCP {
|
|
|
2911
2911
|
groupData.parent = parentGroup.sys_id;
|
|
2912
2912
|
}
|
|
2913
2913
|
else {
|
|
2914
|
-
logger.warn(`Parent group "${parent}" not found, creating group without parent`);
|
|
2914
|
+
this.logger.warn(`Parent group "${parent}" not found, creating group without parent`);
|
|
2915
2915
|
}
|
|
2916
2916
|
}
|
|
2917
2917
|
// Create the group
|
|
@@ -2940,7 +2940,7 @@ class ServiceNowOperationsMCP {
|
|
|
2940
2940
|
}
|
|
2941
2941
|
async handleCreateUser(args) {
|
|
2942
2942
|
const { user_name, first_name, last_name, email, department, manager, phone, title, location, active = true, password } = args;
|
|
2943
|
-
logger.info(`Creating user: ${user_name}`);
|
|
2943
|
+
this.logger.info(`Creating user: ${user_name}`);
|
|
2944
2944
|
try {
|
|
2945
2945
|
// Check if user already exists
|
|
2946
2946
|
const existingUser = await this.client.get('/api/now/table/sys_user', {
|
|
@@ -2976,7 +2976,7 @@ class ServiceNowOperationsMCP {
|
|
|
2976
2976
|
userData.manager = managerUser.sys_id;
|
|
2977
2977
|
}
|
|
2978
2978
|
else {
|
|
2979
|
-
logger.warn(`Manager "${manager}" not found, creating user without manager`);
|
|
2979
|
+
this.logger.warn(`Manager "${manager}" not found, creating user without manager`);
|
|
2980
2980
|
}
|
|
2981
2981
|
}
|
|
2982
2982
|
// Handle department lookup
|
|
@@ -2986,7 +2986,7 @@ class ServiceNowOperationsMCP {
|
|
|
2986
2986
|
userData.department = dept.sys_id;
|
|
2987
2987
|
}
|
|
2988
2988
|
else {
|
|
2989
|
-
logger.warn(`Department "${department}" not found, creating user without department`);
|
|
2989
|
+
this.logger.warn(`Department "${department}" not found, creating user without department`);
|
|
2990
2990
|
}
|
|
2991
2991
|
}
|
|
2992
2992
|
// Handle location lookup
|
|
@@ -2996,7 +2996,7 @@ class ServiceNowOperationsMCP {
|
|
|
2996
2996
|
userData.location = loc.sys_id;
|
|
2997
2997
|
}
|
|
2998
2998
|
else {
|
|
2999
|
-
logger.warn(`Location "${location}" not found, creating user without location`);
|
|
2999
|
+
this.logger.warn(`Location "${location}" not found, creating user without location`);
|
|
3000
3000
|
}
|
|
3001
3001
|
}
|
|
3002
3002
|
// Create the user
|
|
@@ -3025,7 +3025,7 @@ class ServiceNowOperationsMCP {
|
|
|
3025
3025
|
}
|
|
3026
3026
|
async handleAssignUserToGroup(args) {
|
|
3027
3027
|
const { user, group } = args;
|
|
3028
|
-
logger.info(`Assigning user ${user} to group ${group}`);
|
|
3028
|
+
this.logger.info(`Assigning user ${user} to group ${group}`);
|
|
3029
3029
|
try {
|
|
3030
3030
|
// Find the user
|
|
3031
3031
|
const userRecord = await this.findUserBySysIdOrUsername(user);
|
|
@@ -3088,7 +3088,7 @@ class ServiceNowOperationsMCP {
|
|
|
3088
3088
|
}
|
|
3089
3089
|
async handleRemoveUserFromGroup(args) {
|
|
3090
3090
|
const { user, group } = args;
|
|
3091
|
-
logger.info(`Removing user ${user} from group ${group}`);
|
|
3091
|
+
this.logger.info(`Removing user ${user} from group ${group}`);
|
|
3092
3092
|
try {
|
|
3093
3093
|
// Find the user
|
|
3094
3094
|
const userRecord = await this.findUserBySysIdOrUsername(user);
|
|
@@ -3143,7 +3143,7 @@ class ServiceNowOperationsMCP {
|
|
|
3143
3143
|
}
|
|
3144
3144
|
async handleListGroupMembers(args) {
|
|
3145
3145
|
const { group, active_only = true } = args;
|
|
3146
|
-
logger.info(`Listing members of group: ${group}`);
|
|
3146
|
+
this.logger.info(`Listing members of group: ${group}`);
|
|
3147
3147
|
try {
|
|
3148
3148
|
// Find the group
|
|
3149
3149
|
const groupRecord = await this.findGroupBySysIdOrName(group);
|
|
@@ -3180,7 +3180,7 @@ class ServiceNowOperationsMCP {
|
|
|
3180
3180
|
const u = member.user;
|
|
3181
3181
|
// Defensive programming: check if user object exists and has required fields
|
|
3182
3182
|
if (!u || !u.user_name) {
|
|
3183
|
-
logger.warn(`Group member ${index + 1} has invalid user data:`, member);
|
|
3183
|
+
this.logger.warn(`Group member ${index + 1} has invalid user data:`, member);
|
|
3184
3184
|
response += `${index + 1}. **Invalid User Data** - ${member.sys_id || 'Unknown ID'}\n\n`;
|
|
3185
3185
|
return;
|
|
3186
3186
|
}
|
|
@@ -3276,7 +3276,7 @@ class ServiceNowOperationsMCP {
|
|
|
3276
3276
|
async run() {
|
|
3277
3277
|
const transport = new stdio_js_1.StdioServerTransport();
|
|
3278
3278
|
await this.server.connect(transport);
|
|
3279
|
-
logger.info('ServiceNow Operations MCP Server started');
|
|
3279
|
+
this.logger.info('ServiceNow Operations MCP Server started');
|
|
3280
3280
|
}
|
|
3281
3281
|
}
|
|
3282
3282
|
exports.ServiceNowOperationsMCP = ServiceNowOperationsMCP;
|
|
@@ -29,7 +29,7 @@ class ServiceNowSystemPropertiesMCP {
|
|
|
29
29
|
},
|
|
30
30
|
});
|
|
31
31
|
this.client = new servicenow_client_js_1.ServiceNowClient();
|
|
32
|
-
this.oauth = new snow_oauth_js_1.
|
|
32
|
+
this.oauth = new snow_oauth_js_1.ServiceNowOAuth();
|
|
33
33
|
this.logger = new mcp_logger_js_1.MCPLogger('ServiceNowSystemProperties');
|
|
34
34
|
this.setupHandlers();
|
|
35
35
|
this.setupTools();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "snow-flow",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.20",
|
|
4
4
|
"description": "ServiceNow development framework with MCP server integration. Executes background scripts using ES5 JavaScript only (ServiceNow Rhino engine requirement). Provides 17 MCP servers for complete ServiceNow operations including widget deployment with coherence validation, table operations, script execution, machine learning, advanced features, and comprehensive platform management.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "commonjs",
|