check_compliance
Validate project compliance against security frameworks like OWASP, CIS, NIST, and ISO27001 to ensure adherence to required standards and identify potential gaps.
Instructions
Validates project against compliance frameworks
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| frameworks | Yes | Compliance frameworks to check | |
| path | Yes | Project path | |
| profile | No | Compliance check profile (default: standard) |
Implementation Reference
- src/core/server.ts:488-526 (handler)MCP tool handler for check_compliance that validates input path, delegates to ComplianceValidator for scanning and framework mapping, generates HTML report, and formats the response.private async handleComplianceCheck(args: any): Promise<any> { const { path, frameworks, profile = 'standard' } = args; // Validate path const validation = await this.boundaryEnforcer.validatePath(path); if (!validation.allowed) { throw new McpError(ErrorCode.InvalidRequest, validation.reason || 'Path validation failed'); } // Set the project scanner for the compliance validator this.complianceValidator.setProjectScanner(this.projectScanner); // Check compliance - this will run scans and map to frameworks const report = await this.complianceValidator.validate(path, frameworks, profile); // Generate HTML report const htmlPath = await this.complianceValidator.generateHTMLReport(report); // Return simplified result for MCP response return { status: 'success', summary: { overallCompliance: `${report.summary.overallCompliance}%`, totalFindings: report.summary.totalFindings, criticalFindings: report.summary.criticalFindings, highFindings: report.summary.highFindings, }, frameworks: report.frameworks.map(f => ({ name: f.framework, coverage: `${f.coverage}%`, passed: f.passed, failed: f.failed, total: f.totalControls, })), recommendations: report.summary.recommendations.slice(0, 5), reportPath: htmlPath, tokenUsage: report.scanResults?.tokenUsage || 0, }; }
- src/core/server.ts:134-156 (schema)Input schema for the check_compliance tool defining parameters: path (required), frameworks (required array of OWASP/CIS/NIST/ISO27001), and optional profile.name: 'check_compliance', description: 'Validates project against compliance frameworks', inputSchema: { type: 'object', properties: { path: { type: 'string', description: 'Project path' }, frameworks: { type: 'array', items: { type: 'string', enum: ['OWASP', 'CIS', 'NIST', 'ISO27001'] }, description: 'Compliance frameworks to check' }, profile: { type: 'string', enum: ['minimal', 'standard', 'comprehensive'], description: 'Compliance check profile (default: standard)' }, }, required: ['path', 'frameworks'], }, },
- src/core/server.ts:269-271 (registration)Registration of the check_compliance tool handler in the switch statement within the CallToolRequestSchema handler.case 'check_compliance': result = await this.handleComplianceCheck(args); break;
- src/compliance/validator.ts:40-119 (helper)Core compliance validation logic: performs project scan, maps findings to specified frameworks using ComplianceMapper, calculates compliance metrics, generates recommendations and report.async validate( projectPath: string, frameworks: string[], profile: 'minimal' | 'standard' | 'comprehensive' = 'standard' ): Promise<ComplianceReport> { // Run security scans first if scanner is available let findings: Finding[] = []; let scanTimeMs = 0; let tokenUsage = 0; if (this.projectScanner) { console.error('Running security scans for compliance validation...'); const scanRequest: ScanRequest = { type: 'project', target: projectPath, profile: profile === 'minimal' ? 'quick' : profile === 'comprehensive' ? 'thorough' : 'standard', options: { parallel: true, }, }; const scanResult = await this.projectScanner.scan(scanRequest); findings = scanResult.findings; scanTimeMs = scanResult.scanTimeMs; tokenUsage = scanResult.tokenUsage; console.error(`Found ${findings.length} findings to map to compliance frameworks`); } else { console.warn('No project scanner available, using empty findings list'); } // Map findings to each framework const frameworkResults: FrameworkResult[] = []; for (const framework of frameworks) { const frameworkType = framework.toUpperCase() as 'OWASP' | 'CIS' | 'NIST' | 'ISO27001'; if (['OWASP', 'CIS', 'NIST', 'ISO27001'].includes(frameworkType)) { const result = this.mapper.mapFindingsToFramework(findings, frameworkType); frameworkResults.push(result); } else { console.warn(`Unknown compliance framework: ${framework}`); } } // Calculate summary const criticalFindings = findings.filter(f => f.severity === 'critical').length; const highFindings = findings.filter(f => f.severity === 'high').length; const overallCompliance = frameworkResults.length > 0 ? Math.round(frameworkResults.reduce((sum, r) => sum + r.coverage, 0) / frameworkResults.length) : 0; const recommendations = this.generateRecommendations(frameworkResults, findings); const report: ComplianceReport = { timestamp: new Date().toISOString(), projectPath, profile, frameworks: frameworkResults, summary: { overallCompliance, totalFindings: findings.length, criticalFindings, highFindings, recommendations, }, scanResults: { findings, scanTimeMs, tokenUsage, }, }; // Save report to file await this.saveReport(report); return report; }
- src/compliance/mapper.ts:324-410 (helper)Maps security scan findings to compliance framework controls by matching finding types, severities, and keywords; determines control status (passed/failed/partial) and generates coverage metrics.public mapFindingsToFramework( findings: Finding[], framework: 'OWASP' | 'CIS' | 'NIST' | 'ISO27001' ): FrameworkResult { let controls: Map<string, ComplianceControl>; let frameworkName: string; let version: string; switch (framework) { case 'OWASP': controls = this.owaspControls; frameworkName = 'OWASP Top 10'; version = '2021'; break; case 'CIS': controls = this.cisControls; frameworkName = 'CIS Controls'; version = 'v8'; break; case 'NIST': controls = this.nistControls; frameworkName = 'NIST Cybersecurity Framework'; version = '1.1'; break; case 'ISO27001': controls = this.isoControls; frameworkName = 'ISO 27001'; version = '2022'; break; } const controlResults: ControlResult[] = []; let passed = 0; let failed = 0; let partial = 0; let notApplicable = 0; for (const [controlId, control] of controls) { const relevantFindings = this.findRelevantFindings(findings, control); let status: 'passed' | 'failed' | 'partial' | 'not_applicable'; if (relevantFindings.length === 0) { // No findings related to this control status = 'passed'; passed++; } else { const criticalFindings = relevantFindings.filter(f => f.severity === 'critical'); const highFindings = relevantFindings.filter(f => f.severity === 'high'); if (criticalFindings.length > 0) { status = 'failed'; failed++; } else if (highFindings.length > 0) { status = 'partial'; partial++; } else { status = 'partial'; partial++; } } controlResults.push({ id: controlId, title: control.title, status, findings: relevantFindings, evidence: this.generateEvidence(relevantFindings), recommendation: this.generateRecommendation(control, relevantFindings), }); } const totalControls = controls.size; const coverage = Math.round(((passed + partial) / totalControls) * 100); return { framework: frameworkName, version, totalControls, passed, failed, partial, notApplicable, coverage, controls: controlResults, }; }