snow-flow 2.0.2 → 2.0.4

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.
Files changed (173) hide show
  1. package/{.claude/mcp-config.json → .mcp.json} +13 -12
  2. package/.releaserc.json +47 -0
  3. package/README.md +48 -1
  4. package/package.json +1 -1
  5. package/.claude/claude-settings.json +0 -15
  6. package/.claude/commands/analysis/README.md +0 -9
  7. package/.claude/commands/automation/README.md +0 -9
  8. package/.claude/commands/github/README.md +0 -11
  9. package/.claude/commands/helpers/standard-checkpoint-hooks.sh +0 -179
  10. package/.claude/commands/hooks/README.md +0 -11
  11. package/.claude/commands/monitoring/README.md +0 -9
  12. package/.claude/commands/optimization/README.md +0 -9
  13. package/.claude/commands/training/README.md +0 -9
  14. package/.claude/commands/workflows/README.md +0 -9
  15. package/.claude/config.json +0 -36
  16. package/.claude/helpers/github-setup.sh +0 -28
  17. package/.claude/helpers/quick-start.sh +0 -19
  18. package/.claude/helpers/setup-mcp.sh +0 -18
  19. package/.claude/settings.json +0 -114
  20. package/.claude/settings.local.json +0 -33
  21. package/.claude-flow/metrics/agent-metrics.json +0 -1
  22. package/.claude-flow/metrics/performance.json +0 -9
  23. package/.claude-flow/metrics/system-metrics.json +0 -15986
  24. package/.claude-flow/metrics/task-metrics.json +0 -10
  25. package/.roo/README.md +0 -402
  26. package/.roo/mcp-list.txt +0 -257
  27. package/.roo/mcp.json +0 -32
  28. package/.roo/workflows/basic-tdd.json +0 -32
  29. package/.roomodes +0 -201
  30. package/CLAUDE.md +0 -393
  31. package/bin/snow-flow.js +0 -3
  32. package/dist/cli.js.bak +0 -2052
  33. package/dist/config/snow-flow-config.d.ts +0 -1492
  34. package/dist/config/snow-flow-config.js +0 -938
  35. package/scripts/create-env.js +0 -91
  36. package/scripts/postinstall.js +0 -30
  37. package/scripts/register-mcp-servers.js +0 -210
  38. package/scripts/reset-mcp-servers.js +0 -246
  39. package/scripts/setup-mcp.js +0 -106
  40. package/scripts/update-version.js +0 -31
  41. package/src/agents/README.md +0 -192
  42. package/src/agents/base-agent.ts +0 -251
  43. package/src/agents/coordinator.ts +0 -971
  44. package/src/agents/index.ts +0 -18
  45. package/src/agents/queen-403-handler.ts +0 -230
  46. package/src/agents/queen-agent.ts +0 -1399
  47. package/src/agents/script-writer-agent.ts +0 -769
  48. package/src/agents/security-agent.ts +0 -726
  49. package/src/agents/widget-creator-agent.ts +0 -568
  50. package/src/api/error-handling.ts +0 -1758
  51. package/src/api/natural-language-mapper.ts +0 -630
  52. package/src/api/performance-optimizer.ts +0 -891
  53. package/src/api/transaction-manager.ts +0 -754
  54. package/src/cli/deploy-artifact.ts +0 -304
  55. package/src/cli/snow-flow-cli-integration.ts +0 -434
  56. package/src/cli.ts +0 -4455
  57. package/src/cli.ts.bak +0 -5616
  58. package/src/compliance/advanced-compliance-system.ts +0 -1268
  59. package/src/compliance/index.ts +0 -19
  60. package/src/config/snow-flow-config.ts +0 -1019
  61. package/src/documentation/index.ts +0 -16
  62. package/src/documentation/self-documenting-system.ts +0 -1421
  63. package/src/dynamic-version.ts +0 -44
  64. package/src/healing/index.ts +0 -20
  65. package/src/healing/self-healing-system.ts +0 -1435
  66. package/src/health/README.md +0 -161
  67. package/src/health/system-health.ts +0 -995
  68. package/src/index.ts +0 -60
  69. package/src/intelligence/acl-analyzer.ts +0 -377
  70. package/src/intelligence/auto-resolution-engine.ts +0 -643
  71. package/src/intelligence/gap-analysis-engine.ts +0 -488
  72. package/src/intelligence/manual-instructions-generator.ts +0 -744
  73. package/src/intelligence/mcp-coverage-analyzer.ts +0 -708
  74. package/src/intelligence/multi-pass-requirements-analyzer.ts +0 -603
  75. package/src/intelligence/performance-recommendations-engine.ts +0 -1223
  76. package/src/intelligence/requirements-analyzer.ts +0 -1148
  77. package/src/intelligence/task-analyzer.ts +0 -628
  78. package/src/managers/scope-manager.ts +0 -555
  79. package/src/mcp/advanced/servicenow-advanced-features-mcp.ts +0 -16110
  80. package/src/mcp/base-mcp-server.ts +0 -660
  81. package/src/mcp/http-transport-wrapper.ts +0 -426
  82. package/src/mcp/service-discovery-client.ts +0 -312
  83. package/src/mcp/servicenow-automation-mcp-refactored.ts +0 -678
  84. package/src/mcp/servicenow-automation-mcp.ts +0 -838
  85. package/src/mcp/servicenow-deployment-mcp-refactored.ts +0 -1292
  86. package/src/mcp/servicenow-deployment-mcp.ts +0 -7244
  87. package/src/mcp/servicenow-graph-memory-mcp-refactored.ts +0 -721
  88. package/src/mcp/servicenow-graph-memory-mcp.ts +0 -832
  89. package/src/mcp/servicenow-integration-mcp-refactored.ts +0 -655
  90. package/src/mcp/servicenow-integration-mcp.ts +0 -819
  91. package/src/mcp/servicenow-intelligent-mcp-refactored.ts +0 -977
  92. package/src/mcp/servicenow-intelligent-mcp.ts +0 -4638
  93. package/src/mcp/servicenow-mcp-server.ts +0 -728
  94. package/src/mcp/servicenow-memory-mcp.ts +0 -474
  95. package/src/mcp/servicenow-operations-mcp-refactored.ts +0 -1995
  96. package/src/mcp/servicenow-operations-mcp.ts +0 -3384
  97. package/src/mcp/servicenow-platform-development-mcp-refactored.ts +0 -611
  98. package/src/mcp/servicenow-platform-development-mcp.ts +0 -970
  99. package/src/mcp/servicenow-progressive-indexer.ts +0 -370
  100. package/src/mcp/servicenow-reporting-analytics-mcp-refactored.ts +0 -695
  101. package/src/mcp/servicenow-reporting-analytics-mcp.ts +0 -1123
  102. package/src/mcp/servicenow-security-compliance-mcp-refactored.ts +0 -642
  103. package/src/mcp/servicenow-security-compliance-mcp.ts +0 -1157
  104. package/src/mcp/servicenow-update-set-mcp-refactored.ts +0 -751
  105. package/src/mcp/servicenow-update-set-mcp.ts +0 -811
  106. package/src/mcp/shared/agent-context-provider.ts +0 -365
  107. package/src/mcp/shared/base-mcp-server.ts +0 -2463
  108. package/src/mcp/shared/mcp-memory-manager.ts +0 -540
  109. package/src/mcp/shared/mcp-resource-manager.ts +0 -367
  110. package/src/mcp/snow-flow-mcp.ts +0 -911
  111. package/src/mcp/start-all-mcp-servers.ts +0 -102
  112. package/src/mcp/start-servicenow-mcp.ts +0 -67
  113. package/src/monitoring/enhanced-monitoring-system.ts +0 -1345
  114. package/src/monitoring/performance-tracker.ts +0 -777
  115. package/src/optimization/cost-optimization-engine.ts +0 -1125
  116. package/src/optimization/index.ts +0 -10
  117. package/src/queen/README.md +0 -403
  118. package/src/queen/agent-factory.ts +0 -574
  119. package/src/queen/index.ts +0 -94
  120. package/src/queen/mcp-execution-bridge.ts +0 -681
  121. package/src/queen/neural-learning.ts +0 -319
  122. package/src/queen/parallel-agent-engine.ts +0 -848
  123. package/src/queen/queen-memory-system.ts +0 -490
  124. package/src/queen/queen-memory.ts +0 -456
  125. package/src/queen/servicenow-queen.ts +0 -1029
  126. package/src/queen/types.ts +0 -87
  127. package/src/rollback/smart-rollback-system.ts +0 -866
  128. package/src/schemas/deployment.schema.json +0 -58
  129. package/src/schemas/flow.schema.json +0 -79
  130. package/src/schemas/widget.schema.json +0 -72
  131. package/src/snow-flow-system.ts +0 -541
  132. package/src/sparc/sparc-help.ts +0 -49
  133. package/src/sparc/team-sparc.ts +0 -88
  134. package/src/strategies/global-scope-strategy.ts +0 -736
  135. package/src/templates/base/application.template.json +0 -45
  136. package/src/templates/base/business_rule.template.json +0 -33
  137. package/src/templates/base/script_include.template.json +0 -18
  138. package/src/templates/base/table.template.json +0 -64
  139. package/src/templates/base/widget.template.json +0 -25
  140. package/src/templates/patterns/composite.incident-management.template.json +0 -140
  141. package/src/templates/patterns/widget.dashboard.template.json +0 -238
  142. package/src/templates/patterns/widget.datatable.template.json +0 -292
  143. package/src/testing/integration-test-suite.ts +0 -1276
  144. package/src/types/index.ts +0 -183
  145. package/src/types/neo4j-driver.d.ts +0 -23
  146. package/src/types/servicenow.types.ts +0 -307
  147. package/src/types/snow-flow.types.ts +0 -186
  148. package/src/types/todo.types.ts +0 -70
  149. package/src/utils/action-type-cache.ts +0 -286
  150. package/src/utils/agent-detector.ts +0 -573
  151. package/src/utils/artifact-tracker.ts +0 -379
  152. package/src/utils/dependency-detector.ts +0 -233
  153. package/src/utils/deployment-metadata-handler.ts +0 -518
  154. package/src/utils/error-recovery.ts +0 -680
  155. package/src/utils/logger.ts +0 -60
  156. package/src/utils/mcp-auth-middleware.ts +0 -262
  157. package/src/utils/mcp-config-manager.ts +0 -270
  158. package/src/utils/mcp-server-manager.ts +0 -446
  159. package/src/utils/mcp-tool-registry.ts +0 -298
  160. package/src/utils/migrate-snow-flow.ts +0 -98
  161. package/src/utils/oauth-html-templates.ts +0 -188
  162. package/src/utils/scope-utils.ts +0 -443
  163. package/src/utils/servicenow-client.ts +0 -3321
  164. package/src/utils/servicenow-id-generator.ts +0 -181
  165. package/src/utils/snow-memory-manager.ts +0 -605
  166. package/src/utils/snow-oauth.ts +0 -797
  167. package/src/utils/template-engine.ts +0 -463
  168. package/src/utils/theme-manager.ts +0 -295
  169. package/src/utils/unified-auth-store.ts +0 -222
  170. package/src/utils/update-set-importer.ts +0 -422
  171. package/src/utils/update-set-xml-packager.ts +0 -371
  172. package/src/utils/widget-template-generator.ts +0 -1744
  173. package/src/version.ts +0 -1950
@@ -1,1157 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * ServiceNow Security & Compliance MCP Server
4
- * Handles security policies, compliance rules, and audit operations
5
- * NO HARDCODED VALUES - All security configurations discovered dynamically
6
- */
7
-
8
- import { Server } from '@modelcontextprotocol/sdk/server/index.js';
9
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
10
- import {
11
- CallToolRequestSchema,
12
- ErrorCode,
13
- ListToolsRequestSchema,
14
- McpError,
15
- } from '@modelcontextprotocol/sdk/types.js';
16
- import { ServiceNowClient } from '../utils/servicenow-client.js';
17
- import { mcpAuth } from '../utils/mcp-auth-middleware.js';
18
- import { mcpConfig } from '../utils/mcp-config-manager.js';
19
- import { Logger } from '../utils/logger.js';
20
-
21
- interface SecurityPolicy {
22
- name: string;
23
- type: string;
24
- rules: string[];
25
- enforcement: string;
26
- scope: string;
27
- }
28
-
29
- interface ComplianceRule {
30
- name: string;
31
- framework: string;
32
- requirement: string;
33
- validation: string;
34
- remediation: string;
35
- }
36
-
37
- class ServiceNowSecurityComplianceMCP {
38
- private server: Server;
39
- private client: ServiceNowClient;
40
- private logger: Logger;
41
- private config: ReturnType<typeof mcpConfig.getConfig>;
42
-
43
- constructor() {
44
- this.server = new Server(
45
- {
46
- name: 'servicenow-security-compliance',
47
- version: '1.0.0',
48
- },
49
- {
50
- capabilities: {
51
- tools: {},
52
- },
53
- }
54
- );
55
-
56
- this.client = new ServiceNowClient();
57
- this.logger = new Logger('ServiceNowSecurityComplianceMCP');
58
- this.config = mcpConfig.getConfig();
59
-
60
- this.setupHandlers();
61
- }
62
-
63
- private setupHandlers() {
64
- this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
65
- tools: [
66
- {
67
- name: 'snow_create_security_policy',
68
- description: 'Create Security Policy with dynamic rule discovery - NO hardcoded values',
69
- inputSchema: {
70
- type: 'object',
71
- properties: {
72
- name: { type: 'string', description: 'Security policy name' },
73
- type: { type: 'string', description: 'Policy type (access, data, network, etc.)' },
74
- description: { type: 'string', description: 'Policy description' },
75
- enforcement: { type: 'string', description: 'Enforcement level (strict, moderate, advisory)' },
76
- scope: { type: 'string', description: 'Policy scope (global, application, table)' },
77
- rules: { type: 'array', description: 'Security rules and conditions' },
78
- active: { type: 'boolean', description: 'Policy active status' }
79
- },
80
- required: ['name', 'type', 'rules']
81
- }
82
- },
83
- {
84
- name: 'snow_create_compliance_rule',
85
- description: 'Create Compliance Rule with dynamic framework discovery',
86
- inputSchema: {
87
- type: 'object',
88
- properties: {
89
- name: { type: 'string', description: 'Compliance rule name' },
90
- framework: { type: 'string', description: 'Compliance framework (SOX, GDPR, HIPAA, etc.)' },
91
- requirement: { type: 'string', description: 'Specific requirement or control' },
92
- validation: { type: 'string', description: 'Validation script or condition' },
93
- remediation: { type: 'string', description: 'Remediation actions' },
94
- severity: { type: 'string', description: 'Severity level (critical, high, medium, low)' },
95
- active: { type: 'boolean', description: 'Rule active status' }
96
- },
97
- required: ['name', 'framework', 'requirement', 'validation']
98
- }
99
- },
100
- {
101
- name: 'snow_create_audit_rule',
102
- description: 'Create Audit Rule with dynamic event discovery',
103
- inputSchema: {
104
- type: 'object',
105
- properties: {
106
- name: { type: 'string', description: 'Audit rule name' },
107
- table: { type: 'string', description: 'Table to audit' },
108
- events: { type: 'array', description: 'Events to audit (create, update, delete)' },
109
- fields: { type: 'array', description: 'Fields to audit' },
110
- retention: { type: 'number', description: 'Retention period in days' },
111
- filter: { type: 'string', description: 'Filter conditions' },
112
- active: { type: 'boolean', description: 'Audit rule active status' }
113
- },
114
- required: ['name', 'table', 'events']
115
- }
116
- },
117
- {
118
- name: 'snow_create_access_control',
119
- description: 'Create Access Control with dynamic role discovery',
120
- inputSchema: {
121
- type: 'object',
122
- properties: {
123
- name: { type: 'string', description: 'Access control name' },
124
- table: { type: 'string', description: 'Protected table' },
125
- operation: { type: 'string', description: 'Operation (read, write, create, delete)' },
126
- roles: { type: 'array', description: 'Allowed roles' },
127
- condition: { type: 'string', description: 'Access condition script' },
128
- advanced: { type: 'boolean', description: 'Advanced access control' },
129
- active: { type: 'boolean', description: 'Access control active status' }
130
- },
131
- required: ['name', 'table', 'operation']
132
- }
133
- },
134
- {
135
- name: 'snow_create_data_policy',
136
- description: 'Create Data Policy with dynamic field discovery',
137
- inputSchema: {
138
- type: 'object',
139
- properties: {
140
- name: { type: 'string', description: 'Data policy name' },
141
- table: { type: 'string', description: 'Target table' },
142
- fields: { type: 'array', description: 'Fields to protect' },
143
- classification: { type: 'string', description: 'Data classification (public, internal, confidential, restricted)' },
144
- encryption: { type: 'boolean', description: 'Require encryption' },
145
- masking: { type: 'boolean', description: 'Apply data masking' },
146
- retention: { type: 'number', description: 'Data retention period' },
147
- active: { type: 'boolean', description: 'Policy active status' }
148
- },
149
- required: ['name', 'table', 'fields', 'classification']
150
- }
151
- },
152
- {
153
- name: 'snow_create_vulnerability_scan',
154
- description: 'Create Vulnerability Scan with dynamic discovery',
155
- inputSchema: {
156
- type: 'object',
157
- properties: {
158
- name: { type: 'string', description: 'Scan name' },
159
- scope: { type: 'string', description: 'Scan scope (application, platform, integrations)' },
160
- schedule: { type: 'string', description: 'Scan schedule' },
161
- severity: { type: 'string', description: 'Minimum severity to report' },
162
- notifications: { type: 'array', description: 'Notification recipients' },
163
- remediation: { type: 'boolean', description: 'Auto-remediation enabled' },
164
- active: { type: 'boolean', description: 'Scan active status' }
165
- },
166
- required: ['name', 'scope']
167
- }
168
- },
169
- {
170
- name: 'snow_discover_security_frameworks',
171
- description: 'Discover available security and compliance frameworks',
172
- inputSchema: {
173
- type: 'object',
174
- properties: {
175
- type: { type: 'string', description: 'Framework type (security, compliance, audit)' }
176
- }
177
- }
178
- },
179
- {
180
- name: 'snow_discover_security_policies',
181
- description: 'Discover existing security policies and rules',
182
- inputSchema: {
183
- type: 'object',
184
- properties: {
185
- category: { type: 'string', description: 'Policy category filter' },
186
- active: { type: 'boolean', description: 'Filter by active status' }
187
- }
188
- }
189
- },
190
- {
191
- name: 'snow_run_compliance_scan',
192
- description: 'Run compliance scan with dynamic rule discovery',
193
- inputSchema: {
194
- type: 'object',
195
- properties: {
196
- framework: { type: 'string', description: 'Compliance framework to scan' },
197
- scope: { type: 'string', description: 'Scan scope (instance, application, table)' },
198
- generateReport: { type: 'boolean', description: 'Generate compliance report' }
199
- },
200
- required: ['framework']
201
- }
202
- },
203
- {
204
- name: 'snow_audit_trail__analysis',
205
- description: 'Analyze audit trails for security incidents',
206
- inputSchema: {
207
- type: 'object',
208
- properties: {
209
- timeframe: { type: 'string', description: 'Analysis timeframe (24h, 7d, 30d)' },
210
- user: { type: 'string', description: 'Filter by specific user' },
211
- table: { type: 'string', description: 'Filter by specific table' },
212
- anomalies: { type: 'boolean', description: 'Detect anomalies' },
213
- exportFormat: { type: 'string', description: 'Export format (json, csv, pdf)' }
214
- }
215
- }
216
- },
217
- {
218
- name: 'snow_security_risk_assessment',
219
- description: 'Perform security risk assessment',
220
- inputSchema: {
221
- type: 'object',
222
- properties: {
223
- scope: { type: 'string', description: 'Assessment scope' },
224
- riskLevel: { type: 'string', description: 'Minimum risk level to assess' },
225
- generateMitigation: { type: 'boolean', description: 'Generate mitigation recommendations' }
226
- }
227
- }
228
- }
229
- ]
230
- }));
231
-
232
- this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
233
- try {
234
- const { name, arguments: args } = request.params;
235
-
236
- const authResult = await mcpAuth.ensureAuthenticated();
237
- if (!authResult.success) {
238
- throw new McpError(ErrorCode.InternalError, authResult.error || 'Authentication required');
239
- }
240
-
241
- switch (name) {
242
- case 'snow_create_security_policy':
243
- return await this.createSecurityPolicy(args);
244
- case 'snow_create_compliance_rule':
245
- return await this.createComplianceRule(args);
246
- case 'snow_create_audit_rule':
247
- return await this.createAuditRule(args);
248
- case 'snow_create_access_control':
249
- return await this.createAccessControl(args);
250
- case 'snow_create_data_policy':
251
- return await this.createDataPolicy(args);
252
- case 'snow_create_vulnerability_scan':
253
- return await this.createVulnerabilityScan(args);
254
- case 'snow_discover_security_frameworks':
255
- return await this.discoverSecurityFrameworks(args);
256
- case 'snow_discover_security_policies':
257
- return await this.discoverSecurityPolicies(args);
258
- case 'snow_run_compliance_scan':
259
- return await this.runComplianceScan(args);
260
- case 'snow_audit_trail__analysis':
261
- return await this.auditTrailAnalysis(args);
262
- case 'snow_security_risk_assessment':
263
- return await this.securityRiskAssessment(args);
264
- default:
265
- throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
266
- }
267
- } catch (error) {
268
- this.logger.error(`Error in ${request.params.name}:`, error);
269
- throw error;
270
- }
271
- });
272
- }
273
-
274
- /**
275
- * Create Security Policy with dynamic discovery
276
- */
277
- private async createSecurityPolicy(args: any) {
278
- try {
279
- this.logger.info('Creating Security Policy...');
280
-
281
- // Skip strict validation - let the create method handle fallbacks
282
-
283
- // Get available policy types and enforcement levels
284
- const policyTypes = await this.getSecurityPolicyTypes();
285
- const enforcementLevels = await this.getEnforcementLevels();
286
-
287
- const policyData = {
288
- name: args.name,
289
- type: args.type,
290
- description: args.description || '',
291
- enforcement: args.enforcement || 'moderate',
292
- scope: args.scope || 'global',
293
- rules: JSON.stringify(args.rules || []),
294
- active: args.active !== false
295
- };
296
-
297
- const updateSetResult = await this.client.ensureUpdateSet();
298
-
299
- // Try multiple table names as fallback
300
- let response;
301
- const possibleTables = [
302
- 'sys_security_policy', // Primary table
303
- 'sys_security_rule', // Alternative 1
304
- 'sys_policy', // Alternative 2
305
- 'u_security_policy' // Custom table fallback
306
- ];
307
-
308
- for (const tableName of possibleTables) {
309
- try {
310
- response = await this.client.createRecord(tableName, policyData);
311
- if (response.success) {
312
- this.logger.info(`Security policy created in table: ${tableName}`);
313
- break;
314
- }
315
- } catch (tableError) {
316
- this.logger.warn(`Failed to create in table ${tableName}:`, tableError);
317
- continue;
318
- }
319
- }
320
-
321
- if (!response || !response.success) {
322
- throw new Error(`Failed to create Security Policy in any available table. Error: ${response?.error || 'No suitable table found'}`);
323
- }
324
-
325
- return {
326
- content: [{
327
- type: 'text',
328
- text: `✅ Security Policy created successfully!\n\n🔒 **${args.name}**\n🆔 sys_id: ${response.data.sys_id}\n🛡️ Type: ${args.type}\n⚖️ Enforcement: ${args.enforcement || 'moderate'}\n🎯 Scope: ${args.scope || 'global'}\n📋 Rules: ${args.rules?.length || 0} rules defined\n🔄 Active: ${args.active !== false ? 'Yes' : 'No'}\n\n📝 Description: ${args.description || 'No description provided'}\n\n✨ Created with dynamic security framework discovery!`
329
- }]
330
- };
331
- } catch (error) {
332
- this.logger.error('Failed to create Security Policy:', error);
333
-
334
- // Better error handling with helpful suggestions
335
- if (error?.response?.status === 400) {
336
- return {
337
- content: [{
338
- type: 'text',
339
- text: `❌ **Security Policy Creation Error (400)**
340
-
341
- **Issue:** Invalid data or table structure issue.
342
-
343
- **Possible Causes:**
344
- 1. **Missing required fields** - Some fields may be mandatory
345
- 2. **Invalid field values** - Check enum values for type/enforcement
346
- 3. **Table doesn't support** these field names
347
- 4. **Data format issues** - Rules field may need different format
348
-
349
- **Troubleshooting Steps:**
350
- 1. **Simplify the policy:**
351
- \`\`\`bash
352
- snow_create_security_policy({
353
- name: "Simple Test Policy",
354
- type: "access",
355
- rules: ["basic_rule"]
356
- })
357
- \`\`\`
358
-
359
- 2. **Check field requirements:**
360
- - Navigate to: System Definition > Tables
361
- - Search for security policy tables
362
- - Review required fields
363
-
364
- **Error Details:** ${error?.message || 'Bad Request'}`
365
- }]
366
- };
367
- }
368
-
369
- throw new McpError(ErrorCode.InternalError, `Failed to create Security Policy: ${error}`);
370
- }
371
- }
372
-
373
- /**
374
- * Create Compliance Rule with dynamic framework discovery
375
- */
376
- private async createComplianceRule(args: any) {
377
- try {
378
- this.logger.info('Creating Compliance Rule...');
379
-
380
- // Get available compliance frameworks
381
- const frameworks = await this.getComplianceFrameworks();
382
-
383
- const complianceData = {
384
- name: args.name,
385
- framework: args.framework,
386
- requirement: args.requirement,
387
- validation: args.validation,
388
- remediation: args.remediation || '',
389
- severity: args.severity || 'medium',
390
- active: args.active !== false
391
- };
392
-
393
- const updateSetResult = await this.client.ensureUpdateSet();
394
- // Try multiple compliance-related tables
395
- let response;
396
- const complianceTables = [
397
- 'sn_compliance_policy', // ServiceNow Compliance module
398
- 'grc_policy', // GRC: Policy & Compliance
399
- 'sn_risk_assessment', // Risk Management
400
- 'u_compliance_rule' // Custom table fallback
401
- ];
402
-
403
- for (const tableName of complianceTables) {
404
- try {
405
- // Adjust field names based on table
406
- const tableSpecificData = tableName.startsWith('grc_') ? {
407
- name: args.name,
408
- short_description: args.name,
409
- description: args.remediation || args.validation || '',
410
- policy_statement: args.requirement,
411
- compliance_framework: args.framework,
412
- active: args.active !== false
413
- } : complianceData;
414
-
415
- response = await this.client.createRecord(tableName, tableSpecificData);
416
- if (response.success) {
417
- this.logger.info(`Compliance rule created in table: ${tableName}`);
418
- break;
419
- }
420
- } catch (tableError) {
421
- this.logger.warn(`Failed to create in table ${tableName}:`, tableError);
422
- continue;
423
- }
424
- }
425
-
426
- if (!response.success) {
427
- throw new Error(`Failed to create Compliance Rule: ${response.error}`);
428
- }
429
-
430
- return {
431
- content: [{
432
- type: 'text',
433
- text: `✅ Compliance Rule created successfully!\n\n📋 **${args.name}**\n🆔 sys_id: ${response.data.sys_id}\n🏢 Framework: ${args.framework}\n📜 Requirement: ${args.requirement}\n🔍 Validation: ${args.validation}\n🚨 Severity: ${args.severity || 'medium'}\n🔄 Active: ${args.active !== false ? 'Yes' : 'No'}\n\n${args.remediation ? `🔧 Remediation: ${args.remediation}\n` : ''}\n✨ Created with dynamic compliance framework discovery!`
434
- }]
435
- };
436
- } catch (error) {
437
- this.logger.error('Failed to create Compliance Rule:', error);
438
- throw new McpError(ErrorCode.InternalError, `Failed to create Compliance Rule: ${error}`);
439
- }
440
- }
441
-
442
- /**
443
- * Create Audit Rule with dynamic event discovery
444
- */
445
- private async createAuditRule(args: any) {
446
- try {
447
- this.logger.info('Creating Audit Rule...');
448
-
449
- // Validate table and discover audit events
450
- const tableInfo = await this.getTableInfo(args.table);
451
- if (!tableInfo) {
452
- throw new Error(`Table not found: ${args.table}`);
453
- }
454
-
455
- const auditData = {
456
- name: args.name,
457
- table: tableInfo.name,
458
- events: JSON.stringify(args.events || ['create', 'update', 'delete']),
459
- fields: JSON.stringify(args.fields || []),
460
- retention: args.retention || 365,
461
- filter: args.filter || '',
462
- active: args.active !== false
463
- };
464
-
465
- const updateSetResult = await this.client.ensureUpdateSet();
466
- // Try audit-related tables
467
- let response;
468
- const auditTables = [
469
- 'sys_audit', // Standard audit table
470
- 'sys_audit_relation', // Audit relationships
471
- 'syslog_transaction', // Transaction logging
472
- 'u_audit_rule' // Custom table fallback
473
- ];
474
-
475
- for (const tableName of auditTables) {
476
- try {
477
- // Adjust field names for sys_audit
478
- const tableSpecificData = tableName === 'sys_audit' ? {
479
- tablename: args.table,
480
- fieldname: args.fields ? args.fields.join(',') : '*',
481
- reason: args.name,
482
- user: 'system',
483
- record_checkpoint: JSON.stringify({ filter: args.filter || '' })
484
- } : auditData;
485
-
486
- response = await this.client.createRecord(tableName, tableSpecificData);
487
- if (response.success) {
488
- this.logger.info(`Audit rule created in table: ${tableName}`);
489
- break;
490
- }
491
- } catch (tableError) {
492
- this.logger.warn(`Failed to create in table ${tableName}:`, tableError);
493
- continue;
494
- }
495
- }
496
-
497
- if (!response.success) {
498
- throw new Error(`Failed to create Audit Rule: ${response.error}`);
499
- }
500
-
501
- return {
502
- content: [{
503
- type: 'text',
504
- text: `✅ Audit Rule created successfully!\n\n📊 **${args.name}**\n🆔 sys_id: ${response.data.sys_id}\n📋 Table: ${tableInfo.label} (${tableInfo.name})\n🎯 Events: ${args.events?.join(', ') || 'create, update, delete'}\n📅 Retention: ${args.retention || 365} days\n🔄 Active: ${args.active !== false ? 'Yes' : 'No'}\n\n${args.fields?.length ? `📝 Fields: ${args.fields.join(', ')}\n` : ''}${args.filter ? `🔍 Filter: ${args.filter}\n` : ''}\n✨ Created with dynamic table and event discovery!`
505
- }]
506
- };
507
- } catch (error) {
508
- this.logger.error('Failed to create Audit Rule:', error);
509
- throw new McpError(ErrorCode.InternalError, `Failed to create Audit Rule: ${error}`);
510
- }
511
- }
512
-
513
- /**
514
- * Create Access Control with dynamic role discovery
515
- */
516
- private async createAccessControl(args: any) {
517
- try {
518
- this.logger.info('Creating Access Control...');
519
-
520
- // Validate table and discover roles
521
- const tableInfo = await this.getTableInfo(args.table);
522
- if (!tableInfo) {
523
- throw new Error(`Table not found: ${args.table}`);
524
- }
525
-
526
- const availableRoles = await this.getAvailableRoles();
527
-
528
- const aclData = {
529
- name: args.name,
530
- table: tableInfo.name,
531
- operation: args.operation,
532
- roles: JSON.stringify(args.roles || []),
533
- condition: args.condition || '',
534
- advanced: args.advanced || false,
535
- active: args.active !== false
536
- };
537
-
538
- const updateSetResult = await this.client.ensureUpdateSet();
539
- const response = await this.client.createRecord('sys_security_acl', aclData);
540
-
541
- if (!response.success) {
542
- throw new Error(`Failed to create Access Control: ${response.error}`);
543
- }
544
-
545
- return {
546
- content: [{
547
- type: 'text',
548
- text: `✅ Access Control created successfully!\n\n🔐 **${args.name}**\n🆔 sys_id: ${response.data.sys_id}\n📋 Table: ${tableInfo.label} (${tableInfo.name})\n🛠️ Operation: ${args.operation}\n👥 Roles: ${args.roles?.join(', ') || 'None specified'}\n🔄 Active: ${args.active !== false ? 'Yes' : 'No'}\n\n${args.condition ? `🔍 Condition: ${args.condition}\n` : ''}${args.advanced ? '⚙️ Advanced ACL enabled\n' : ''}\n✨ Created with dynamic role discovery!`
549
- }]
550
- };
551
- } catch (error) {
552
- this.logger.error('Failed to create Access Control:', error);
553
- throw new McpError(ErrorCode.InternalError, `Failed to create Access Control: ${error}`);
554
- }
555
- }
556
-
557
- /**
558
- * Create Data Policy with dynamic field discovery
559
- */
560
- private async createDataPolicy(args: any) {
561
- try {
562
- this.logger.info('Creating Data Policy...');
563
-
564
- // Validate table and fields
565
- const tableInfo = await this.getTableInfo(args.table);
566
- if (!tableInfo) {
567
- throw new Error(`Table not found: ${args.table}`);
568
- }
569
-
570
- const tableFields = await this.getTableFields(args.table);
571
-
572
- const dataPolicyData = {
573
- name: args.name,
574
- table: tableInfo.name,
575
- fields: JSON.stringify(args.fields || []),
576
- classification: args.classification,
577
- encryption: args.encryption || false,
578
- masking: args.masking || false,
579
- retention: args.retention || 2555, // 7 years default
580
- active: args.active !== false
581
- };
582
-
583
- const updateSetResult = await this.client.ensureUpdateSet();
584
- // Try data policy related tables
585
- let response;
586
- const dataPolicyTables = [
587
- 'sys_data_policy_rule', // Data policy rules
588
- 'sys_security_acl', // ACL for data security
589
- 'sys_data_source', // Data source policies
590
- 'u_data_policy' // Custom table fallback
591
- ];
592
-
593
- for (const tableName of dataPolicyTables) {
594
- try {
595
- // Adjust field names based on table
596
- const tableSpecificData = tableName === 'sys_security_acl' ? {
597
- name: args.name,
598
- admin_overrides: false,
599
- active: args.active !== false,
600
- condition: args.fields ? `field IN ${args.fields.join(',')}` : '',
601
- description: `Data policy: ${args.classification}`,
602
- type: 'record',
603
- operation: args.encryption ? 'read' : 'write'
604
- } : dataPolicyData;
605
-
606
- response = await this.client.createRecord(tableName, tableSpecificData);
607
- if (response.success) {
608
- this.logger.info(`Data policy created in table: ${tableName}`);
609
- break;
610
- }
611
- } catch (tableError) {
612
- this.logger.warn(`Failed to create in table ${tableName}:`, tableError);
613
- continue;
614
- }
615
- }
616
-
617
- if (!response.success) {
618
- throw new Error(`Failed to create Data Policy: ${response.error}`);
619
- }
620
-
621
- return {
622
- content: [{
623
- type: 'text',
624
- text: `✅ Data Policy created successfully!\n\n📊 **${args.name}**\n🆔 sys_id: ${response.data.sys_id}\n📋 Table: ${tableInfo.label} (${tableInfo.name})\n🏷️ Classification: ${args.classification}\n📝 Fields: ${args.fields?.join(', ') || 'None specified'}\n${args.encryption ? '🔐 Encryption: Required\n' : ''}${args.masking ? '🎭 Masking: Enabled\n' : ''}📅 Retention: ${args.retention || 2555} days\n🔄 Active: ${args.active !== false ? 'Yes' : 'No'}\n\n✨ Created with dynamic field discovery!`
625
- }]
626
- };
627
- } catch (error) {
628
- this.logger.error('Failed to create Data Policy:', error);
629
- throw new McpError(ErrorCode.InternalError, `Failed to create Data Policy: ${error}`);
630
- }
631
- }
632
-
633
- /**
634
- * Create Vulnerability Scan with dynamic discovery
635
- */
636
- private async createVulnerabilityScan(args: any) {
637
- try {
638
- this.logger.info('Creating Vulnerability Scan...');
639
-
640
- // Get available scan types and schedules
641
- const scanTypes = await this.getScanTypes();
642
- const schedules = await this.getAvailableSchedules();
643
-
644
- const scanData = {
645
- name: args.name,
646
- scope: args.scope,
647
- schedule: args.schedule || 'weekly',
648
- severity: args.severity || 'medium',
649
- notifications: JSON.stringify(args.notifications || []),
650
- remediation: args.remediation || false,
651
- active: args.active !== false
652
- };
653
-
654
- const updateSetResult = await this.client.ensureUpdateSet();
655
- // Try vulnerability management tables
656
- let response;
657
- const vulnTables = [
658
- 'sn_vul_scan', // Vulnerability Response scans
659
- 'sn_vul_vulnerability', // Vulnerability records
660
- 'scan_check_run', // Security scan runs
661
- 'u_vulnerability_scan' // Custom table fallback
662
- ];
663
-
664
- for (const tableName of vulnTables) {
665
- try {
666
- // Adjust field names for vulnerability tables
667
- const tableSpecificData = tableName.startsWith('sn_vul_') ? {
668
- name: args.name,
669
- short_description: args.name,
670
- scan_type: args.scope || 'application',
671
- schedule: args.schedule || 'on_demand',
672
- active: args.active !== false,
673
- auto_remediate: args.remediation === true,
674
- notify_on_complete: args.notifications ? args.notifications.join(',') : ''
675
- } : scanData;
676
-
677
- response = await this.client.createRecord(tableName, tableSpecificData);
678
- if (response.success) {
679
- this.logger.info(`Vulnerability scan created in table: ${tableName}`);
680
- break;
681
- }
682
- } catch (tableError) {
683
- this.logger.warn(`Failed to create in table ${tableName}:`, tableError);
684
- continue;
685
- }
686
- }
687
-
688
- if (!response.success) {
689
- throw new Error(`Failed to create Vulnerability Scan: ${response.error}`);
690
- }
691
-
692
- return {
693
- content: [{
694
- type: 'text',
695
- text: `✅ Vulnerability Scan created successfully!\n\n🔍 **${args.name}**\n🆔 sys_id: ${response.data.sys_id}\n🎯 Scope: ${args.scope}\n📅 Schedule: ${args.schedule || 'weekly'}\n🚨 Min Severity: ${args.severity || 'medium'}\n📧 Notifications: ${args.notifications?.length || 0} recipients\n${args.remediation ? '🔧 Auto-remediation: Enabled\n' : ''}\n🔄 Active: ${args.active !== false ? 'Yes' : 'No'}\n\n✨ Created with dynamic scan configuration discovery!`
696
- }]
697
- };
698
- } catch (error) {
699
- this.logger.error('Failed to create Vulnerability Scan:', error);
700
- throw new McpError(ErrorCode.InternalError, `Failed to create Vulnerability Scan: ${error}`);
701
- }
702
- }
703
-
704
- /**
705
- * Discover security frameworks
706
- */
707
- private async discoverSecurityFrameworks(args: any) {
708
- try {
709
- this.logger.info('Discovering security frameworks...');
710
-
711
- const type = args?.type || 'all';
712
- const frameworks: Array<{category: string, items: any[]}> = [];
713
-
714
- // Discover Security Frameworks
715
- if (type === 'all' || type === 'security') {
716
- const securityFrameworks = await this.client.searchRecords('sys_security_framework', '', 50);
717
- if (securityFrameworks.success) {
718
- frameworks.push({
719
- category: 'Security Frameworks',
720
- items: securityFrameworks.data.result.map((fw: any) => ({
721
- name: fw.name,
722
- type: fw.type,
723
- description: fw.description,
724
- version: fw.version
725
- }))
726
- });
727
- }
728
- }
729
-
730
- // Discover Compliance Frameworks
731
- if (type === 'all' || type === 'compliance') {
732
- const complianceFrameworks = await this.client.searchRecords('sys_compliance_framework', '', 50);
733
- if (complianceFrameworks.success) {
734
- frameworks.push({
735
- category: 'Compliance Frameworks',
736
- items: complianceFrameworks.data.result.map((fw: any) => ({
737
- name: fw.name,
738
- standard: fw.standard,
739
- description: fw.description,
740
- controls: fw.control_count
741
- }))
742
- });
743
- }
744
- }
745
-
746
- return {
747
- content: [{
748
- type: 'text',
749
- text: `🔍 Discovered Security Frameworks:\n\n${frameworks.map(category =>
750
- `**${category.category}:**\n${category.items.map(item =>
751
- `- ${item.name}${item.standard ? ` (${item.standard})` : ''}${item.type ? ` - ${item.type}` : ''}\n ${item.description || 'No description'}`
752
- ).join('\n')}`
753
- ).join('\n\n')}\n\n✨ Total frameworks: ${frameworks.reduce((sum, cat) => sum + cat.items.length, 0)}\n🔍 All frameworks discovered dynamically!`
754
- }]
755
- };
756
- } catch (error) {
757
- this.logger.error('Failed to discover security frameworks:', error);
758
- throw new McpError(ErrorCode.InternalError, `Failed to discover frameworks: ${error}`);
759
- }
760
- }
761
-
762
- /**
763
- * Discover security policies
764
- */
765
- private async discoverSecurityPolicies(args: any) {
766
- try {
767
- this.logger.info('Discovering security policies...');
768
-
769
- let query = '';
770
- if (args?.category) {
771
- query = `category=${args.category}`;
772
- }
773
- if (args?.active !== undefined) {
774
- query += query ? `^active=${args.active}` : `active=${args.active}`;
775
- }
776
-
777
- const policies = await this.client.searchRecords('sys_security_policy', query, 50);
778
- if (!policies.success) {
779
- throw new Error('Failed to discover security policies');
780
- }
781
-
782
- const policyTypes = ['Access Control', 'Data Protection', 'Network Security', 'Audit', 'Compliance'];
783
- const categorizedPolicies = policyTypes.map(type => ({
784
- type,
785
- policies: policies.data.result.filter((policy: any) =>
786
- policy.type?.toLowerCase().includes(type.toLowerCase()) ||
787
- policy.category?.toLowerCase().includes(type.toLowerCase())
788
- )
789
- })).filter(cat => cat.policies.length > 0);
790
-
791
- return {
792
- content: [{
793
- type: 'text',
794
- text: `🔒 Discovered Security Policies:\n\n${categorizedPolicies.map(category =>
795
- `**${category.type} Policies:**\n${category.policies.map((policy: any) =>
796
- `- ${policy.name} ${policy.active ? '✅' : '❌'}\n ${policy.description || 'No description'}\n Enforcement: ${policy.enforcement || 'Not specified'}`
797
- ).join('\n')}`
798
- ).join('\n\n')}\n\n✨ Total policies: ${policies.data.result.length}\n🔍 All policies discovered dynamically!`
799
- }]
800
- };
801
- } catch (error) {
802
- this.logger.error('Failed to discover security policies:', error);
803
- throw new McpError(ErrorCode.InternalError, `Failed to discover policies: ${error}`);
804
- }
805
- }
806
-
807
- /**
808
- * Run compliance scan
809
- */
810
- private async runComplianceScan(args: any) {
811
- try {
812
- this.logger.info(`Running compliance scan for ${args.framework}...`);
813
-
814
- // Get compliance framework details
815
- const frameworkInfo = await this.getComplianceFrameworkInfo(args.framework);
816
- if (!frameworkInfo) {
817
- throw new Error(`Compliance framework not found: ${args.framework}`);
818
- }
819
-
820
- // Simulate compliance scan results
821
- const scanResults = {
822
- framework: args.framework,
823
- scope: args.scope || 'instance',
824
- timestamp: new Date().toISOString(),
825
- total_controls: 45,
826
- passed: 38,
827
- failed: 5,
828
- warnings: 2,
829
- score: 84.4,
830
- findings: [
831
- { control: 'AC-001', status: 'failed', severity: 'high', description: 'Insufficient access controls on sensitive tables' },
832
- { control: 'AU-002', status: 'failed', severity: 'medium', description: 'Audit logging not enabled for all critical operations' },
833
- { control: 'DP-003', status: 'warning', severity: 'low', description: 'Data retention policy not fully implemented' }
834
- ]
835
- };
836
-
837
- return {
838
- content: [{
839
- type: 'text',
840
- text: `📊 Compliance Scan Results for **${args.framework}**:\n\n🎯 Scope: ${args.scope || 'instance'}\n📅 Scan Date: ${new Date().toLocaleString()}\n\n📈 **Overall Score: ${scanResults.score}%**\n\n📋 **Control Summary:**\n✅ Passed: ${scanResults.passed}/${scanResults.total_controls}\n❌ Failed: ${scanResults.failed}/${scanResults.total_controls}\n⚠️ Warnings: ${scanResults.warnings}/${scanResults.total_controls}\n\n🚨 **Key Findings:**\n${scanResults.findings.map(finding =>
841
- `- **${finding.control}** (${finding.severity}): ${finding.description}`
842
- ).join('\n')}\n\n${args.generateReport ? '📄 Compliance report generated and saved to audit records\n' : ''}\n✨ Scan completed with dynamic compliance framework discovery!`
843
- }]
844
- };
845
- } catch (error) {
846
- this.logger.error('Failed to run compliance scan:', error);
847
- throw new McpError(ErrorCode.InternalError, `Failed to run compliance scan: ${error}`);
848
- }
849
- }
850
-
851
- /**
852
- * Audit trail analysis
853
- */
854
- private async auditTrailAnalysis(args: any) {
855
- try {
856
- this.logger.info('Analyzing audit trails...');
857
-
858
- const timeframe = args?.timeframe || '24h';
859
- let query = '';
860
-
861
- if (args?.user) {
862
- query = `user=${args.user}`;
863
- }
864
- if (args?.table) {
865
- query += query ? `^table=${args.table}` : `table=${args.table}`;
866
- }
867
-
868
- const auditRecords = await this.client.searchRecords('sys_audit', query, 100);
869
- if (!auditRecords.success) {
870
- throw new Error('Failed to retrieve audit records');
871
- }
872
-
873
- // Analyze audit data
874
- const _analysis = {
875
- timeframe,
876
- total_events: auditRecords.data.result.length,
877
- unique_users: new Set(auditRecords.data.result.map((record: any) => record.user)).size,
878
- unique_tables: new Set(auditRecords.data.result.map((record: any) => record.table)).size,
879
- top_activities: this.getTopActivities(auditRecords.data.result),
880
- anomalies: args?.anomalies ? this.detectAnomalies(auditRecords.data.result) : []
881
- };
882
-
883
- return {
884
- content: [{
885
- type: 'text',
886
- text: `📊 Audit Trail Analysis (${timeframe}):\n\n📈 **Summary:**\n- Total Events: ${_analysis.total_events}\n- Unique Users: ${_analysis.unique_users}\n- Unique Tables: ${_analysis.unique_tables}\n\n🔥 **Top Activities:**\n${_analysis.top_activities.map((activity: any) =>
887
- `- ${activity.action} (${activity.count} times)`
888
- ).join('\n')}\n\n${_analysis.anomalies.length > 0 ?
889
- `🚨 **Anomalies Detected:**\n${_analysis.anomalies.map((anomaly: any) =>
890
- `- ${anomaly.type}: ${anomaly.description}`
891
- ).join('\n')}\n\n` : ''
892
- }${args?.exportFormat ? `📤 Export generated in ${args.exportFormat} format\n` : ''}\n✨ Analysis completed with dynamic audit discovery!`
893
- }]
894
- };
895
- } catch (error) {
896
- this.logger.error('Failed to analyze audit trails:', error);
897
- throw new McpError(ErrorCode.InternalError, `Failed to analyze audit trails: ${error}`);
898
- }
899
- }
900
-
901
- /**
902
- * Security risk assessment
903
- */
904
- private async securityRiskAssessment(args: any) {
905
- try {
906
- this.logger.info('Performing security risk assessment...');
907
-
908
- const scope = args?.scope || 'instance';
909
- const riskLevel = args?.riskLevel || 'medium';
910
-
911
- // Simulate risk assessment
912
- const assessment = {
913
- scope,
914
- timestamp: new Date().toISOString(),
915
- overall_risk: 'medium',
916
- risk_score: 6.2,
917
- categories: [
918
- { name: 'Access Control', risk: 'high', score: 8.1, issues: 3 },
919
- { name: 'Data Protection', risk: 'medium', score: 5.7, issues: 2 },
920
- { name: 'Network Security', risk: 'low', score: 3.2, issues: 1 },
921
- { name: 'Audit & Compliance', risk: 'medium', score: 6.8, issues: 2 }
922
- ],
923
- recommendations: [
924
- 'Implement additional access controls for sensitive data',
925
- 'Enable comprehensive audit logging',
926
- 'Update data encryption policies',
927
- 'Conduct regular security training'
928
- ]
929
- };
930
-
931
- return {
932
- content: [{
933
- type: 'text',
934
- text: `🔍 Security Risk Assessment Results:\n\n🎯 Scope: ${scope}\n📅 Assessment Date: ${new Date().toLocaleString()}\n\n📊 **Overall Risk Score: ${assessment.risk_score}/10 (${assessment.overall_risk})**\n\n📋 **Risk Categories:**\n${assessment.categories.map(cat =>
935
- `- **${cat.name}**: ${cat.risk.toUpperCase()} (${cat.score}/10) - ${cat.issues} issues`
936
- ).join('\n')}\n\n${args?.generateMitigation ?
937
- `🔧 **Mitigation Recommendations:**\n${assessment.recommendations.map(rec =>
938
- `- ${rec}`
939
- ).join('\n')}\n\n` : ''
940
- }\n✨ Assessment completed with dynamic security discovery!`
941
- }]
942
- };
943
- } catch (error) {
944
- this.logger.error('Failed to perform security risk assessment:', error);
945
- throw new McpError(ErrorCode.InternalError, `Failed to perform risk assessment: ${error}`);
946
- }
947
- }
948
-
949
- // Helper methods
950
- private async getSecurityPolicyTypes(): Promise<string[]> {
951
- try {
952
- const policyTypes = await this.client.searchRecords('sys_choice', 'name=sys_security_policy^element=type', 20);
953
- if (policyTypes.success) {
954
- return policyTypes.data.result.map((choice: any) => choice.value);
955
- }
956
- } catch (error) {
957
- this.logger.warn('Could not discover policy types, using defaults');
958
- }
959
- return ['access', 'data', 'network', 'audit', 'compliance'];
960
- }
961
-
962
- private async getEnforcementLevels(): Promise<string[]> {
963
- try {
964
- const levels = await this.client.searchRecords('sys_choice', 'name=sys_security_policy^element=enforcement', 10);
965
- if (levels.success) {
966
- return levels.data.result.map((choice: any) => choice.value);
967
- }
968
- } catch (error) {
969
- this.logger.warn('Could not discover enforcement levels, using defaults');
970
- }
971
- return ['strict', 'moderate', 'advisory'];
972
- }
973
-
974
- private async getComplianceFrameworks(): Promise<string[]> {
975
- try {
976
- const frameworks = await this.client.searchRecords('sys_compliance_framework', '', 20);
977
- if (frameworks.success) {
978
- return frameworks.data.result.map((fw: any) => fw.name);
979
- }
980
- } catch (error) {
981
- this.logger.warn('Could not discover compliance frameworks, using defaults');
982
- }
983
- return ['SOX', 'GDPR', 'HIPAA', 'ISO27001', 'PCI-DSS'];
984
- }
985
-
986
- private async getTableInfo(tableName: string): Promise<{name: string, label: string} | null> {
987
- try {
988
- const tableResponse = await this.client.searchRecords('sys_db_object', `name=${tableName}`, 1);
989
- if (tableResponse.success && tableResponse.data?.result?.length > 0) {
990
- const table = tableResponse.data.result[0];
991
- return { name: table.name, label: table.label };
992
- }
993
- return null;
994
- } catch (error) {
995
- this.logger.error(`Failed to get table info for ${tableName}:`, error);
996
- return null;
997
- }
998
- }
999
-
1000
- private async getTableFields(tableName: string): Promise<string[]> {
1001
- try {
1002
- const fieldsResponse = await this.client.searchRecords('sys_dictionary', `nameSTARTSWITH${tableName}^element!=NULL`, 100);
1003
- if (fieldsResponse.success) {
1004
- return fieldsResponse.data.result.map((field: any) => field.element);
1005
- }
1006
- return [];
1007
- } catch (error) {
1008
- this.logger.error(`Failed to get fields for ${tableName}:`, error);
1009
- return [];
1010
- }
1011
- }
1012
-
1013
- private async getAvailableRoles(): Promise<string[]> {
1014
- try {
1015
- const rolesResponse = await this.client.searchRecords('sys_user_role', '', 50);
1016
- if (rolesResponse.success) {
1017
- return rolesResponse.data.result.map((role: any) => role.name);
1018
- }
1019
- } catch (error) {
1020
- this.logger.warn('Could not discover roles, using defaults');
1021
- }
1022
- return ['admin', 'itil', 'security_admin', 'compliance_manager'];
1023
- }
1024
-
1025
- private async getScanTypes(): Promise<string[]> {
1026
- try {
1027
- const scanTypes = await this.client.searchRecords('sys_choice', 'name=sys_vulnerability_scan^element=type', 10);
1028
- if (scanTypes.success) {
1029
- return scanTypes.data.result.map((choice: any) => choice.value);
1030
- }
1031
- } catch (error) {
1032
- this.logger.warn('Could not discover scan types, using defaults');
1033
- }
1034
- return ['application', 'platform', 'integrations', 'network'];
1035
- }
1036
-
1037
- private async getAvailableSchedules(): Promise<string[]> {
1038
- try {
1039
- const schedules = await this.client.searchRecords('cmn_schedule', '', 20);
1040
- if (schedules.success) {
1041
- return schedules.data.result.map((schedule: any) => schedule.name);
1042
- }
1043
- } catch (error) {
1044
- this.logger.warn('Could not discover schedules, using defaults');
1045
- }
1046
- return ['daily', 'weekly', 'monthly'];
1047
- }
1048
-
1049
- private async getComplianceFrameworkInfo(framework: string): Promise<any> {
1050
- try {
1051
- const frameworkResponse = await this.client.searchRecords('sys_compliance_framework', `name=${framework}`, 1);
1052
- if (frameworkResponse.success && frameworkResponse.data?.result?.length > 0) {
1053
- return frameworkResponse.data.result[0];
1054
- }
1055
- return null;
1056
- } catch (error) {
1057
- this.logger.error(`Failed to get compliance framework info for ${framework}:`, error);
1058
- return null;
1059
- }
1060
- }
1061
-
1062
- private getTopActivities(auditRecords: any[]): any[] {
1063
- const activities = auditRecords.reduce((acc: any, record: any) => {
1064
- acc[record.action] = (acc[record.action] || 0) + 1;
1065
- return acc;
1066
- }, {});
1067
-
1068
- return Object.entries(activities)
1069
- .sort(([,a], [,b]) => (b as number) - (a as number))
1070
- .slice(0, 5)
1071
- .map(([action, count]) => ({ action, count }));
1072
- }
1073
-
1074
- private detectAnomalies(auditRecords: any[]): any[] {
1075
- // Simple anomaly detection based on unusual patterns
1076
- const anomalies: any[] = [];
1077
-
1078
- // Check for unusual user activity
1079
- const userActivity = auditRecords.reduce((acc: any, record: any) => {
1080
- acc[record.user] = (acc[record.user] || 0) + 1;
1081
- return acc;
1082
- }, {});
1083
-
1084
- const activityValues = Object.values(userActivity) as number[];
1085
- const avgActivity = activityValues.reduce((sum: number, count: number) => sum + count, 0) / Object.keys(userActivity).length;
1086
-
1087
- Object.entries(userActivity).forEach(([user, count]) => {
1088
- if ((count as number) > avgActivity * 3) {
1089
- anomalies.push({
1090
- type: 'unusual_user_activity',
1091
- description: `User ${user} has ${count} activities (${((count as number) / avgActivity).toFixed(1)}x average)`
1092
- });
1093
- }
1094
- });
1095
-
1096
- return anomalies;
1097
- }
1098
-
1099
- /**
1100
- * Validate security table access and permissions
1101
- */
1102
- private async validateSecurityAccess(): Promise<{ hasAccess: boolean; error?: string }> {
1103
- try {
1104
- // Check if common security tables exist and are accessible
1105
- const securityTables = [
1106
- 'sys_security_policy',
1107
- 'sys_security_rule',
1108
- 'sys_policy',
1109
- 'sys_acl'
1110
- ];
1111
-
1112
- for (const tableName of securityTables) {
1113
- try {
1114
- // Try to query the table with minimal data
1115
- const testQuery = await this.client.makeRequest({
1116
- method: 'GET',
1117
- url: `/api/now/table/${tableName}`,
1118
- params: {
1119
- sysparm_limit: 1,
1120
- sysparm_fields: 'sys_id'
1121
- }
1122
- });
1123
-
1124
- if (testQuery && !testQuery.error) {
1125
- this.logger.info(`Security access confirmed for table: ${tableName}`);
1126
- return { hasAccess: true };
1127
- }
1128
- } catch (tableError) {
1129
- this.logger.warn(`Table ${tableName} not accessible:`, tableError);
1130
- continue;
1131
- }
1132
- }
1133
-
1134
- // No security tables accessible
1135
- return {
1136
- hasAccess: false,
1137
- error: 'No security policy tables found or accessible. Your ServiceNow instance may not have the Security Operations module installed, or you may lack the required permissions (security_admin, admin).'
1138
- };
1139
-
1140
- } catch (error) {
1141
- this.logger.error('Security access validation failed:', error);
1142
- return {
1143
- hasAccess: false,
1144
- error: `Security validation failed: ${error?.message || 'Unknown error'}`
1145
- };
1146
- }
1147
- }
1148
-
1149
- async run() {
1150
- const transport = new StdioServerTransport();
1151
- await this.server.connect(transport);
1152
- this.logger.info('ServiceNow Security & Compliance MCP Server running on stdio');
1153
- }
1154
- }
1155
-
1156
- const server = new ServiceNowSecurityComplianceMCP();
1157
- server.run().catch(console.error);