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.
@@ -43,7 +43,7 @@ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
43
43
  const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
44
44
  const servicenow_client_js_1 = require("../utils/servicenow-client.js");
45
45
  const snow_oauth_js_1 = require("../utils/snow-oauth.js");
46
- const logger_js_1 = require("../utils/logger.js");
46
+ const mcp_logger_js_1 = require("./shared/mcp-logger.js");
47
47
  const scope_manager_js_1 = require("../managers/scope-manager.js");
48
48
  const global_scope_strategy_js_1 = require("../strategies/global-scope-strategy.js");
49
49
  const artifact_tracker_js_1 = require("../utils/artifact-tracker.js");
@@ -63,7 +63,7 @@ class ServiceNowDeploymentMCP {
63
63
  });
64
64
  this.client = new servicenow_client_js_1.ServiceNowClient();
65
65
  this.oauth = new snow_oauth_js_1.ServiceNowOAuth();
66
- this.logger = new logger_js_1.Logger('ServiceNowDeploymentMCP');
66
+ this.logger = new mcp_logger_js_1.MCPLogger('ServiceNowDeploymentMCP');
67
67
  this.deploymentAuthManager = new deployment_auth_fix_js_1.DeploymentAuthManager();
68
68
  // Initialize global scope management
69
69
  this.scopeManager = new scope_manager_js_1.ScopeManager({
@@ -361,41 +361,61 @@ class ServiceNowDeploymentMCP {
361
361
  this.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
362
362
  const { name, arguments: args } = request.params;
363
363
  try {
364
+ // Start operation with token tracking
365
+ this.logger.operationStart(name, args);
364
366
  // Note: Authentication check moved to individual tool methods
365
367
  // This allows the MCP server to start without credentials
366
368
  // and fail gracefully when tools are actually used
369
+ let result;
367
370
  switch (name) {
368
371
  case 'snow_validate_deployment':
369
- return await this.validateDeployment(args);
372
+ result = await this.validateDeployment(args);
373
+ break;
370
374
  case 'snow_rollback_deployment':
371
- return await this.rollbackDeployment(args);
375
+ result = await this.rollbackDeployment(args);
376
+ break;
372
377
  case 'snow_deployment_status':
373
- return await this.getDeploymentStatus(args);
378
+ result = await this.getDeploymentStatus(args);
379
+ break;
374
380
  case 'snow_export_artifact':
375
- return await this.exportArtifact(args);
381
+ result = await this.exportArtifact(args);
382
+ break;
376
383
  case 'snow_import_artifact':
377
- return await this.importArtifact(args);
384
+ result = await this.importArtifact(args);
385
+ break;
378
386
  case 'snow_clone_instance_artifact':
379
- return await this.cloneInstanceArtifact(args);
387
+ result = await this.cloneInstanceArtifact(args);
388
+ break;
380
389
  case 'snow_validate_sysid':
381
- return await this.validateSysId(args);
390
+ result = await this.validateSysId(args);
391
+ break;
382
392
  case 'snow_deployment_debug':
383
- return await this.getDeploymentDebug(args);
393
+ result = await this.getDeploymentDebug(args);
394
+ break;
384
395
  case 'snow_auth_diagnostics':
385
- return await this.runAuthDiagnostics(args);
396
+ result = await this.runAuthDiagnostics(args);
397
+ break;
386
398
  case 'snow_preview_widget':
387
- return await this.previewWidget(args);
399
+ result = await this.previewWidget(args);
400
+ break;
388
401
  case 'snow_widget_test':
389
- return await this.testWidget(args);
402
+ result = await this.testWidget(args);
403
+ break;
390
404
  case 'snow_create_solution_package':
391
- return await this.createSolutionPackage(args);
405
+ result = await this.createSolutionPackage(args);
406
+ break;
392
407
  case 'snow_deploy':
393
- return await this.unifiedDeploy(args);
408
+ result = await this.unifiedDeploy(args);
409
+ break;
394
410
  case 'snow_update':
395
- return await this.updateArtifact(args);
411
+ result = await this.updateArtifact(args);
412
+ break;
396
413
  default:
397
414
  throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
398
415
  }
416
+ // Complete operation with token tracking
417
+ this.logger.operationComplete(name, result);
418
+ return result;
399
419
  }
400
420
  catch (error) {
401
421
  this.logger.error(`Tool execution failed: ${name}`, error);
@@ -433,6 +453,7 @@ class ServiceNowDeploymentMCP {
433
453
  5. snow_update_set_complete()
434
454
  `);
435
455
  const updateSetName = `Auto: ${artifactType} - ${artifactName} - ${new Date().toISOString().split('T')[0]}`;
456
+ this.logger.trackAPICall('CREATE', 'sys_update_set', 1);
436
457
  const createResult = await this.client.createUpdateSet({
437
458
  name: updateSetName,
438
459
  description: `Automatically created for ${artifactType} deployment: ${artifactName}`,
@@ -459,6 +480,7 @@ class ServiceNowDeploymentMCP {
459
480
  async createRecordWithRetry(table, data) {
460
481
  try {
461
482
  // First attempt
483
+ this.logger.trackAPICall('CREATE', table, 1);
462
484
  return await this.client.createRecord(table, data);
463
485
  }
464
486
  catch (error) {
@@ -12,7 +12,7 @@ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
12
12
  const servicenow_client_js_1 = require("../utils/servicenow-client.js");
13
13
  const mcp_auth_middleware_js_1 = require("../utils/mcp-auth-middleware.js");
14
14
  const mcp_config_manager_js_1 = require("../utils/mcp-config-manager.js");
15
- const logger_js_1 = require("../utils/logger.js");
15
+ const mcp_logger_js_1 = require("../shared/mcp-logger.js");
16
16
  const widget_template_generator_js_1 = require("../utils/widget-template-generator.js");
17
17
  const fs_1 = require("fs");
18
18
  const path_1 = require("path");
@@ -33,7 +33,7 @@ class ServiceNowDevelopmentAssistantMCP {
33
33
  },
34
34
  });
35
35
  this.client = new servicenow_client_js_1.ServiceNowClient();
36
- this.logger = new logger_js_1.Logger('ServiceNowDevelopmentAssistantMCP');
36
+ this.logger = new mcp_logger_js_1.MCPLogger('ServiceNowDevelopmentAssistantMCP');
37
37
  this.config = mcp_config_manager_js_1.mcpConfig.getMemoryConfig();
38
38
  this.memoryPath = this.config.path || (0, path_1.join)(process.cwd(), 'memory', 'servicenow_artifacts');
39
39
  this.setupHandlers();
@@ -240,46 +240,66 @@ class ServiceNowDevelopmentAssistantMCP {
240
240
  this.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
241
241
  const { name, arguments: args } = request.params;
242
242
  try {
243
+ // Start operation with token tracking
244
+ this.logger.operationStart(name, args);
243
245
  // Authenticate if needed
244
246
  const authResult = await mcp_auth_middleware_js_1.mcpAuth.ensureAuthenticated();
245
247
  if (!authResult.success) {
246
248
  throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, authResult.error || 'Authentication required');
247
249
  }
250
+ let result;
248
251
  switch (name) {
249
252
  case 'snow_find_artifact':
250
- return await this.findArtifact(args);
253
+ result = await this.findArtifact(args);
254
+ break;
251
255
  case 'snow_edit_artifact':
252
- return await this.editArtifact(args);
256
+ result = await this.editArtifact(args);
257
+ break;
253
258
  case 'snow_get_by_sysid':
254
- return await this.getBySysId(args);
259
+ result = await this.getBySysId(args);
260
+ break;
255
261
  case 'snow_edit_by_sysid':
256
- return await this.editBySysId(args);
262
+ result = await this.editBySysId(args);
263
+ break;
257
264
  case 'snow_analyze_artifact':
258
- return await this.analyzeArtifact(args);
265
+ result = await this.analyzeArtifact(args);
266
+ break;
259
267
  case 'snow_memory_search':
260
- return await this.searchMemory(args);
268
+ result = await this.searchMemory(args);
269
+ break;
261
270
  case 'snow_comprehensive_search':
262
- return await this.comprehensiveSearch(args);
271
+ result = await this.comprehensiveSearch(args);
272
+ break;
263
273
  case 'snow_sync_data_consistency':
264
- return await this.syncDataConsistency(args);
274
+ result = await this.syncDataConsistency(args);
275
+ break;
265
276
  case 'snow_validate_live_connection':
266
- return await this.validateLiveConnection(args);
277
+ result = await this.validateLiveConnection(args);
278
+ break;
267
279
  case 'batch_deployment_validator':
268
- return await this.batchDeploymentValidator(args);
280
+ result = await this.batchDeploymentValidator(args);
281
+ break;
269
282
  case 'snow_escalate_permissions':
270
- return await this.escalatePermissions(args);
283
+ result = await this.escalatePermissions(args);
284
+ break;
271
285
  case 'snow_analyze_requirements':
272
- return await this.analyzeRequirements(args);
286
+ result = await this.analyzeRequirements(args);
287
+ break;
273
288
  case 'snow_orchestrate_development':
274
- return await this.orchestrateDevelopment(args);
289
+ result = await this.orchestrateDevelopment(args);
290
+ break;
275
291
  case 'snow_verify_artifact_searchable':
276
- return await this.verifyArtifactSearchable(args);
292
+ result = await this.verifyArtifactSearchable(args);
293
+ break;
277
294
  case 'snow_generate_documentation':
278
- return await this.generateDocumentation(args);
295
+ result = await this.generateDocumentation(args);
296
+ break;
279
297
  case 'snow_documentation_suggestions':
280
- return await this.getDocumentationSuggestions(args);
298
+ result = await this.getDocumentationSuggestions(args);
299
+ break;
281
300
  case 'snow_start_continuous_documentation':
282
- return await this.startContinuousDocumentation(args);
301
+ result = await this.startContinuousDocumentation(args);
302
+ break;
283
303
  case 'snow_analyze_costs':
284
304
  const costRequest = {
285
305
  scope: args.scope || 'all',
@@ -288,7 +308,7 @@ class ServiceNowDevelopmentAssistantMCP {
288
308
  testing_enabled: args.testing_enabled !== false
289
309
  };
290
310
  const costResult = await this.costOptimizationEngine.analyzeCosts(costRequest);
291
- return {
311
+ result = {
292
312
  content: [
293
313
  {
294
314
  type: 'text',
@@ -296,9 +316,10 @@ class ServiceNowDevelopmentAssistantMCP {
296
316
  }
297
317
  ]
298
318
  };
319
+ break;
299
320
  case 'snow_cost_dashboard':
300
321
  const dashboardResult = await this.costOptimizationEngine.getCostDashboard();
301
- return {
322
+ result = {
302
323
  content: [
303
324
  {
304
325
  type: 'text',
@@ -306,9 +327,10 @@ class ServiceNowDevelopmentAssistantMCP {
306
327
  }
307
328
  ]
308
329
  };
330
+ break;
309
331
  case 'snow_start_autonomous_cost_optimization':
310
332
  const startResult = await this.costOptimizationEngine.startAutonomousOptimization(args);
311
- return {
333
+ result = {
312
334
  content: [
313
335
  {
314
336
  type: 'text',
@@ -316,9 +338,10 @@ class ServiceNowDevelopmentAssistantMCP {
316
338
  }
317
339
  ]
318
340
  };
341
+ break;
319
342
  case 'snow_implement_cost_optimization':
320
343
  const implementResult = await this.costOptimizationEngine.implementOptimization(String(args.optimization_id));
321
- return {
344
+ result = {
322
345
  content: [
323
346
  {
324
347
  type: 'text',
@@ -326,9 +349,10 @@ class ServiceNowDevelopmentAssistantMCP {
326
349
  }
327
350
  ]
328
351
  };
352
+ break;
329
353
  case 'snow_assess_compliance':
330
354
  const complianceResult = await this.complianceSystem.assessCompliance(args);
331
- return {
355
+ result = {
332
356
  content: [
333
357
  {
334
358
  type: 'text',
@@ -336,9 +360,10 @@ class ServiceNowDevelopmentAssistantMCP {
336
360
  }
337
361
  ]
338
362
  };
363
+ break;
339
364
  case 'snow_compliance_dashboard':
340
365
  const complianceDashboard = await this.complianceSystem.getComplianceDashboard();
341
- return {
366
+ result = {
342
367
  content: [
343
368
  {
344
369
  type: 'text',
@@ -346,9 +371,10 @@ class ServiceNowDevelopmentAssistantMCP {
346
371
  }
347
372
  ]
348
373
  };
374
+ break;
349
375
  case 'snow_start_compliance_monitoring':
350
376
  const monitoringResult = await this.complianceSystem.startContinuousMonitoring(args);
351
- return {
377
+ result = {
352
378
  content: [
353
379
  {
354
380
  type: 'text',
@@ -356,9 +382,10 @@ class ServiceNowDevelopmentAssistantMCP {
356
382
  }
357
383
  ]
358
384
  };
385
+ break;
359
386
  case 'snow_execute_corrective_action':
360
387
  const actionResult = await this.complianceSystem.executeCorrectiveAction(String(args.action_id), args);
361
- return {
388
+ result = {
362
389
  content: [
363
390
  {
364
391
  type: 'text',
@@ -366,9 +393,10 @@ class ServiceNowDevelopmentAssistantMCP {
366
393
  }
367
394
  ]
368
395
  };
396
+ break;
369
397
  case 'snow_health_check':
370
398
  const healthResult = await this.selfHealingSystem.performHealthCheck(args);
371
- return {
399
+ result = {
372
400
  content: [
373
401
  {
374
402
  type: 'text',
@@ -376,9 +404,10 @@ class ServiceNowDevelopmentAssistantMCP {
376
404
  }
377
405
  ]
378
406
  };
407
+ break;
379
408
  case 'snow_health_dashboard':
380
409
  const healthDashboard = await this.selfHealingSystem.getHealthDashboard();
381
- return {
410
+ result = {
382
411
  content: [
383
412
  {
384
413
  type: 'text',
@@ -386,9 +415,10 @@ class ServiceNowDevelopmentAssistantMCP {
386
415
  }
387
416
  ]
388
417
  };
418
+ break;
389
419
  case 'snow_start_autonomous_healing':
390
420
  const healingStartResult = await this.selfHealingSystem.startAutonomousHealing(args);
391
- return {
421
+ result = {
392
422
  content: [
393
423
  {
394
424
  type: 'text',
@@ -396,9 +426,10 @@ class ServiceNowDevelopmentAssistantMCP {
396
426
  }
397
427
  ]
398
428
  };
429
+ break;
399
430
  case 'snow_execute_healing_action':
400
431
  const healingResult = await this.selfHealingSystem.executeHealingAction(String(args.action_id), args);
401
- return {
432
+ result = {
402
433
  content: [
403
434
  {
404
435
  type: 'text',
@@ -406,9 +437,13 @@ class ServiceNowDevelopmentAssistantMCP {
406
437
  }
407
438
  ]
408
439
  };
440
+ break;
409
441
  default:
410
442
  throw new Error(`Unknown tool: ${name}`);
411
443
  }
444
+ // Complete operation with token tracking
445
+ this.logger.operationComplete(name, result);
446
+ return result;
412
447
  }
413
448
  catch (error) {
414
449
  this.logger.error(`Tool execution failed: ${name}`, error);
@@ -537,6 +572,7 @@ class ServiceNowDevelopmentAssistantMCP {
537
572
  try {
538
573
  this.logger.info('Analyzing ServiceNow artifact', { sys_id: args.sys_id });
539
574
  // Fetch complete artifact from ServiceNow
575
+ this.logger.trackAPICall('GET', args.table, 1);
540
576
  const artifact = await this.client.getRecord(args.table, args.sys_id);
541
577
  // Skip indexing - causes timeouts
542
578
  /*
@@ -12,7 +12,7 @@ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
12
12
  const servicenow_client_js_1 = require("../utils/servicenow-client.js");
13
13
  const mcp_auth_middleware_js_1 = require("../utils/mcp-auth-middleware.js");
14
14
  const mcp_config_manager_js_1 = require("../utils/mcp-config-manager.js");
15
- const logger_js_1 = require("../utils/logger.js");
15
+ const mcp_logger_js_1 = require("../shared/mcp-logger.js");
16
16
  class ServiceNowFlowWorkspaceMobileMCP {
17
17
  constructor() {
18
18
  this.server = new index_js_1.Server({
@@ -24,7 +24,7 @@ class ServiceNowFlowWorkspaceMobileMCP {
24
24
  },
25
25
  });
26
26
  this.client = new servicenow_client_js_1.ServiceNowClient();
27
- this.logger = new logger_js_1.Logger('ServiceNowFlowWorkspaceMobileMCP');
27
+ this.logger = new mcp_logger_js_1.MCPLogger('ServiceNowFlowWorkspaceMobileMCP');
28
28
  this.config = mcp_config_manager_js_1.mcpConfig.getConfig();
29
29
  this.setupHandlers();
30
30
  }
@@ -341,57 +341,83 @@ class ServiceNowFlowWorkspaceMobileMCP {
341
341
  this.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
342
342
  try {
343
343
  const { name, arguments: args } = request.params;
344
+ // Start operation with token tracking
345
+ this.logger.operationStart(name, args);
344
346
  const authResult = await mcp_auth_middleware_js_1.mcpAuth.ensureAuthenticated();
345
347
  if (!authResult.success) {
346
348
  throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, authResult.error || 'Authentication required');
347
349
  }
350
+ let result;
348
351
  switch (name) {
349
352
  // Flow Designer
350
353
  case 'snow_create_flow':
351
- return await this.createFlow(args);
354
+ result = await this.createFlow(args);
355
+ break;
352
356
  case 'snow_create_flow_action':
353
- return await this.createFlowAction(args);
357
+ result = await this.createFlowAction(args);
358
+ break;
354
359
  case 'snow_create_subflow':
355
- return await this.createSubflow(args);
360
+ result = await this.createSubflow(args);
361
+ break;
356
362
  case 'snow_create_flow_trigger':
357
- return await this.createFlowTrigger(args);
363
+ result = await this.createFlowTrigger(args);
364
+ break;
358
365
  case 'snow_test_flow':
359
- return await this.testFlow(args);
366
+ result = await this.testFlow(args);
367
+ break;
360
368
  case 'snow_get_flow_execution':
361
- return await this.getFlowExecution(args);
369
+ result = await this.getFlowExecution(args);
370
+ break;
362
371
  case 'snow_discover_flows':
363
- return await this.discoverFlows(args);
372
+ result = await this.discoverFlows(args);
373
+ break;
364
374
  // Agent Workspace
365
375
  case 'snow_create_workspace':
366
- return await this.createWorkspace(args);
376
+ result = await this.createWorkspace(args);
377
+ break;
367
378
  case 'snow_create_workspace_tab':
368
- return await this.createWorkspaceTab(args);
379
+ result = await this.createWorkspaceTab(args);
380
+ break;
369
381
  case 'snow_create_workspace_list':
370
- return await this.createWorkspaceList(args);
382
+ result = await this.createWorkspaceList(args);
383
+ break;
371
384
  case 'snow_create_contextual_panel':
372
- return await this.createContextualPanel(args);
385
+ result = await this.createContextualPanel(args);
386
+ break;
373
387
  case 'snow_configure_workspace_notifications':
374
- return await this.configureWorkspaceNotifications(args);
388
+ result = await this.configureWorkspaceNotifications(args);
389
+ break;
375
390
  case 'snow_discover_workspaces':
376
- return await this.discoverWorkspaces(args);
391
+ result = await this.discoverWorkspaces(args);
392
+ break;
377
393
  // Mobile
378
394
  case 'snow_configure_mobile_app':
379
- return await this.configureMobileApp(args);
395
+ result = await this.configureMobileApp(args);
396
+ break;
380
397
  case 'snow_create_mobile_layout':
381
- return await this.createMobileLayout(args);
398
+ result = await this.createMobileLayout(args);
399
+ break;
382
400
  case 'snow_send_push_notification':
383
- return await this.sendPushNotification(args);
401
+ result = await this.sendPushNotification(args);
402
+ break;
384
403
  case 'snow_configure_offline_sync':
385
- return await this.configureOfflineSync(args);
404
+ result = await this.configureOfflineSync(args);
405
+ break;
386
406
  case 'snow_create_mobile_action':
387
- return await this.createMobileAction(args);
407
+ result = await this.createMobileAction(args);
408
+ break;
388
409
  case 'snow_get_mobile_analytics':
389
- return await this.getMobileAnalytics(args);
410
+ result = await this.getMobileAnalytics(args);
411
+ break;
390
412
  case 'snow_discover_mobile_configs':
391
- return await this.discoverMobileConfigs(args);
413
+ result = await this.discoverMobileConfigs(args);
414
+ break;
392
415
  default:
393
416
  throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
394
417
  }
418
+ // Complete operation with token tracking
419
+ this.logger.operationComplete(name, result);
420
+ return result;
395
421
  }
396
422
  catch (error) {
397
423
  this.logger.error(`Error in ${request.params.name}:`, error);
@@ -414,6 +440,7 @@ class ServiceNowFlowWorkspaceMobileMCP {
414
440
  sys_class_name: 'sys_hub_flow'
415
441
  };
416
442
  const updateSetResult = await this.client.ensureUpdateSet();
443
+ this.logger.trackAPICall('CREATE', 'sys_hub_flow', 1);
417
444
  const response = await this.client.createRecord('sys_hub_flow', flowData);
418
445
  if (!response.success) {
419
446
  throw new Error(`Failed to create flow: ${response.error}`);
@@ -451,6 +478,7 @@ class ServiceNowFlowWorkspaceMobileMCP {
451
478
  values: args.values ? JSON.stringify(args.values) : '',
452
479
  condition: args.condition || ''
453
480
  };
481
+ this.logger.trackAPICall('CREATE', 'sys_hub_action_instance', 1);
454
482
  const response = await this.client.createRecord('sys_hub_action_instance', actionData);
455
483
  if (!response.success) {
456
484
  throw new Error(`Failed to create flow action: ${response.error}`);
@@ -646,6 +674,7 @@ ${executionList}
646
674
  query += query ? '^' : '';
647
675
  query += 'active=true';
648
676
  }
677
+ this.logger.trackAPICall('SEARCH', 'sys_hub_flow', 50);
649
678
  const response = await this.client.searchRecords('sys_hub_flow', query, 50);
650
679
  if (!response.success) {
651
680
  throw new Error('Failed to discover flows');
@@ -695,6 +724,7 @@ ${args.include_subflows && subflows.length ? `\nšŸ”„ Subflows:\n\n${subflowList}
695
724
  theme: args.theme || 'default',
696
725
  roles: args.roles ? args.roles.join(',') : ''
697
726
  };
727
+ this.logger.trackAPICall('CREATE', 'sys_aw_workspace', 1);
698
728
  const response = await this.client.createRecord('sys_aw_workspace', workspaceData);
699
729
  if (!response.success) {
700
730
  throw new Error(`Failed to create workspace: ${response.error}`);
@@ -923,6 +953,7 @@ ${workspaceList.join('\n\n')}
923
953
  authentication: args.authentication || 'oauth',
924
954
  push_enabled: args.push_enabled !== false
925
955
  };
956
+ this.logger.trackAPICall('CREATE', 'sys_mobile_config', 1);
926
957
  const response = await this.client.createRecord('sys_mobile_config', mobileConfig);
927
958
  if (!response.success) {
928
959
  throw new Error(`Failed to configure mobile app: ${response.error}`);