snow-flow 3.4.13 → 3.4.14

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.
@@ -18,7 +18,7 @@ const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
18
18
  const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
19
19
  const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
20
20
  const servicenow_client_js_1 = require("../utils/servicenow-client.js");
21
- const logger_js_1 = require("../utils/logger.js");
21
+ const mcp_logger_js_1 = require("./shared/mcp-logger.js");
22
22
  // Operational table mappings for ServiceNow
23
23
  const operationalTableMapping = {
24
24
  // ITIL Core Processes
@@ -122,6 +122,7 @@ class ServiceNowOperationsMCP {
122
122
  },
123
123
  });
124
124
  this.client = new servicenow_client_js_1.ServiceNowClient();
125
+ this.logger = new mcp_logger_js_1.MCPLogger('ServiceNowOperationsMCP');
125
126
  this.setupToolHandlers();
126
127
  }
127
128
  setupToolHandlers() {
@@ -777,53 +778,79 @@ class ServiceNowOperationsMCP {
777
778
  this.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
778
779
  const { name, arguments: args } = request.params;
779
780
  try {
781
+ // Start operation with token tracking
782
+ this.logger.operationStart(name, args);
783
+ let result;
780
784
  switch (name) {
781
785
  case 'snow_query_table':
782
- return await this.handleUniversalQuery(args);
786
+ result = await this.handleUniversalQuery(args);
787
+ break;
783
788
  case 'snow_query_incidents':
784
- return await this.handleQueryIncidents(args);
789
+ result = await this.handleQueryIncidents(args);
790
+ break;
785
791
  case 'snow_analyze_incident':
786
- return await this.handleAnalyzeIncident(args);
792
+ result = await this.handleAnalyzeIncident(args);
793
+ break;
787
794
  case 'snow_auto_resolve_incident':
788
- return await this.handleAutoResolveIncident(args);
795
+ result = await this.handleAutoResolveIncident(args);
796
+ break;
789
797
  case 'snow_query_requests':
790
- return await this.handleQueryRequests(args);
798
+ result = await this.handleQueryRequests(args);
799
+ break;
791
800
  case 'snow_query_problems':
792
- return await this.handleQueryProblems(args);
801
+ result = await this.handleQueryProblems(args);
802
+ break;
793
803
  case 'snow_cmdb_search':
794
- return await this.handleCMDBSearch(args);
804
+ result = await this.handleCMDBSearch(args);
805
+ break;
795
806
  case 'snow_user_lookup':
796
- return await this.handleUserLookup(args);
807
+ result = await this.handleUserLookup(args);
808
+ break;
797
809
  case 'snow_operational_metrics':
798
- return await this.handleOperationalMetrics(args);
810
+ result = await this.handleOperationalMetrics(args);
811
+ break;
799
812
  case 'snow_pattern__analysis':
800
- return await this.handlePatternAnalysis(args);
813
+ result = await this.handlePatternAnalysis(args);
814
+ break;
801
815
  case 'snow_knowledge_search':
802
- return await this.handleKnowledgeSearch(args);
816
+ result = await this.handleKnowledgeSearch(args);
817
+ break;
803
818
  case 'snow_predictive__analysis':
804
- return await this.handlePredictiveAnalysis(args);
819
+ result = await this.handlePredictiveAnalysis(args);
820
+ break;
805
821
  case 'snow_catalog_item_manager':
806
- return await this.handleCatalogItemManager(args);
822
+ result = await this.handleCatalogItemManager(args);
823
+ break;
807
824
  case 'snow_catalog_item_search':
808
- return await this.handleCatalogItemSearch(args);
825
+ result = await this.handleCatalogItemSearch(args);
826
+ break;
809
827
  case 'snow_cleanup_test_artifacts':
810
- return await this.handleCleanupTestArtifacts(args);
828
+ result = await this.handleCleanupTestArtifacts(args);
829
+ break;
811
830
  case 'snow_create_user_group':
812
- return await this.handleCreateUserGroup(args);
831
+ result = await this.handleCreateUserGroup(args);
832
+ break;
813
833
  case 'snow_create_user':
814
- return await this.handleCreateUser(args);
834
+ result = await this.handleCreateUser(args);
835
+ break;
815
836
  case 'snow_assign_user_to_group':
816
- return await this.handleAssignUserToGroup(args);
837
+ result = await this.handleAssignUserToGroup(args);
838
+ break;
817
839
  case 'snow_remove_user_from_group':
818
- return await this.handleRemoveUserFromGroup(args);
840
+ result = await this.handleRemoveUserFromGroup(args);
841
+ break;
819
842
  case 'snow_list_group_members':
820
- return await this.handleListGroupMembers(args);
843
+ result = await this.handleListGroupMembers(args);
844
+ break;
821
845
  default:
822
846
  throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Tool ${name} not found`);
823
847
  }
848
+ // Complete operation with token tracking
849
+ this.logger.operationComplete(name, result);
850
+ return result;
824
851
  }
825
852
  catch (error) {
826
- logger_js_1.logger.error(`Error executing tool ${name}:`, error);
853
+ this.logger.error(`Error executing tool ${name}:`, error);
827
854
  throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to execute ${name}: ${error}`);
828
855
  }
829
856
  });
@@ -843,7 +870,7 @@ class ServiceNowOperationsMCP {
843
870
  query?.toLowerCase().includes('onboard') ||
844
871
  (fields && fields.length <= 2); // Minimal fields = analytics
845
872
  if (isAnalyticsContext) {
846
- logger_js_1.logger.info(`📊 Analytics context detected - NO LIMIT applied for complete analysis`);
873
+ logger.info(`📊 Analytics context detected - NO LIMIT applied for complete analysis`);
847
874
  return undefined; // No limit - get ALL records
848
875
  }
849
876
  // 🤖 ML Training context
@@ -851,21 +878,21 @@ class ServiceNowOperationsMCP {
851
878
  query?.toLowerCase().includes('ml') ||
852
879
  table?.toLowerCase().includes('train');
853
880
  if (isMLContext) {
854
- logger_js_1.logger.info(`🧠 ML context detected - using ML-optimized limit: 5000`);
881
+ logger.info(`🧠 ML context detected - using ML-optimized limit: 5000`);
855
882
  return 5000; // ML training needs substantial data
856
883
  }
857
884
  // 📈 Count-only queries - efficient
858
885
  if (!includeContent) {
859
- logger_js_1.logger.info(`📈 Count-only query - can handle large datasets efficiently`);
886
+ logger.info(`📈 Count-only query - can handle large datasets efficiently`);
860
887
  return 10000; // Count queries are very memory-efficient
861
888
  }
862
889
  // 🖥️ Display context - limited data needed
863
890
  if (includeContent && fields && fields.length > 5) {
864
- logger_js_1.logger.info(`🖥️ Display context detected - limiting to viewable records`);
891
+ logger.info(`🖥️ Display context detected - limiting to viewable records`);
865
892
  return 100; // Display queries need less data
866
893
  }
867
894
  // Default: moderate limit
868
- logger_js_1.logger.info(`⚠️ No specific context detected - using conservative limit. Consider specifying limit for your use case!`);
895
+ logger.info(`⚠️ No specific context detected - using conservative limit. Consider specifying limit for your use case!`);
869
896
  return 500; // Conservative default
870
897
  };
871
898
  const { table, query = '', include_content = false, fields, include_display_values = false, group_by, order_by, offset = 0 // ✅ NEW: Support pagination!
@@ -883,9 +910,9 @@ class ServiceNowOperationsMCP {
883
910
  query?.toLowerCase().includes('ml') ||
884
911
  args.limit !== undefined && args.limit < 1000;
885
912
  if (isMLTrainingContext && limit < 1000) {
886
- logger_js_1.logger.warn(`⚠️ ML Training detected with low limit (${limit}). Consider setting limit=5000+ for better training data!`);
913
+ logger.warn(`⚠️ ML Training detected with low limit (${limit}). Consider setting limit=5000+ for better training data!`);
887
914
  }
888
- logger_js_1.logger.info(`Universal query on table '${table}' with: ${query} (limit: ${limit === undefined ? 'UNLIMITED' : limit}, offset: ${offset}, include_content: ${include_content})`);
915
+ logger.info(`Universal query on table '${table}' with: ${query} (limit: ${limit === undefined ? 'UNLIMITED' : limit}, offset: ${offset}, include_content: ${include_content})`);
889
916
  try {
890
917
  // Convert natural language to ServiceNow query if needed
891
918
  const processedQuery = this.processNaturalLanguageQuery(query || '', table);
@@ -898,6 +925,7 @@ class ServiceNowOperationsMCP {
898
925
  finalQuery += `^ORDERBY${orderDirection ? orderDirection : ''}${orderField}`;
899
926
  }
900
927
  // ✅ NEW: Use searchRecordsWithOffset when offset is provided
928
+ this.logger.trackAPICall('SEARCH', table, effectiveLimit);
901
929
  const records = offset > 0
902
930
  ? await this.client.searchRecordsWithOffset(table, finalQuery, effectiveLimit, offset)
903
931
  : await this.client.searchRecords(table, finalQuery, effectiveLimit);
@@ -929,7 +957,7 @@ class ServiceNowOperationsMCP {
929
957
  const exists = sampleRecord.hasOwnProperty(field) ||
930
958
  sampleRecord.hasOwnProperty(`${field}_display_value`);
931
959
  if (!exists) {
932
- logger_js_1.logger.warn(`⚠️ Field '${field}' not found in table '${table}'`);
960
+ logger.warn(`⚠️ Field '${field}' not found in table '${table}'`);
933
961
  }
934
962
  return exists;
935
963
  });
@@ -1012,7 +1040,7 @@ class ServiceNowOperationsMCP {
1012
1040
  }
1013
1041
  catch (error) {
1014
1042
  // ✅ IMPROVED: Better error messages
1015
- logger_js_1.logger.error(`Error querying ${table}:`, error);
1043
+ logger.error(`Error querying ${table}:`, error);
1016
1044
  if (error.code === 'ECONNREFUSED') {
1017
1045
  throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Cannot connect to ServiceNow. Please check your instance URL and network connection.`);
1018
1046
  }
@@ -1051,11 +1079,12 @@ class ServiceNowOperationsMCP {
1051
1079
  async handleQueryIncidents(args) {
1052
1080
  const { query, limit = 10, include__analysis = false, fields, include_content = false // 🎯 NEW: Explicit control over returning full incident data
1053
1081
  } = args;
1054
- logger_js_1.logger.info(`Querying incidents with: ${query} (include_content: ${include_content})`);
1082
+ logger.info(`Querying incidents with: ${query} (include_content: ${include_content})`);
1055
1083
  try {
1056
1084
  // Convert natural language to ServiceNow query if needed
1057
1085
  const processedQuery = this.processNaturalLanguageQuery(query, 'incident');
1058
1086
  // Query incidents
1087
+ this.logger.trackAPICall('SEARCH', 'incident', limit);
1059
1088
  const incidents = await this.client.searchRecords('incident', processedQuery, limit);
1060
1089
  let result = {
1061
1090
  total_results: incidents.success ? incidents.data.result.length : 0,
@@ -1108,13 +1137,13 @@ class ServiceNowOperationsMCP {
1108
1137
  };
1109
1138
  }
1110
1139
  catch (error) {
1111
- logger_js_1.logger.error('Error querying incidents:', error);
1140
+ logger.error('Error querying incidents:', error);
1112
1141
  throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to query incidents: ${error}`);
1113
1142
  }
1114
1143
  }
1115
1144
  async handleAnalyzeIncident(args) {
1116
1145
  const { incident_id, include_similar = true, suggest_resolution = true } = args;
1117
- logger_js_1.logger.info(`Analyzing incident: ${incident_id}`);
1146
+ logger.info(`Analyzing incident: ${incident_id}`);
1118
1147
  try {
1119
1148
  // Get incident details
1120
1149
  const incident = await this.getIncidentDetails(incident_id);
@@ -1133,13 +1162,13 @@ class ServiceNowOperationsMCP {
1133
1162
  };
1134
1163
  }
1135
1164
  catch (error) {
1136
- logger_js_1.logger.error('Error analyzing incident:', error);
1165
+ logger.error('Error analyzing incident:', error);
1137
1166
  throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to analyze incident: ${error}`);
1138
1167
  }
1139
1168
  }
1140
1169
  async handleAutoResolveIncident(args) {
1141
1170
  const { incident_id, dry_run = true } = args;
1142
- logger_js_1.logger.info(`Auto-resolving incident: ${incident_id} (dry_run: ${dry_run})`);
1171
+ logger.info(`Auto-resolving incident: ${incident_id} (dry_run: ${dry_run})`);
1143
1172
  try {
1144
1173
  // Get incident details
1145
1174
  const incident = await this.getIncidentDetails(incident_id);
@@ -1171,13 +1200,13 @@ class ServiceNowOperationsMCP {
1171
1200
  };
1172
1201
  }
1173
1202
  catch (error) {
1174
- logger_js_1.logger.error('Error auto-resolving incident:', error);
1203
+ logger.error('Error auto-resolving incident:', error);
1175
1204
  throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to auto-resolve incident: ${error}`);
1176
1205
  }
1177
1206
  }
1178
1207
  async handleQueryRequests(args) {
1179
1208
  const { query, limit = 10, include_items = false } = args;
1180
- logger_js_1.logger.info(`Querying requests with: ${query}`);
1209
+ logger.info(`Querying requests with: ${query}`);
1181
1210
  try {
1182
1211
  const processedQuery = this.processNaturalLanguageQuery(query, 'request');
1183
1212
  const requests = await this.client.searchRecords('sc_request', processedQuery, limit);
@@ -1200,13 +1229,13 @@ class ServiceNowOperationsMCP {
1200
1229
  };
1201
1230
  }
1202
1231
  catch (error) {
1203
- logger_js_1.logger.error('Error querying requests:', error);
1232
+ logger.error('Error querying requests:', error);
1204
1233
  throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to query requests: ${error}`);
1205
1234
  }
1206
1235
  }
1207
1236
  async handleQueryProblems(args) {
1208
1237
  const { query, limit = 10, include_incidents = false } = args;
1209
- logger_js_1.logger.info(`Querying problems with: ${query}`);
1238
+ logger.info(`Querying problems with: ${query}`);
1210
1239
  try {
1211
1240
  const processedQuery = this.processNaturalLanguageQuery(query, 'problem');
1212
1241
  const problems = await this.client.searchRecords('problem', processedQuery, limit);
@@ -1229,13 +1258,13 @@ class ServiceNowOperationsMCP {
1229
1258
  };
1230
1259
  }
1231
1260
  catch (error) {
1232
- logger_js_1.logger.error('Error querying problems:', error);
1261
+ logger.error('Error querying problems:', error);
1233
1262
  throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to query problems: ${error}`);
1234
1263
  }
1235
1264
  }
1236
1265
  async handleCMDBSearch(args) {
1237
1266
  const { query, ci_type = 'any', limit = 10, include_relationships = false } = args;
1238
- logger_js_1.logger.info(`Searching CMDB with: ${query}, type: ${ci_type}`);
1267
+ logger.info(`Searching CMDB with: ${query}, type: ${ci_type}`);
1239
1268
  try {
1240
1269
  const ciTable = ci_type === 'any' ? 'cmdb_ci' : operationalTableMapping[ci_type] || 'cmdb_ci';
1241
1270
  const processedQuery = this.processNaturalLanguageQuery(query, 'cmdb');
@@ -1260,13 +1289,13 @@ class ServiceNowOperationsMCP {
1260
1289
  };
1261
1290
  }
1262
1291
  catch (error) {
1263
- logger_js_1.logger.error('Error searching CMDB:', error);
1292
+ logger.error('Error searching CMDB:', error);
1264
1293
  throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to search CMDB: ${error}`);
1265
1294
  }
1266
1295
  }
1267
1296
  async handleUserLookup(args) {
1268
1297
  const { identifier, include_roles = true, include_groups = true } = args;
1269
- logger_js_1.logger.info(`Looking up user: ${identifier}`);
1298
+ logger.info(`Looking up user: ${identifier}`);
1270
1299
  try {
1271
1300
  // Try different user lookup strategies
1272
1301
  let userQuery = '';
@@ -1309,13 +1338,13 @@ class ServiceNowOperationsMCP {
1309
1338
  };
1310
1339
  }
1311
1340
  catch (error) {
1312
- logger_js_1.logger.error('Error looking up user:', error);
1341
+ logger.error('Error looking up user:', error);
1313
1342
  throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to lookup user: ${error}`);
1314
1343
  }
1315
1344
  }
1316
1345
  async handleOperationalMetrics(args) {
1317
1346
  const { timeframe = 'week', metric_types = [] } = args;
1318
- logger_js_1.logger.info(`Getting operational metrics for timeframe: ${timeframe}`);
1347
+ logger.info(`Getting operational metrics for timeframe: ${timeframe}`);
1319
1348
  try {
1320
1349
  const metrics = await this.calculateOperationalMetrics(timeframe, metric_types);
1321
1350
  return {
@@ -1328,13 +1357,13 @@ class ServiceNowOperationsMCP {
1328
1357
  };
1329
1358
  }
1330
1359
  catch (error) {
1331
- logger_js_1.logger.error('Error getting operational metrics:', error);
1360
+ logger.error('Error getting operational metrics:', error);
1332
1361
  throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to get operational metrics: ${error}`);
1333
1362
  }
1334
1363
  }
1335
1364
  async handlePatternAnalysis(args) {
1336
1365
  const { analysis_type, timeframe = 'week' } = args;
1337
- logger_js_1.logger.info(`Performing pattern _analysis: ${analysis_type} for ${timeframe}`);
1366
+ logger.info(`Performing pattern _analysis: ${analysis_type} for ${timeframe}`);
1338
1367
  try {
1339
1368
  const patterns = await this.analyzePatterns(analysis_type, timeframe);
1340
1369
  return {
@@ -1347,13 +1376,13 @@ class ServiceNowOperationsMCP {
1347
1376
  };
1348
1377
  }
1349
1378
  catch (error) {
1350
- logger_js_1.logger.error('Error analyzing patterns:', error);
1379
+ logger.error('Error analyzing patterns:', error);
1351
1380
  throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to analyze patterns: ${error}`);
1352
1381
  }
1353
1382
  }
1354
1383
  async handleKnowledgeSearch(args) {
1355
1384
  const { query, match_incident, limit = 5 } = args;
1356
- logger_js_1.logger.info(`Searching knowledge base with: ${query}`);
1385
+ logger.info(`Searching knowledge base with: ${query}`);
1357
1386
  try {
1358
1387
  const processedQuery = this.processNaturalLanguageQuery(query, 'knowledge');
1359
1388
  const articles = await this.client.searchRecords('kb_knowledge', processedQuery, limit);
@@ -1379,13 +1408,13 @@ class ServiceNowOperationsMCP {
1379
1408
  };
1380
1409
  }
1381
1410
  catch (error) {
1382
- logger_js_1.logger.error('Error searching knowledge base:', error);
1411
+ logger.error('Error searching knowledge base:', error);
1383
1412
  throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to search knowledge base: ${error}`);
1384
1413
  }
1385
1414
  }
1386
1415
  async handlePredictiveAnalysis(args) {
1387
1416
  const { prediction_type, timeframe = 'week' } = args;
1388
- logger_js_1.logger.info(`Performing predictive _analysis: ${prediction_type} for ${timeframe}`);
1417
+ logger.info(`Performing predictive _analysis: ${prediction_type} for ${timeframe}`);
1389
1418
  try {
1390
1419
  const predictions = await this.performPredictiveAnalysis(prediction_type, timeframe);
1391
1420
  return {
@@ -1398,7 +1427,7 @@ class ServiceNowOperationsMCP {
1398
1427
  };
1399
1428
  }
1400
1429
  catch (error) {
1401
- logger_js_1.logger.error('Error performing predictive _analysis:', error);
1430
+ logger.error('Error performing predictive _analysis:', error);
1402
1431
  throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to perform predictive _analysis: ${error}`);
1403
1432
  }
1404
1433
  }
@@ -1408,7 +1437,7 @@ class ServiceNowOperationsMCP {
1408
1437
  const lowerQuery = query.toLowerCase();
1409
1438
  // If already a ServiceNow encoded query, return as-is
1410
1439
  if (query.includes('=') || query.includes('!=') || query.includes('^') || query.includes('LIKE')) {
1411
- logger_js_1.logger.info(`Using raw ServiceNow query: ${query}`);
1440
+ logger.info(`Using raw ServiceNow query: ${query}`);
1412
1441
  return query;
1413
1442
  }
1414
1443
  // Common ServiceNow query patterns
@@ -1581,7 +1610,7 @@ class ServiceNowOperationsMCP {
1581
1610
  for (const action of actions) {
1582
1611
  try {
1583
1612
  // This would integrate with actual automation systems
1584
- logger_js_1.logger.info(`Executing action: ${action} for incident ${incident_id}`);
1613
+ logger.info(`Executing action: ${action} for incident ${incident_id}`);
1585
1614
  executed.push(`✅ ${action}`);
1586
1615
  }
1587
1616
  catch (error) {
@@ -1622,7 +1651,7 @@ class ServiceNowOperationsMCP {
1622
1651
  });
1623
1652
  }
1624
1653
  catch (error) {
1625
- logger_js_1.logger.error(`Error getting relationships for CI ${ci.sys_id}:`, error);
1654
+ logger.error(`Error getting relationships for CI ${ci.sys_id}:`, error);
1626
1655
  }
1627
1656
  }
1628
1657
  return relationships;
@@ -1671,7 +1700,7 @@ class ServiceNowOperationsMCP {
1671
1700
  .map(([category, count]) => `${category}: ${count}`);
1672
1701
  }
1673
1702
  catch (error) {
1674
- logger_js_1.logger.error('Error calculating operational metrics:', error);
1703
+ logger.error('Error calculating operational metrics:', error);
1675
1704
  }
1676
1705
  return metrics;
1677
1706
  }
@@ -2080,7 +2109,7 @@ class ServiceNowOperationsMCP {
2080
2109
  }
2081
2110
  async handleCatalogItemManager(args) {
2082
2111
  const { action, item_id, ...params } = args;
2083
- logger_js_1.logger.info(`Catalog item manager action: ${action}`, { item_id, params });
2112
+ logger.info(`Catalog item manager action: ${action}`, { item_id, params });
2084
2113
  try {
2085
2114
  switch (action) {
2086
2115
  case 'create': {
@@ -2092,13 +2121,13 @@ class ServiceNowOperationsMCP {
2092
2121
  const defaultCatalogResult = await this.client.searchRecords('sc_catalog', 'active=true^ORDERBYsys_created_on', 1);
2093
2122
  if (defaultCatalogResult.success && defaultCatalogResult.data?.result?.length > 0) {
2094
2123
  catalogId = defaultCatalogResult.data.result[0].sys_id;
2095
- logger_js_1.logger.info('Using default catalog:', {
2124
+ logger.info('Using default catalog:', {
2096
2125
  catalogId,
2097
2126
  catalogName: defaultCatalogResult.data.result[0].title
2098
2127
  });
2099
2128
  }
2100
2129
  else {
2101
- logger_js_1.logger.warn('No catalogs found, catalog item may not be visible');
2130
+ logger.warn('No catalogs found, catalog item may not be visible');
2102
2131
  }
2103
2132
  }
2104
2133
  if (!categoryId) {
@@ -2106,7 +2135,7 @@ class ServiceNowOperationsMCP {
2106
2135
  const defaultCategoryResult = await this.client.searchRecords('sc_category', 'active=true^titleLIKEHardware^ORtitleLIKEGeneral^ORtitleLIKEIT^ORDERBYsys_created_on', 1);
2107
2136
  if (defaultCategoryResult.success && defaultCategoryResult.data?.result?.length > 0) {
2108
2137
  categoryId = defaultCategoryResult.data.result[0].sys_id;
2109
- logger_js_1.logger.info('Using default category:', {
2138
+ logger.info('Using default category:', {
2110
2139
  categoryId,
2111
2140
  categoryName: defaultCategoryResult.data.result[0].title
2112
2141
  });
@@ -2294,7 +2323,7 @@ class ServiceNowOperationsMCP {
2294
2323
  }
2295
2324
  }
2296
2325
  catch (error) {
2297
- logger_js_1.logger.error('Error in catalog item manager:', error);
2326
+ logger.error('Error in catalog item manager:', error);
2298
2327
  throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Catalog item manager error: ${error}`);
2299
2328
  }
2300
2329
  }
@@ -2329,7 +2358,7 @@ class ServiceNowOperationsMCP {
2329
2358
  }
2330
2359
  async handleCatalogItemSearch(args) {
2331
2360
  const { query, include_inactive = false, fuzzy_match = true, category_filter, limit = 50, include_variables = false } = args;
2332
- logger_js_1.logger.info(`Searching catalog items for: ${query}`, { fuzzy_match, category_filter, limit });
2361
+ logger.info(`Searching catalog items for: ${query}`, { fuzzy_match, category_filter, limit });
2333
2362
  try {
2334
2363
  // Build search queries
2335
2364
  const searchQueries = [];
@@ -2468,7 +2497,7 @@ class ServiceNowOperationsMCP {
2468
2497
  };
2469
2498
  }
2470
2499
  catch (error) {
2471
- logger_js_1.logger.error('Error searching catalog items:', error);
2500
+ logger.error('Error searching catalog items:', error);
2472
2501
  throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Catalog search error: ${error}`);
2473
2502
  }
2474
2503
  }
@@ -2599,7 +2628,7 @@ class ServiceNowOperationsMCP {
2599
2628
  }
2600
2629
  async handleCleanupTestArtifacts(args) {
2601
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;
2602
- logger_js_1.logger.info('Starting test artifact cleanup', {
2631
+ logger.info('Starting test artifact cleanup', {
2603
2632
  artifact_types,
2604
2633
  test_patterns,
2605
2634
  max_age_hours,
@@ -2708,7 +2737,7 @@ class ServiceNowOperationsMCP {
2708
2737
  };
2709
2738
  }
2710
2739
  catch (error) {
2711
- logger_js_1.logger.error('Error during test artifact cleanup:', error);
2740
+ logger.error('Error during test artifact cleanup:', error);
2712
2741
  return {
2713
2742
  content: [{
2714
2743
  type: 'text',
@@ -2839,7 +2868,7 @@ class ServiceNowOperationsMCP {
2839
2868
  }
2840
2869
  async handleCreateUserGroup(args) {
2841
2870
  const { name, description, email, manager, parent, type, active = true } = args;
2842
- logger_js_1.logger.info(`Creating user group: ${name}`);
2871
+ logger.info(`Creating user group: ${name}`);
2843
2872
  try {
2844
2873
  // Check if group already exists
2845
2874
  const existingGroup = await this.client.get('/api/now/table/sys_user_group', {
@@ -2872,7 +2901,7 @@ class ServiceNowOperationsMCP {
2872
2901
  groupData.manager = managerUser.sys_id;
2873
2902
  }
2874
2903
  else {
2875
- logger_js_1.logger.warn(`Manager "${manager}" not found, creating group without manager`);
2904
+ logger.warn(`Manager "${manager}" not found, creating group without manager`);
2876
2905
  }
2877
2906
  }
2878
2907
  // Handle parent group lookup
@@ -2882,7 +2911,7 @@ class ServiceNowOperationsMCP {
2882
2911
  groupData.parent = parentGroup.sys_id;
2883
2912
  }
2884
2913
  else {
2885
- logger_js_1.logger.warn(`Parent group "${parent}" not found, creating group without parent`);
2914
+ logger.warn(`Parent group "${parent}" not found, creating group without parent`);
2886
2915
  }
2887
2916
  }
2888
2917
  // Create the group
@@ -2911,7 +2940,7 @@ class ServiceNowOperationsMCP {
2911
2940
  }
2912
2941
  async handleCreateUser(args) {
2913
2942
  const { user_name, first_name, last_name, email, department, manager, phone, title, location, active = true, password } = args;
2914
- logger_js_1.logger.info(`Creating user: ${user_name}`);
2943
+ logger.info(`Creating user: ${user_name}`);
2915
2944
  try {
2916
2945
  // Check if user already exists
2917
2946
  const existingUser = await this.client.get('/api/now/table/sys_user', {
@@ -2947,7 +2976,7 @@ class ServiceNowOperationsMCP {
2947
2976
  userData.manager = managerUser.sys_id;
2948
2977
  }
2949
2978
  else {
2950
- logger_js_1.logger.warn(`Manager "${manager}" not found, creating user without manager`);
2979
+ logger.warn(`Manager "${manager}" not found, creating user without manager`);
2951
2980
  }
2952
2981
  }
2953
2982
  // Handle department lookup
@@ -2957,7 +2986,7 @@ class ServiceNowOperationsMCP {
2957
2986
  userData.department = dept.sys_id;
2958
2987
  }
2959
2988
  else {
2960
- logger_js_1.logger.warn(`Department "${department}" not found, creating user without department`);
2989
+ logger.warn(`Department "${department}" not found, creating user without department`);
2961
2990
  }
2962
2991
  }
2963
2992
  // Handle location lookup
@@ -2967,7 +2996,7 @@ class ServiceNowOperationsMCP {
2967
2996
  userData.location = loc.sys_id;
2968
2997
  }
2969
2998
  else {
2970
- logger_js_1.logger.warn(`Location "${location}" not found, creating user without location`);
2999
+ logger.warn(`Location "${location}" not found, creating user without location`);
2971
3000
  }
2972
3001
  }
2973
3002
  // Create the user
@@ -2996,7 +3025,7 @@ class ServiceNowOperationsMCP {
2996
3025
  }
2997
3026
  async handleAssignUserToGroup(args) {
2998
3027
  const { user, group } = args;
2999
- logger_js_1.logger.info(`Assigning user ${user} to group ${group}`);
3028
+ logger.info(`Assigning user ${user} to group ${group}`);
3000
3029
  try {
3001
3030
  // Find the user
3002
3031
  const userRecord = await this.findUserBySysIdOrUsername(user);
@@ -3059,7 +3088,7 @@ class ServiceNowOperationsMCP {
3059
3088
  }
3060
3089
  async handleRemoveUserFromGroup(args) {
3061
3090
  const { user, group } = args;
3062
- logger_js_1.logger.info(`Removing user ${user} from group ${group}`);
3091
+ logger.info(`Removing user ${user} from group ${group}`);
3063
3092
  try {
3064
3093
  // Find the user
3065
3094
  const userRecord = await this.findUserBySysIdOrUsername(user);
@@ -3114,7 +3143,7 @@ class ServiceNowOperationsMCP {
3114
3143
  }
3115
3144
  async handleListGroupMembers(args) {
3116
3145
  const { group, active_only = true } = args;
3117
- logger_js_1.logger.info(`Listing members of group: ${group}`);
3146
+ logger.info(`Listing members of group: ${group}`);
3118
3147
  try {
3119
3148
  // Find the group
3120
3149
  const groupRecord = await this.findGroupBySysIdOrName(group);
@@ -3151,7 +3180,7 @@ class ServiceNowOperationsMCP {
3151
3180
  const u = member.user;
3152
3181
  // Defensive programming: check if user object exists and has required fields
3153
3182
  if (!u || !u.user_name) {
3154
- logger_js_1.logger.warn(`Group member ${index + 1} has invalid user data:`, member);
3183
+ logger.warn(`Group member ${index + 1} has invalid user data:`, member);
3155
3184
  response += `${index + 1}. **Invalid User Data** - ${member.sys_id || 'Unknown ID'}\n\n`;
3156
3185
  return;
3157
3186
  }
@@ -3247,7 +3276,7 @@ class ServiceNowOperationsMCP {
3247
3276
  async run() {
3248
3277
  const transport = new stdio_js_1.StdioServerTransport();
3249
3278
  await this.server.connect(transport);
3250
- logger_js_1.logger.info('ServiceNow Operations MCP Server started');
3279
+ logger.info('ServiceNow Operations MCP Server started');
3251
3280
  }
3252
3281
  }
3253
3282
  exports.ServiceNowOperationsMCP = ServiceNowOperationsMCP;
@@ -3255,7 +3284,7 @@ exports.ServiceNowOperationsMCP = ServiceNowOperationsMCP;
3255
3284
  if (require.main === module) {
3256
3285
  const server = new ServiceNowOperationsMCP();
3257
3286
  server.run().catch((error) => {
3258
- logger_js_1.logger.error('Failed to start ServiceNow Operations MCP server:', error);
3287
+ logger.error('Failed to start ServiceNow Operations MCP server:', error);
3259
3288
  process.exit(1);
3260
3289
  });
3261
3290
  }