framework-mcp 1.0.0

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.
package/dist/index.js ADDED
@@ -0,0 +1,693 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
5
+ // Enhanced CIS Controls Framework Data with color-coded categorization
6
+ const CIS_SAFEGUARDS = {
7
+ "1.1": {
8
+ id: "1.1",
9
+ title: "Establish and Maintain a Detailed Enterprise Asset Inventory",
10
+ description: "Establish and maintain an accurate, detailed, and up-to-date inventory of all enterprise assets with the potential to store or process data",
11
+ implementationGroup: "IG1",
12
+ assetType: ["end-user devices", "network devices", "IoT devices", "servers"],
13
+ securityFunction: ["Identify"],
14
+ governanceElements: [
15
+ "establish inventory process",
16
+ "maintain inventory process",
17
+ "documented process",
18
+ "review and update bi-annually",
19
+ "enterprise asset management policy"
20
+ ],
21
+ coreRequirements: [
22
+ "accurate inventory",
23
+ "detailed inventory",
24
+ "up-to-date inventory",
25
+ "all enterprise assets",
26
+ "potential to store or process data"
27
+ ],
28
+ subTaxonomicalElements: [
29
+ "network address (if static)",
30
+ "hardware address",
31
+ "machine name",
32
+ "enterprise asset owner",
33
+ "department for each asset",
34
+ "approved to connect to network",
35
+ "end-user devices (portable and mobile)",
36
+ "network devices",
37
+ "non-computing/IoT devices",
38
+ "servers",
39
+ "physical connection",
40
+ "virtual connection",
41
+ "remote connection",
42
+ "cloud environments",
43
+ "regularly connected devices not under enterprise control"
44
+ ],
45
+ implementationSuggestions: [
46
+ "MDM type tools for mobile devices",
47
+ "enterprise and software asset management tool",
48
+ "asset discovery tools",
49
+ "DHCP logging",
50
+ "passive discovery tools"
51
+ ],
52
+ relatedSafeguards: ["1.2", "1.3", "1.4", "1.5", "2.1", "3.2", "4.1", "5.1"],
53
+ keywords: ["asset", "inventory", "device", "network", "mobile", "IoT", "server", "detailed", "accurate", "up-to-date"]
54
+ },
55
+ "5.1": {
56
+ id: "5.1",
57
+ title: "Establish and Maintain an Inventory of Accounts",
58
+ description: "Establish and maintain an inventory of all accounts managed in the enterprise",
59
+ implementationGroup: "IG1",
60
+ assetType: ["users"],
61
+ securityFunction: ["Identify"],
62
+ governanceElements: [
63
+ "establish inventory process",
64
+ "maintain inventory process",
65
+ "validate all active accounts are authorized",
66
+ "recurring schedule minimum quarterly",
67
+ "account management policy"
68
+ ],
69
+ coreRequirements: [
70
+ "inventory of all accounts",
71
+ "user accounts",
72
+ "administrator accounts",
73
+ "managed in the enterprise"
74
+ ],
75
+ subTaxonomicalElements: [
76
+ "person's name",
77
+ "username",
78
+ "start/stop dates",
79
+ "department",
80
+ "account status",
81
+ "account type",
82
+ "access rights",
83
+ "last login date"
84
+ ],
85
+ implementationSuggestions: [
86
+ "identity and access management tool",
87
+ "directory services",
88
+ "automated account provisioning",
89
+ "account lifecycle management",
90
+ "role-based access control system"
91
+ ],
92
+ relatedSafeguards: ["1.1", "2.1", "5.2", "5.3", "5.4", "5.5", "5.6", "6.1", "6.2"],
93
+ keywords: ["accounts", "inventory", "user", "administrator", "name", "username", "dates", "department", "quarterly"]
94
+ },
95
+ "6.3": {
96
+ id: "6.3",
97
+ title: "Require MFA for Externally-Exposed Applications",
98
+ description: "Require all externally-exposed enterprise or third-party applications to enforce MFA",
99
+ implementationGroup: "IG1",
100
+ assetType: ["users"],
101
+ securityFunction: ["Protect"],
102
+ governanceElements: [
103
+ "require MFA enforcement",
104
+ "policy for externally-exposed applications",
105
+ "MFA compliance verification"
106
+ ],
107
+ coreRequirements: [
108
+ "multi-factor authentication",
109
+ "all externally-exposed applications",
110
+ "enterprise applications",
111
+ "third-party applications",
112
+ "enforce MFA where supported"
113
+ ],
114
+ subTaxonomicalElements: [
115
+ "authentication factors",
116
+ "something you know (password)",
117
+ "something you have (token)",
118
+ "something you are (biometric)",
119
+ "external access points",
120
+ "application inventory",
121
+ "exposure assessment"
122
+ ],
123
+ implementationSuggestions: [
124
+ "directory service enforcement",
125
+ "SSO provider enforcement",
126
+ "multi-factor authentication tools",
127
+ "SAML integration",
128
+ "OAuth implementation",
129
+ "conditional access policies"
130
+ ],
131
+ relatedSafeguards: ["2.1", "4.1", "5.1", "6.1", "6.2"],
132
+ keywords: ["MFA", "multi-factor", "authentication", "externally-exposed", "applications", "third-party", "SSO", "directory"]
133
+ },
134
+ "7.1": {
135
+ id: "7.1",
136
+ title: "Establish and Maintain a Vulnerability Management Process",
137
+ description: "Establish and maintain a documented vulnerability management process for enterprise assets",
138
+ implementationGroup: "IG1",
139
+ assetType: ["documentation"],
140
+ securityFunction: ["Govern"],
141
+ governanceElements: [
142
+ "establish documented process",
143
+ "maintain vulnerability management process",
144
+ "review and update documentation annually",
145
+ "update when significant enterprise changes occur",
146
+ "vulnerability management policy"
147
+ ],
148
+ coreRequirements: [
149
+ "vulnerability management process",
150
+ "enterprise assets scope",
151
+ "documented procedures",
152
+ "vulnerability identification",
153
+ "vulnerability assessment"
154
+ ],
155
+ subTaxonomicalElements: [
156
+ "vulnerability scanning procedures",
157
+ "risk assessment criteria",
158
+ "remediation prioritization",
159
+ "patch management integration",
160
+ "vulnerability tracking",
161
+ "reporting requirements",
162
+ "roles and responsibilities",
163
+ "escalation procedures"
164
+ ],
165
+ implementationSuggestions: [
166
+ "vulnerability scanning tools",
167
+ "patch management systems",
168
+ "vulnerability databases",
169
+ "CVSS scoring",
170
+ "automated scanning",
171
+ "vulnerability management platforms"
172
+ ],
173
+ relatedSafeguards: ["1.1", "2.1", "7.2", "7.3", "7.4", "7.5", "7.6", "7.7"],
174
+ keywords: ["vulnerability", "management", "process", "documented", "annual", "review", "enterprise", "assets"]
175
+ },
176
+ "1.2": {
177
+ id: "1.2",
178
+ title: "Address Unauthorized Assets",
179
+ description: "Ensure that a process exists to address unauthorized assets on a weekly basis",
180
+ implementationGroup: "IG1",
181
+ assetType: ["devices"],
182
+ securityFunction: ["Respond"],
183
+ governanceElements: [
184
+ "ensure process exists",
185
+ "weekly basis requirement",
186
+ "unauthorized asset handling policy"
187
+ ],
188
+ coreRequirements: [
189
+ "address unauthorized assets",
190
+ "process to handle unauthorized devices",
191
+ "weekly execution"
192
+ ],
193
+ subTaxonomicalElements: [
194
+ "unauthorized asset detection",
195
+ "asset classification",
196
+ "response timeline",
197
+ "documentation requirements"
198
+ ],
199
+ implementationSuggestions: [
200
+ "remove asset from network",
201
+ "deny asset from connecting remotely",
202
+ "quarantine asset",
203
+ "automated response systems",
204
+ "network access control"
205
+ ],
206
+ relatedSafeguards: ["1.1", "1.3"],
207
+ keywords: ["unauthorized", "assets", "weekly", "remove", "deny", "quarantine", "process"]
208
+ }
209
+ };
210
+ class GRCAnalysisServer {
211
+ constructor() {
212
+ this.server = new Server({
213
+ name: 'framework-mcp',
214
+ version: '1.0.0',
215
+ });
216
+ this.setupToolHandlers();
217
+ }
218
+ setupToolHandlers() {
219
+ this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
220
+ tools: [
221
+ {
222
+ name: 'analyze_vendor_response',
223
+ description: 'Analyze a vendor response for a specific CIS Control safeguard against the 4 GRC attributes with detailed sub-element coverage',
224
+ inputSchema: {
225
+ type: 'object',
226
+ properties: {
227
+ vendor_name: {
228
+ type: 'string',
229
+ description: 'Name of the vendor'
230
+ },
231
+ safeguard_id: {
232
+ type: 'string',
233
+ description: 'CIS Control safeguard ID (e.g., "5.1", "1.1", "6.3")',
234
+ pattern: '^[0-9]+\\.[0-9]+$'
235
+ },
236
+ response_text: {
237
+ type: 'string',
238
+ description: 'Vendor response text to analyze'
239
+ }
240
+ },
241
+ required: ['vendor_name', 'safeguard_id', 'response_text']
242
+ }
243
+ },
244
+ {
245
+ name: 'get_safeguard_details',
246
+ description: 'Get detailed information about a CIS Control safeguard including governance requirements, core elements, and sub-taxonomical breakdown',
247
+ inputSchema: {
248
+ type: 'object',
249
+ properties: {
250
+ safeguard_id: {
251
+ type: 'string',
252
+ description: 'CIS Control safeguard ID (e.g., "5.1", "1.1")',
253
+ pattern: '^[0-9]+\\.[0-9]+$'
254
+ },
255
+ include_examples: {
256
+ type: 'boolean',
257
+ description: 'Include implementation examples and suggestions',
258
+ default: true
259
+ }
260
+ },
261
+ required: ['safeguard_id']
262
+ }
263
+ },
264
+ {
265
+ name: 'validate_coverage_claim',
266
+ description: 'Validate a vendor\'s coverage claim (FULL/PARTIAL) against specific safeguard requirements',
267
+ inputSchema: {
268
+ type: 'object',
269
+ properties: {
270
+ vendor_name: {
271
+ type: 'string',
272
+ description: 'Name of the vendor'
273
+ },
274
+ safeguard_id: {
275
+ type: 'string',
276
+ description: 'CIS Control safeguard ID',
277
+ pattern: '^[0-9]+\\.[0-9]+$'
278
+ },
279
+ coverage_claim: {
280
+ type: 'string',
281
+ enum: ['FULL', 'PARTIAL'],
282
+ description: 'Vendor\'s coverage claim'
283
+ },
284
+ response_text: {
285
+ type: 'string',
286
+ description: 'Vendor response explaining their coverage'
287
+ },
288
+ capabilities: {
289
+ type: 'array',
290
+ items: { type: 'string' },
291
+ description: 'List of vendor capabilities/attributes (Governance, Facilitates, Validates)'
292
+ }
293
+ },
294
+ required: ['vendor_name', 'safeguard_id', 'coverage_claim', 'response_text', 'capabilities']
295
+ }
296
+ },
297
+ {
298
+ name: 'list_available_safeguards',
299
+ description: 'List all available CIS Control safeguards with their categorization',
300
+ inputSchema: {
301
+ type: 'object',
302
+ properties: {
303
+ implementation_group: {
304
+ type: 'string',
305
+ enum: ['IG1', 'IG2', 'IG3'],
306
+ description: 'Filter by implementation group (optional)'
307
+ },
308
+ security_function: {
309
+ type: 'string',
310
+ enum: ['Identify', 'Protect', 'Detect', 'Respond', 'Recover', 'Govern'],
311
+ description: 'Filter by security function (optional)'
312
+ }
313
+ }
314
+ }
315
+ }
316
+ ],
317
+ }));
318
+ this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
319
+ const { name, arguments: args } = request.params;
320
+ try {
321
+ switch (name) {
322
+ case 'analyze_vendor_response':
323
+ return await this.analyzeVendorResponse(args);
324
+ case 'get_safeguard_details':
325
+ return await this.getSafeguardDetails(args);
326
+ case 'validate_coverage_claim':
327
+ return await this.validateCoverageClaim(args);
328
+ case 'list_available_safeguards':
329
+ return await this.listAvailableSafeguards(args);
330
+ default:
331
+ throw new Error(`Unknown tool: ${name}`);
332
+ }
333
+ }
334
+ catch (error) {
335
+ return {
336
+ content: [
337
+ {
338
+ type: 'text',
339
+ text: `Error: ${error instanceof Error ? error.message : String(error)}`,
340
+ },
341
+ ],
342
+ };
343
+ }
344
+ });
345
+ }
346
+ async getSafeguardDetails(args) {
347
+ const { safeguard_id, include_examples = true } = args;
348
+ const safeguard = CIS_SAFEGUARDS[safeguard_id];
349
+ if (!safeguard) {
350
+ throw new Error(`Safeguard ${safeguard_id} not found. Use list_available_safeguards to see available safeguards.`);
351
+ }
352
+ const result = {
353
+ ...safeguard,
354
+ elementBreakdown: {
355
+ governanceElements: {
356
+ count: safeguard.governanceElements.length,
357
+ description: "Orange elements - MUST be met for compliance",
358
+ elements: safeguard.governanceElements
359
+ },
360
+ coreRequirements: {
361
+ count: safeguard.coreRequirements.length,
362
+ description: "Green elements - The 'what' of the safeguard",
363
+ elements: safeguard.coreRequirements
364
+ },
365
+ subTaxonomicalElements: {
366
+ count: safeguard.subTaxonomicalElements.length,
367
+ description: "Yellow elements - Detailed sub-taxonomical components",
368
+ elements: safeguard.subTaxonomicalElements
369
+ },
370
+ ...(include_examples && {
371
+ implementationSuggestions: {
372
+ count: safeguard.implementationSuggestions.length,
373
+ description: "Gray elements - Implementation suggestions and methods",
374
+ elements: safeguard.implementationSuggestions
375
+ }
376
+ })
377
+ }
378
+ };
379
+ return {
380
+ content: [
381
+ {
382
+ type: 'text',
383
+ text: JSON.stringify(result, null, 2),
384
+ },
385
+ ],
386
+ };
387
+ }
388
+ async listAvailableSafeguards(args) {
389
+ const { implementation_group, security_function } = args;
390
+ let safeguards = Object.values(CIS_SAFEGUARDS);
391
+ if (implementation_group) {
392
+ safeguards = safeguards.filter(s => s.implementationGroup === implementation_group);
393
+ }
394
+ if (security_function) {
395
+ safeguards = safeguards.filter(s => s.securityFunction.includes(security_function));
396
+ }
397
+ const summary = {
398
+ totalSafeguards: safeguards.length,
399
+ byImplementationGroup: {
400
+ IG1: safeguards.filter(s => s.implementationGroup === 'IG1').length,
401
+ IG2: safeguards.filter(s => s.implementationGroup === 'IG2').length,
402
+ IG3: safeguards.filter(s => s.implementationGroup === 'IG3').length,
403
+ },
404
+ safeguards: safeguards.map(s => ({
405
+ id: s.id,
406
+ title: s.title,
407
+ implementationGroup: s.implementationGroup,
408
+ assetType: s.assetType,
409
+ securityFunction: s.securityFunction
410
+ }))
411
+ };
412
+ return {
413
+ content: [
414
+ {
415
+ type: 'text',
416
+ text: JSON.stringify(summary, null, 2),
417
+ },
418
+ ],
419
+ };
420
+ }
421
+ async analyzeVendorResponse(args) {
422
+ const { vendor_name, safeguard_id, response_text } = args;
423
+ const safeguard = CIS_SAFEGUARDS[safeguard_id];
424
+ if (!safeguard) {
425
+ throw new Error(`Safeguard ${safeguard_id} not found. Available safeguards: ${Object.keys(CIS_SAFEGUARDS).join(', ')}`);
426
+ }
427
+ const analysis = this.performEnhancedSafeguardAnalysis(vendor_name, safeguard, response_text);
428
+ return {
429
+ content: [
430
+ {
431
+ type: 'text',
432
+ text: JSON.stringify(analysis, null, 2),
433
+ },
434
+ ],
435
+ };
436
+ }
437
+ async validateCoverageClaim(args) {
438
+ const { vendor_name, safeguard_id, coverage_claim, response_text, capabilities } = args;
439
+ const safeguard = CIS_SAFEGUARDS[safeguard_id];
440
+ if (!safeguard) {
441
+ throw new Error(`Safeguard ${safeguard_id} not found`);
442
+ }
443
+ const analysis = this.performEnhancedSafeguardAnalysis(vendor_name, safeguard, response_text);
444
+ // Validate the coverage claim
445
+ const validation = this.validateClaim(coverage_claim, analysis, capabilities, safeguard);
446
+ return {
447
+ content: [
448
+ {
449
+ type: 'text',
450
+ text: JSON.stringify({
451
+ vendor: vendor_name,
452
+ safeguardId: safeguard_id,
453
+ claimedCoverage: coverage_claim,
454
+ claimedCapabilities: capabilities,
455
+ analysis,
456
+ validation
457
+ }, null, 2),
458
+ },
459
+ ],
460
+ };
461
+ }
462
+ performEnhancedSafeguardAnalysis(vendorName, safeguard, responseText) {
463
+ const text = responseText.toLowerCase();
464
+ // Enhanced keywords based on GRC attributes
465
+ const governanceKeywords = [
466
+ 'policy', 'policies', 'manage', 'process', 'workflow', 'governance', 'grc',
467
+ 'compliance management', 'documented', 'establish', 'maintain', 'procedure'
468
+ ];
469
+ const facilitatesKeywords = [
470
+ 'improve', 'enhance', 'optimize', 'faster', 'better', 'stronger', 'automate',
471
+ 'streamline', 'efficiency', 'facilitate', 'support', 'enable', 'accelerate'
472
+ ];
473
+ const validatesKeywords = [
474
+ 'audit', 'report', 'evidence', 'verify', 'validate', 'check', 'monitor',
475
+ 'compliance report', 'assessment', 'logging', 'tracking', 'review', 'attest'
476
+ ];
477
+ // Calculate GRC attribute scores
478
+ const governanceScore = this.calculateKeywordScore(text, governanceKeywords);
479
+ const facilitatesScore = this.calculateKeywordScore(text, facilitatesKeywords);
480
+ const validatesScore = this.calculateKeywordScore(text, validatesKeywords);
481
+ // Analyze coverage against each category of elements
482
+ const governanceCoverage = this.analyzeElementCoverage(text, safeguard.governanceElements);
483
+ const coreCoverage = this.analyzeElementCoverage(text, safeguard.coreRequirements);
484
+ const subElementCoverage = this.analyzeElementCoverage(text, safeguard.subTaxonomicalElements);
485
+ const implementationCoverage = this.analyzeElementCoverage(text, safeguard.implementationSuggestions);
486
+ // Calculate overall coverage breakdown
487
+ const coverageBreakdown = {
488
+ governance: governanceCoverage.percentage,
489
+ core: coreCoverage.percentage,
490
+ subElements: subElementCoverage.percentage,
491
+ overall: (governanceCoverage.percentage * 0.4 + coreCoverage.percentage * 0.4 + subElementCoverage.percentage * 0.2)
492
+ };
493
+ // Determine coverage level based on comprehensive analysis
494
+ let coverage = 'none';
495
+ if (coverageBreakdown.governance >= 80 && coverageBreakdown.core >= 70) {
496
+ coverage = 'full';
497
+ }
498
+ else if (coverageBreakdown.overall >= 25) {
499
+ coverage = 'partial';
500
+ }
501
+ // Extract evidence with enhanced context
502
+ const evidence = this.extractEnhancedEvidence(responseText, safeguard);
503
+ // Calculate confidence based on multiple factors
504
+ const confidence = Math.min(((governanceScore + facilitatesScore + validatesScore) / 3 * 0.4 +
505
+ coverageBreakdown.overall / 100 * 0.6) * 100, 100);
506
+ return {
507
+ vendor: vendorName,
508
+ safeguardId: safeguard.id,
509
+ safeguardTitle: safeguard.title,
510
+ governance: governanceScore > 0.3,
511
+ facilitates: facilitatesScore > 0.3,
512
+ coverage,
513
+ validates: validatesScore > 0.3,
514
+ confidence: Math.round(confidence),
515
+ reasoning: this.generateEnhancedReasoning(governanceScore, facilitatesScore, validatesScore, coverageBreakdown, safeguard),
516
+ evidence,
517
+ governanceElementsCovered: governanceCoverage.coveredElements,
518
+ coreRequirementsCovered: coreCoverage.coveredElements,
519
+ subElementsCovered: subElementCoverage.coveredElements,
520
+ implementationMethodsUsed: implementationCoverage.coveredElements,
521
+ coverageBreakdown: {
522
+ governance: Math.round(coverageBreakdown.governance),
523
+ core: Math.round(coverageBreakdown.core),
524
+ subElements: Math.round(coverageBreakdown.subElements),
525
+ overall: Math.round(coverageBreakdown.overall)
526
+ }
527
+ };
528
+ }
529
+ calculateKeywordScore(text, keywords) {
530
+ let score = 0;
531
+ let matches = 0;
532
+ keywords.forEach(keyword => {
533
+ const regex = new RegExp(keyword.replace(/\s+/g, '\\s+'), 'gi');
534
+ const keywordMatches = (text.match(regex) || []).length;
535
+ if (keywordMatches > 0) {
536
+ matches++;
537
+ score += keywordMatches;
538
+ }
539
+ });
540
+ return matches > 0 ? score / text.split(' ').length : 0;
541
+ }
542
+ analyzeElementCoverage(text, elements) {
543
+ const coveredElements = [];
544
+ const uncoveredElements = [];
545
+ elements.forEach(element => {
546
+ const elementKeywords = element.toLowerCase().split(/[\s\-\(\)\/]+/).filter(w => w.length > 2);
547
+ let elementFound = false;
548
+ // Check for keyword matches
549
+ for (const keyword of elementKeywords) {
550
+ if (text.includes(keyword)) {
551
+ elementFound = true;
552
+ break;
553
+ }
554
+ }
555
+ // Check for semantic matches
556
+ if (!elementFound) {
557
+ const regex = new RegExp(element.replace(/[()]/g, '').replace(/\s+/g, '\\s*'), 'gi');
558
+ if (regex.test(text)) {
559
+ elementFound = true;
560
+ }
561
+ }
562
+ if (elementFound) {
563
+ coveredElements.push(element);
564
+ }
565
+ else {
566
+ uncoveredElements.push(element);
567
+ }
568
+ });
569
+ return {
570
+ percentage: elements.length > 0 ? (coveredElements.length / elements.length) * 100 : 0,
571
+ coveredElements,
572
+ uncoveredElements
573
+ };
574
+ }
575
+ extractEnhancedEvidence(text, safeguard) {
576
+ const sentences = text.split(/[.!?]+/).filter(s => s.trim().length > 15);
577
+ const evidence = [];
578
+ // Collect all keywords from all categories
579
+ const allKeywords = [
580
+ ...safeguard.keywords,
581
+ ...safeguard.governanceElements,
582
+ ...safeguard.coreRequirements,
583
+ ...safeguard.subTaxonomicalElements
584
+ ];
585
+ // Extract relevant sentences
586
+ allKeywords.forEach(keyword => {
587
+ sentences.forEach(sentence => {
588
+ const lowerSentence = sentence.toLowerCase();
589
+ const lowerKeyword = keyword.toLowerCase();
590
+ if (lowerSentence.includes(lowerKeyword) &&
591
+ !evidence.includes(sentence.trim()) &&
592
+ evidence.length < 8) {
593
+ evidence.push(sentence.trim());
594
+ }
595
+ });
596
+ });
597
+ return evidence;
598
+ }
599
+ generateEnhancedReasoning(governance, facilitates, validates, coverageBreakdown, safeguard) {
600
+ const reasons = [];
601
+ // GRC attribute analysis
602
+ if (governance > 0.3)
603
+ reasons.push(`Strong governance capabilities for ${safeguard.title}`);
604
+ if (facilitates > 0.3)
605
+ reasons.push(`Enhancement features that facilitate ${safeguard.id} implementation`);
606
+ if (validates > 0.3)
607
+ reasons.push(`Validation capabilities for ${safeguard.id} compliance verification`);
608
+ // Coverage breakdown analysis
609
+ reasons.push(`Coverage breakdown: ${coverageBreakdown.governance}% governance, ${coverageBreakdown.core}% core requirements, ${coverageBreakdown.subElements}% sub-elements`);
610
+ if (coverageBreakdown.governance < 50) {
611
+ reasons.push(`Limited governance element coverage may impact compliance`);
612
+ }
613
+ if (coverageBreakdown.core < 50) {
614
+ reasons.push(`Core requirements coverage needs improvement`);
615
+ }
616
+ return reasons.join('. ');
617
+ }
618
+ validateClaim(claim, analysis, capabilities, safeguard) {
619
+ const validation = {
620
+ coverageClaimValid: false,
621
+ capabilityClaimsValid: {},
622
+ gaps: [],
623
+ recommendations: []
624
+ };
625
+ // Validate coverage claim
626
+ if (claim === 'FULL') {
627
+ // For FULL claim, should cover at least 80% of governance elements and 70% of core requirements
628
+ const meetsFullCriteria = analysis.coverageBreakdown.governance >= 80 &&
629
+ analysis.coverageBreakdown.core >= 70;
630
+ validation.coverageClaimValid = meetsFullCriteria;
631
+ if (!meetsFullCriteria) {
632
+ validation.gaps.push(`FULL coverage claim not supported: Governance ${analysis.coverageBreakdown.governance}% (need 80%+), Core ${analysis.coverageBreakdown.core}% (need 70%+)`);
633
+ }
634
+ }
635
+ else if (claim === 'PARTIAL') {
636
+ // For PARTIAL claim, should cover at least some elements
637
+ const meetsPartialCriteria = analysis.coverageBreakdown.overall >= 20;
638
+ validation.coverageClaimValid = meetsPartialCriteria;
639
+ if (!meetsPartialCriteria) {
640
+ validation.gaps.push(`PARTIAL coverage claim questionable: Overall coverage only ${analysis.coverageBreakdown.overall}%`);
641
+ }
642
+ }
643
+ // Validate capability claims
644
+ capabilities.forEach(capability => {
645
+ switch (capability.toLowerCase()) {
646
+ case 'governance':
647
+ validation.capabilityClaimsValid[capability] = analysis.governance;
648
+ if (!analysis.governance) {
649
+ validation.gaps.push(`Governance capability not evidenced in response`);
650
+ }
651
+ break;
652
+ case 'facilitates':
653
+ validation.capabilityClaimsValid[capability] = analysis.facilitates;
654
+ if (!analysis.facilitates) {
655
+ validation.gaps.push(`Facilitates capability not evidenced in response`);
656
+ }
657
+ break;
658
+ case 'validates':
659
+ validation.capabilityClaimsValid[capability] = analysis.validates;
660
+ if (!analysis.validates) {
661
+ validation.gaps.push(`Validates capability not evidenced in response`);
662
+ }
663
+ break;
664
+ }
665
+ });
666
+ // Generate recommendations
667
+ if (validation.gaps.length === 0) {
668
+ validation.recommendations.push(`Claims appear to be well-supported by the vendor response`);
669
+ }
670
+ else {
671
+ validation.recommendations.push(`Consider requesting additional information about: ${validation.gaps.join(', ')}`);
672
+ // Specific recommendations based on gaps
673
+ if (analysis.coverageBreakdown.governance < 80) {
674
+ validation.recommendations.push(`Request details on policy management and documented processes`);
675
+ }
676
+ if (analysis.coverageBreakdown.core < 70) {
677
+ validation.recommendations.push(`Ask for specifics on how core safeguard requirements are met`);
678
+ }
679
+ if (!analysis.validates && capabilities.includes('Validates')) {
680
+ validation.recommendations.push(`Request examples of audit trails, reporting capabilities, and compliance evidence`);
681
+ }
682
+ }
683
+ return validation;
684
+ }
685
+ async run() {
686
+ const transport = new StdioServerTransport();
687
+ await this.server.connect(transport);
688
+ console.error('FrameworkMCP server running on stdio');
689
+ }
690
+ }
691
+ const server = new GRCAnalysisServer();
692
+ server.run().catch(console.error);
693
+ //# sourceMappingURL=index.js.map