snow-flow 3.4.13 → 3.4.15

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.
@@ -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 ServiceNowPlatformDevelopmentMCP {
17
17
  constructor() {
18
18
  this.tableCache = new Map();
@@ -25,7 +25,7 @@ class ServiceNowPlatformDevelopmentMCP {
25
25
  },
26
26
  });
27
27
  this.client = new servicenow_client_js_1.ServiceNowClient();
28
- this.logger = new logger_js_1.Logger('ServiceNowPlatformDevelopmentMCP');
28
+ this.logger = new mcp_logger_js_1.MCPLogger('ServiceNowPlatformDevelopmentMCP');
29
29
  this.config = mcp_config_manager_js_1.mcpConfig.getConfig();
30
30
  this.setupHandlers();
31
31
  }
@@ -172,33 +172,48 @@ class ServiceNowPlatformDevelopmentMCP {
172
172
  this.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
173
173
  try {
174
174
  const { name, arguments: args } = request.params;
175
+ // Start operation with token tracking
176
+ this.logger.operationStart(name, args);
175
177
  // Ensure authentication
176
178
  const authResult = await mcp_auth_middleware_js_1.mcpAuth.ensureAuthenticated();
177
179
  if (!authResult.success) {
178
180
  throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, authResult.error || 'Authentication required');
179
181
  }
182
+ let result;
180
183
  switch (name) {
181
184
  case 'snow_create_ui_page':
182
- return await this.createUIPage(args);
185
+ result = await this.createUIPage(args);
186
+ break;
183
187
  case 'snow_create_script_include':
184
- return await this.createScriptInclude(args);
188
+ result = await this.createScriptInclude(args);
189
+ break;
185
190
  case 'snow_create_business_rule':
186
- return await this.createBusinessRule(args);
191
+ result = await this.createBusinessRule(args);
192
+ break;
187
193
  case 'snow_create_client_script':
188
- return await this.createClientScript(args);
194
+ result = await this.createClientScript(args);
195
+ break;
189
196
  case 'snow_create_ui_policy':
190
- return await this.createUIPolicy(args);
197
+ result = await this.createUIPolicy(args);
198
+ break;
191
199
  case 'snow_create_ui_action':
192
- return await this.createUIAction(args);
200
+ result = await this.createUIAction(args);
201
+ break;
193
202
  case 'snow_discover_platform_tables':
194
- return await this.discoverPlatformTables(args);
203
+ result = await this.discoverPlatformTables(args);
204
+ break;
195
205
  case 'snow_discover_table_fields':
196
- return await this.discoverTableFields(args);
206
+ result = await this.discoverTableFields(args);
207
+ break;
197
208
  case 'snow_table_schema_discovery':
198
- return await this.discoverTableSchema(args);
209
+ result = await this.discoverTableSchema(args);
210
+ break;
199
211
  default:
200
212
  throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
201
213
  }
214
+ // Complete operation with token tracking
215
+ this.logger.operationComplete(name, result);
216
+ return result;
202
217
  }
203
218
  catch (error) {
204
219
  this.logger.error(`Error in ${request.params.name}:`, error);
@@ -224,6 +239,7 @@ class ServiceNowPlatformDevelopmentMCP {
224
239
  const discoveredTables = [];
225
240
  for (const tableQuery of tableQueries) {
226
241
  if (category === 'all' || category === tableQuery.category) {
242
+ this.logger.trackAPICall('SEARCH', 'sys_db_object', 50);
227
243
  const tablesResponse = await this.client.searchRecords('sys_db_object', tableQuery.query, 50);
228
244
  if (tablesResponse.success && tablesResponse.data) {
229
245
  discoveredTables.push({
@@ -268,6 +284,7 @@ class ServiceNowPlatformDevelopmentMCP {
268
284
  }
269
285
  // Get all fields for this table with CORRECT query syntax
270
286
  // ✅ FIX: Use proper ServiceNow query for dictionary
287
+ this.logger.trackAPICall('SEARCH', 'sys_dictionary', 500);
271
288
  const fieldsResponse = await this.client.searchRecords('sys_dictionary', `name=${tableInfo.name}^element!=NULL^ORname=${tableInfo.name}^elementISNOTEMPTY`, 500 // Increased limit for tables with many fields
272
289
  );
273
290
  if (!fieldsResponse.success || !fieldsResponse.data) {
@@ -361,6 +378,7 @@ class ServiceNowPlatformDevelopmentMCP {
361
378
  };
362
379
  }
363
380
  // Try direct lookup first
381
+ this.logger.trackAPICall('SEARCH', 'sys_db_object', 1);
364
382
  const tableResponse = await this.client.searchRecords('sys_db_object', `name=${tableName}`, 1);
365
383
  if (tableResponse.success && tableResponse.data?.result?.length > 0) {
366
384
  const table = tableResponse.data.result[0];
@@ -373,6 +391,7 @@ class ServiceNowPlatformDevelopmentMCP {
373
391
  // Log the actual response for debugging
374
392
  this.logger.debug(`Table lookup response for ${tableName}: ${JSON.stringify(tableResponse)}`);
375
393
  // Try by sys_id
394
+ this.logger.trackAPICall('SEARCH', 'sys_db_object', 1);
376
395
  const tableByIdResponse = await this.client.searchRecords('sys_db_object', `sys_id=${tableName}`, 1);
377
396
  if (tableByIdResponse.success && tableByIdResponse.data?.result?.length > 0) {
378
397
  const table = tableByIdResponse.data.result[0];
@@ -383,6 +402,7 @@ class ServiceNowPlatformDevelopmentMCP {
383
402
  };
384
403
  }
385
404
  // Try partial match
405
+ this.logger.trackAPICall('SEARCH', 'sys_db_object', 5);
386
406
  const tableByPartialResponse = await this.client.searchRecords('sys_db_object', `nameCONTAINS${tableName}^ORlabelCONTAINS${tableName}`, 5);
387
407
  if (tableByPartialResponse.success && tableByPartialResponse.data?.result?.length > 0) {
388
408
  const table = tableByPartialResponse.data.result[0];
@@ -418,6 +438,7 @@ class ServiceNowPlatformDevelopmentMCP {
418
438
  };
419
439
  // Ensure we have Update Set
420
440
  const updateSetResult = await this.client.ensureUpdateSet();
441
+ this.logger.trackAPICall('CREATE', 'sys_ui_page', 1);
421
442
  const response = await this.client.createRecord('sys_ui_page', uiPageData);
422
443
  if (!response.success) {
423
444
  throw new Error(`Failed to create UI Page: ${response.error}`);
@@ -448,6 +469,7 @@ class ServiceNowPlatformDevelopmentMCP {
448
469
  api_name: args.apiName || args.name
449
470
  };
450
471
  const updateSetResult = await this.client.ensureUpdateSet();
472
+ this.logger.trackAPICall('CREATE', 'sys_script_include', 1);
451
473
  const response = await this.client.createRecord('sys_script_include', scriptIncludeData);
452
474
  if (!response.success) {
453
475
  throw new Error(`Failed to create Script Include: ${response.error}`);
@@ -484,6 +506,7 @@ class ServiceNowPlatformDevelopmentMCP {
484
506
  description: args.description || ''
485
507
  };
486
508
  const updateSetResult = await this.client.ensureUpdateSet();
509
+ this.logger.trackAPICall('CREATE', 'sys_script', 1);
487
510
  const response = await this.client.createRecord('sys_script', businessRuleData);
488
511
  if (!response.success) {
489
512
  throw new Error(`Failed to create Business Rule: ${response.error}`);
@@ -520,6 +543,7 @@ class ServiceNowPlatformDevelopmentMCP {
520
543
  description: args.description || ''
521
544
  };
522
545
  const updateSetResult = await this.client.ensureUpdateSet();
546
+ this.logger.trackAPICall('CREATE', 'sys_script_client', 1);
523
547
  const response = await this.client.createRecord('sys_script_client', clientScriptData);
524
548
  if (!response.success) {
525
549
  throw new Error(`Failed to create Client Script: ${response.error}`);
@@ -555,6 +579,7 @@ class ServiceNowPlatformDevelopmentMCP {
555
579
  reverse_if_false: args.reverseWhenFalse || false
556
580
  };
557
581
  const updateSetResult = await this.client.ensureUpdateSet();
582
+ this.logger.trackAPICall('CREATE', 'sys_ui_policy', 1);
558
583
  const response = await this.client.createRecord('sys_ui_policy', uiPolicyData);
559
584
  if (!response.success) {
560
585
  throw new Error(`Failed to create UI Policy: ${response.error}`);
@@ -592,6 +617,7 @@ class ServiceNowPlatformDevelopmentMCP {
592
617
  description: args.description || ''
593
618
  };
594
619
  const updateSetResult = await this.client.ensureUpdateSet();
620
+ this.logger.trackAPICall('CREATE', 'sys_ui_action', 1);
595
621
  const response = await this.client.createRecord('sys_ui_action', uiActionData);
596
622
  if (!response.success) {
597
623
  throw new Error(`Failed to create UI Action: ${response.error}`);
@@ -613,6 +639,7 @@ class ServiceNowPlatformDevelopmentMCP {
613
639
  */
614
640
  async discoverRequiredFields(tableName) {
615
641
  try {
642
+ this.logger.trackAPICall('SEARCH', 'sys_dictionary', 50);
616
643
  const fieldsResponse = await this.client.searchRecords('sys_dictionary', `nameSTARTSWITH${tableName}^element!=NULL^mandatory=true`, 50);
617
644
  if (fieldsResponse.success && fieldsResponse.data) {
618
645
  return fieldsResponse.data.result.map((field) => field.element);
@@ -647,6 +674,7 @@ class ServiceNowPlatformDevelopmentMCP {
647
674
  const isStandardTable = tableInfo.sys_id.startsWith('standard_table_');
648
675
  let tableDetailsResponse = { success: false };
649
676
  if (!isStandardTable) {
677
+ this.logger.trackAPICall('GET', 'sys_db_object', 1);
650
678
  tableDetailsResponse = await this.client.getRecord('sys_db_object', tableInfo.sys_id);
651
679
  }
652
680
  // Declare the variable once with proper type
@@ -676,6 +704,7 @@ class ServiceNowPlatformDevelopmentMCP {
676
704
  tableDetails = tableDetailsResponse.data;
677
705
  }
678
706
  // Get all fields with detailed information
707
+ this.logger.trackAPICall('SEARCH', 'sys_dictionary', 200);
679
708
  const fieldsResponse = await this.client.searchRecords('sys_dictionary', `name=${tableInfo.name}^element!=NULL`, 200);
680
709
  if (!fieldsResponse.success || !fieldsResponse.data) {
681
710
  const errorMessage = fieldsResponse.error ||
@@ -722,6 +751,7 @@ class ServiceNowPlatformDevelopmentMCP {
722
751
  extensionModel: tableDetails.extension_model
723
752
  };
724
753
  // Find tables that extend this one
754
+ this.logger.trackAPICall('SEARCH', 'sys_db_object', 50);
725
755
  const childTablesResponse = await this.client.searchRecords('sys_db_object', `super_class=${tableInfo.sys_id}`, 50);
726
756
  if (childTablesResponse.success && childTablesResponse.data) {
727
757
  hierarchy.extendedBy = childTablesResponse.data.result.map((child) => ({
@@ -734,6 +764,7 @@ class ServiceNowPlatformDevelopmentMCP {
734
764
  // Get indexes if requested
735
765
  let indexes = [];
736
766
  if (includeIndexes) {
767
+ this.logger.trackAPICall('SEARCH', 'sys_db_index', 50);
737
768
  const indexResponse = await this.client.searchRecords('sys_db_index', `table=${tableInfo.sys_id}`, 50);
738
769
  if (indexResponse.success && indexResponse.data) {
739
770
  indexes = indexResponse.data.result.map((index) => ({
@@ -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 anti_mock_data_validator_js_1 = require("../utils/anti-mock-data-validator.js");
17
17
  class ServiceNowReportingAnalyticsMCP {
18
18
  constructor() {
@@ -25,7 +25,7 @@ class ServiceNowReportingAnalyticsMCP {
25
25
  },
26
26
  });
27
27
  this.client = new servicenow_client_js_1.ServiceNowClient();
28
- this.logger = new logger_js_1.Logger('ServiceNowReportingAnalyticsMCP');
28
+ this.logger = new mcp_logger_js_1.MCPLogger('ServiceNowReportingAnalyticsMCP');
29
29
  this.config = mcp_config_manager_js_1.mcpConfig.getConfig();
30
30
  this.setupHandlers();
31
31
  }
@@ -215,36 +215,53 @@ class ServiceNowReportingAnalyticsMCP {
215
215
  this.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
216
216
  try {
217
217
  const { name, arguments: args } = request.params;
218
+ // Start operation with token tracking
219
+ this.logger.operationStart(name, args);
218
220
  const authResult = await mcp_auth_middleware_js_1.mcpAuth.ensureAuthenticated();
219
221
  if (!authResult.success) {
220
222
  throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, authResult.error || 'Authentication required');
221
223
  }
224
+ let result;
222
225
  switch (name) {
223
226
  case 'snow_create_report':
224
- return await this.createReport(args);
227
+ result = await this.createReport(args);
228
+ break;
225
229
  case 'snow_create_dashboard':
226
- return await this.createDashboard(args);
230
+ result = await this.createDashboard(args);
231
+ break;
227
232
  case 'snow_create_kpi':
228
- return await this.createKPI(args);
233
+ result = await this.createKPI(args);
234
+ break;
229
235
  case 'snow_create_data_visualization':
230
- return await this.createDataVisualization(args);
236
+ result = await this.createDataVisualization(args);
237
+ break;
231
238
  case 'snow_create_performance_analytics':
232
- return await this.createPerformanceAnalytics(args);
239
+ result = await this.createPerformanceAnalytics(args);
240
+ break;
233
241
  case 'snow_create_scheduled_report':
234
- return await this.createScheduledReport(args);
242
+ result = await this.createScheduledReport(args);
243
+ break;
235
244
  case 'snow_discover_reporting_tables':
236
- return await this.discoverReportingTables(args);
245
+ result = await this.discoverReportingTables(args);
246
+ break;
237
247
  case 'snow_discover_report_fields':
238
- return await this.discoverReportFields(args);
248
+ result = await this.discoverReportFields(args);
249
+ break;
239
250
  case 'snow_analyze_data_quality':
240
- return await this.analyzeDataQuality(args);
251
+ result = await this.analyzeDataQuality(args);
252
+ break;
241
253
  case 'snow_generate_insights':
242
- return await this.generateInsights(args);
254
+ result = await this.generateInsights(args);
255
+ break;
243
256
  case 'snow_export_report_data':
244
- return await this.exportReportData(args);
257
+ result = await this.exportReportData(args);
258
+ break;
245
259
  default:
246
260
  throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
247
261
  }
262
+ // Complete operation with token tracking
263
+ this.logger.operationComplete(name, result);
264
+ return result;
248
265
  }
249
266
  catch (error) {
250
267
  this.logger.error(`Error in ${request.params.name}:`, error);
@@ -295,6 +312,7 @@ class ServiceNowReportingAnalyticsMCP {
295
312
  ...aggregateConfig
296
313
  };
297
314
  const updateSetResult = await this.client.ensureUpdateSet();
315
+ this.logger.trackAPICall('CREATE', 'sys_report', 1);
298
316
  const response = await this.client.createRecord('sys_report', reportData);
299
317
  if (!response.success) {
300
318
  throw new Error(`Failed to create Report: ${response.error}`);
@@ -324,6 +342,7 @@ class ServiceNowReportingAnalyticsMCP {
324
342
  const layouts = await this.getDashboardLayouts();
325
343
  const updateSetResult = await this.client.ensureUpdateSet();
326
344
  // Try Performance Analytics dashboard first (pa_dashboards)
345
+ this.logger.trackAPICall('CREATE', 'pa_dashboards', 1);
327
346
  let response = await this.client.createRecord('pa_dashboards', {
328
347
  name: args.name,
329
348
  title: args.name,
@@ -431,6 +450,7 @@ class ServiceNowReportingAnalyticsMCP {
431
450
  };
432
451
  const updateSetResult = await this.client.ensureUpdateSet();
433
452
  // Try pa_indicators (Performance Analytics) for KPIs
453
+ this.logger.trackAPICall('CREATE', 'pa_indicators', 1);
434
454
  let response = await this.client.createRecord('pa_indicators', {
435
455
  name: args.name,
436
456
  label: args.name,
@@ -672,6 +692,7 @@ class ServiceNowReportingAnalyticsMCP {
672
692
  if (args?.category) {
673
693
  query = `sys_class_name=${args.category}`;
674
694
  }
695
+ this.logger.trackAPICall('SEARCH', 'sys_db_object', 100);
675
696
  const tables = await this.client.searchRecords('sys_db_object', query, 100);
676
697
  if (!tables.success) {
677
698
  throw new Error('Failed to discover reporting tables');
@@ -720,6 +741,7 @@ class ServiceNowReportingAnalyticsMCP {
720
741
  if (args.fieldType) {
721
742
  query += `^internal_type=${args.fieldType}`;
722
743
  }
744
+ this.logger.trackAPICall('SEARCH', 'sys_dictionary', 100);
723
745
  const fields = await this.client.searchRecords('sys_dictionary', query, 100);
724
746
  if (!fields.success) {
725
747
  throw new Error('Failed to discover report fields');
@@ -756,6 +778,7 @@ class ServiceNowReportingAnalyticsMCP {
756
778
  throw new Error(`Table not found: ${args.table}`);
757
779
  }
758
780
  // Get REAL data for analysis (increased from sample to comprehensive dataset)
781
+ this.logger.trackAPICall('SEARCH', args.table, 1000);
759
782
  const sampleData = await this.client.searchRecords(args.table, '', 1000); // Get up to 1000 records for REAL analysis
760
783
  if (!sampleData.success) {
761
784
  throw new Error('Failed to retrieve sample data');
@@ -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 ServiceNowSecurityComplianceMCP {
17
17
  constructor() {
18
18
  this.server = new index_js_1.Server({
@@ -24,7 +24,7 @@ class ServiceNowSecurityComplianceMCP {
24
24
  },
25
25
  });
26
26
  this.client = new servicenow_client_js_1.ServiceNowClient();
27
- this.logger = new logger_js_1.Logger('ServiceNowSecurityComplianceMCP');
27
+ this.logger = new mcp_logger_js_1.MCPLogger('ServiceNowSecurityComplianceMCP');
28
28
  this.config = mcp_config_manager_js_1.mcpConfig.getConfig();
29
29
  this.setupHandlers();
30
30
  }
@@ -199,36 +199,53 @@ class ServiceNowSecurityComplianceMCP {
199
199
  this.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
200
200
  try {
201
201
  const { name, arguments: args } = request.params;
202
+ // Start operation with token tracking
203
+ this.logger.operationStart(name, args);
202
204
  const authResult = await mcp_auth_middleware_js_1.mcpAuth.ensureAuthenticated();
203
205
  if (!authResult.success) {
204
206
  throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, authResult.error || 'Authentication required');
205
207
  }
208
+ let result;
206
209
  switch (name) {
207
210
  case 'snow_create_security_policy':
208
- return await this.createSecurityPolicy(args);
211
+ result = await this.createSecurityPolicy(args);
212
+ break;
209
213
  case 'snow_create_compliance_rule':
210
- return await this.createComplianceRule(args);
214
+ result = await this.createComplianceRule(args);
215
+ break;
211
216
  case 'snow_create_audit_rule':
212
- return await this.createAuditRule(args);
217
+ result = await this.createAuditRule(args);
218
+ break;
213
219
  case 'snow_create_access_control':
214
- return await this.createAccessControl(args);
220
+ result = await this.createAccessControl(args);
221
+ break;
215
222
  case 'snow_create_data_policy':
216
- return await this.createDataPolicy(args);
223
+ result = await this.createDataPolicy(args);
224
+ break;
217
225
  case 'snow_create_vulnerability_scan':
218
- return await this.createVulnerabilityScan(args);
226
+ result = await this.createVulnerabilityScan(args);
227
+ break;
219
228
  case 'snow_discover_security_frameworks':
220
- return await this.discoverSecurityFrameworks(args);
229
+ result = await this.discoverSecurityFrameworks(args);
230
+ break;
221
231
  case 'snow_discover_security_policies':
222
- return await this.discoverSecurityPolicies(args);
232
+ result = await this.discoverSecurityPolicies(args);
233
+ break;
223
234
  case 'snow_run_compliance_scan':
224
- return await this.runComplianceScan(args);
235
+ result = await this.runComplianceScan(args);
236
+ break;
225
237
  case 'snow_audit_trail__analysis':
226
- return await this.auditTrailAnalysis(args);
238
+ result = await this.auditTrailAnalysis(args);
239
+ break;
227
240
  case 'snow_security_risk_assessment':
228
- return await this.securityRiskAssessment(args);
241
+ result = await this.securityRiskAssessment(args);
242
+ break;
229
243
  default:
230
244
  throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
231
245
  }
246
+ // Complete operation with token tracking
247
+ this.logger.operationComplete(name, result);
248
+ return result;
232
249
  }
233
250
  catch (error) {
234
251
  this.logger.error(`Error in ${request.params.name}:`, error);
@@ -266,6 +283,7 @@ class ServiceNowSecurityComplianceMCP {
266
283
  ];
267
284
  for (const tableName of possibleTables) {
268
285
  try {
286
+ this.logger.trackAPICall('CREATE', tableName, 1);
269
287
  response = await this.client.createRecord(tableName, policyData);
270
288
  if (response.success) {
271
289
  this.logger.info(`Security policy created in table: ${tableName}`);
@@ -636,6 +654,7 @@ class ServiceNowSecurityComplianceMCP {
636
654
  const frameworks = [];
637
655
  // Discover Security Frameworks
638
656
  if (type === 'all' || type === 'security') {
657
+ this.logger.trackAPICall('SEARCH', 'sys_security_framework', 50);
639
658
  const securityFrameworks = await this.client.searchRecords('sys_security_framework', '', 50);
640
659
  if (securityFrameworks.success) {
641
660
  frameworks.push({
@@ -651,6 +670,7 @@ class ServiceNowSecurityComplianceMCP {
651
670
  }
652
671
  // Discover Compliance Frameworks
653
672
  if (type === 'all' || type === 'compliance') {
673
+ this.logger.trackAPICall('SEARCH', 'sys_compliance_framework', 50);
654
674
  const complianceFrameworks = await this.client.searchRecords('sys_compliance_framework', '', 50);
655
675
  if (complianceFrameworks.success) {
656
676
  frameworks.push({
@@ -689,6 +709,7 @@ class ServiceNowSecurityComplianceMCP {
689
709
  if (args?.active !== undefined) {
690
710
  query += query ? `^active=${args.active}` : `active=${args.active}`;
691
711
  }
712
+ this.logger.trackAPICall('SEARCH', 'sys_security_policy', 50);
692
713
  const policies = await this.client.searchRecords('sys_security_policy', query, 50);
693
714
  if (!policies.success) {
694
715
  throw new Error('Failed to discover security policies');
@@ -764,6 +785,7 @@ class ServiceNowSecurityComplianceMCP {
764
785
  if (args?.table) {
765
786
  query += query ? `^table=${args.table}` : `table=${args.table}`;
766
787
  }
788
+ this.logger.trackAPICall('SEARCH', 'sys_audit', 100);
767
789
  const auditRecords = await this.client.searchRecords('sys_audit', query, 100);
768
790
  if (!auditRecords.success) {
769
791
  throw new Error('Failed to retrieve audit records');
@@ -12,6 +12,7 @@ export declare class ServiceNowSystemPropertiesMCP {
12
12
  private server;
13
13
  private client;
14
14
  private oauth;
15
+ private logger;
15
16
  private propertyCache;
16
17
  constructor();
17
18
  private setupHandlers;