@greenarmor/ges-mcp-server 1.2.3 → 1.2.5
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/server.js +104 -3
- package/package.json +12 -12
package/dist/server.js
CHANGED
|
@@ -9,6 +9,7 @@ import { generateScoreFile, formatScoreOutput, computeGrade, generateBadgeSvg, i
|
|
|
9
9
|
import { runAudit, deduplicateFindings } from "@greenarmor/ges-audit-engine";
|
|
10
10
|
import { GESF_VERSION, GES_DIR, COMPLIANCE_DIR, SECURITY_DIR, CONTROLS_DIR, POLICIES_DIR, CHECKLISTS_DIR, DOCS_DIR, REPORTS_DIR, DEFAULT_FRAMEWORKS } from "@greenarmor/ges-core";
|
|
11
11
|
import { appendFixHistory, createFixHistoryEntry } from "@greenarmor/ges-core";
|
|
12
|
+
import { addFrameworkToConfig, removeFrameworkFromConfig, saveControlOverride, loadControlsFromDisk, recordActivity } from "@greenarmor/ges-core";
|
|
12
13
|
import { ProjectConfigSchema } from "@greenarmor/ges-core";
|
|
13
14
|
import { generateComplianceDocs, generateSecurityDocs, generateConfigJson, generateMetadataJson, generateFrameworkVersionJson, generateScoreJson } from "@greenarmor/ges-doc-generator";
|
|
14
15
|
import { generateAllWorkflows } from "@greenarmor/ges-cicd-generator";
|
|
@@ -2201,6 +2202,14 @@ export function handleRequest(request) {
|
|
|
2201
2202
|
lines.push(`\n*Note: ${projectConfig.overrides.length} control overrides applied.*`);
|
|
2202
2203
|
}
|
|
2203
2204
|
resultText = lines.join("\n");
|
|
2205
|
+
recordActivity(projectPath, {
|
|
2206
|
+
source: "mcp",
|
|
2207
|
+
action: "audit",
|
|
2208
|
+
title: `MCP audit completed`,
|
|
2209
|
+
description: `Scanned ${scannedFiles} files, found ${findings.length} findings (${critical.length} critical, ${high.length} high, ${medium.length} medium, ${low.length} low). Overall score: ${score.overall}%.`,
|
|
2210
|
+
status: critical.length > 0 ? "failed" : findings.length > 0 ? "partial" : "success",
|
|
2211
|
+
details: { findings_count: findings.length, score: score.overall, files_scanned: scannedFiles },
|
|
2212
|
+
});
|
|
2204
2213
|
break;
|
|
2205
2214
|
}
|
|
2206
2215
|
case "generate_compliance_report": {
|
|
@@ -2318,13 +2327,18 @@ export function handleRequest(request) {
|
|
|
2318
2327
|
let projectControls = [];
|
|
2319
2328
|
try {
|
|
2320
2329
|
const configPath = path.join(projectPath, ".ges", "config.json");
|
|
2330
|
+
let inMemoryControls = [];
|
|
2321
2331
|
if (fs.existsSync(configPath)) {
|
|
2322
2332
|
const cfg = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
2323
2333
|
const fwLower = new Set(cfg.frameworks.map((f) => f.toLowerCase()));
|
|
2324
2334
|
const allPacks = getAllPacks();
|
|
2325
2335
|
const filtered = allPacks.filter((pack) => fwLower.has(pack.id.toLowerCase()));
|
|
2326
|
-
|
|
2336
|
+
inMemoryControls = filtered.flatMap((p) => p.controls);
|
|
2327
2337
|
}
|
|
2338
|
+
const diskControls = loadControlsFromDisk(projectPath);
|
|
2339
|
+
const seenIds = new Set(inMemoryControls.map(c => c.id));
|
|
2340
|
+
const extraFromDisk = diskControls.filter(c => !seenIds.has(c.id));
|
|
2341
|
+
projectControls = [...inMemoryControls, ...extraFromDisk];
|
|
2328
2342
|
}
|
|
2329
2343
|
catch { /* ignore */ }
|
|
2330
2344
|
const npmInstalls = getNpmInstallsFromActions(actions);
|
|
@@ -2423,6 +2437,14 @@ export function handleRequest(request) {
|
|
|
2423
2437
|
lines.push("4. Address remaining manual review items");
|
|
2424
2438
|
lines.push("5. Use `fix_recommendation` tool for detailed guidance on manual items");
|
|
2425
2439
|
resultText = lines.join("\n");
|
|
2440
|
+
recordActivity(projectPath, {
|
|
2441
|
+
source: "mcp",
|
|
2442
|
+
action: "fix",
|
|
2443
|
+
title: `MCP auto-fix ${dryRun ? "planned" : "applied"}: ${applied} fixes`,
|
|
2444
|
+
description: `${dryRun ? "Planned" : "Applied"} ${applied} fix(es)${failed > 0 ? ` (${failed} failed)` : ""}. Scanned ${scannedFiles} files, ${findings.length} findings found.`,
|
|
2445
|
+
status: failed > 0 ? "partial" : "success",
|
|
2446
|
+
details: { fixes_applied: applied, findings_count: findings.length },
|
|
2447
|
+
});
|
|
2426
2448
|
break;
|
|
2427
2449
|
}
|
|
2428
2450
|
case "apply_control_override": {
|
|
@@ -2471,6 +2493,13 @@ export function handleRequest(request) {
|
|
|
2471
2493
|
`\nRun \`ges audit\` then \`ges score\` to see the updated compliance score.`,
|
|
2472
2494
|
];
|
|
2473
2495
|
resultText = lines.join("\n");
|
|
2496
|
+
recordActivity(projectPath, {
|
|
2497
|
+
source: "mcp",
|
|
2498
|
+
action: "control_override",
|
|
2499
|
+
title: `Control ${controlId} → ${status}`,
|
|
2500
|
+
description: `MCP applied override: control ${controlId} set to ${status}. Reason: ${reason || "(none)"}`,
|
|
2501
|
+
details: { controls_affected: [controlId] },
|
|
2502
|
+
});
|
|
2474
2503
|
break;
|
|
2475
2504
|
}
|
|
2476
2505
|
case "implement_control": {
|
|
@@ -2536,18 +2565,27 @@ export function handleRequest(request) {
|
|
|
2536
2565
|
break;
|
|
2537
2566
|
}
|
|
2538
2567
|
lines.push(`**Control**: ${plan.name}\n`);
|
|
2568
|
+
let appliedCount = 0;
|
|
2569
|
+
let skippedCount = 0;
|
|
2539
2570
|
for (const action of plan.actions) {
|
|
2540
2571
|
const result = applyAutoFixAction(projectPath, action);
|
|
2541
2572
|
if (result.applied) {
|
|
2573
|
+
appliedCount++;
|
|
2542
2574
|
lines.push(`- ✓ [${action.type}] ${action.filePath}: ${action.description}`);
|
|
2543
2575
|
}
|
|
2544
2576
|
else if (result.error === "File already exists") {
|
|
2577
|
+
skippedCount++;
|
|
2545
2578
|
lines.push(`- → [${action.type}] ${action.filePath}: Already exists (skipped)`);
|
|
2546
2579
|
}
|
|
2547
2580
|
else {
|
|
2548
2581
|
lines.push(`- ✗ [${action.type}] ${action.filePath}: ${result.error}`);
|
|
2549
2582
|
}
|
|
2550
2583
|
}
|
|
2584
|
+
if (appliedCount > 0 || skippedCount > 0) {
|
|
2585
|
+
saveControlOverride(projectPath, controlId, "pass", `Auto-implemented by GESF (${plan.name})`);
|
|
2586
|
+
lines.push(`\n✅ Control **${controlId}** marked as **pass** in .ges/control-overrides.json`);
|
|
2587
|
+
lines.push(` The dashboard will reflect this immediately.`);
|
|
2588
|
+
}
|
|
2551
2589
|
const npmInstalls = getNpmInstallsFromActions(plan.actions);
|
|
2552
2590
|
if (npmInstalls.length > 0) {
|
|
2553
2591
|
lines.push(`\n## Install Dependencies\n`);
|
|
@@ -2564,8 +2602,14 @@ export function handleRequest(request) {
|
|
|
2564
2602
|
lines.push("1. Install any npm packages listed above");
|
|
2565
2603
|
lines.push("2. Import and integrate the generated files into your app");
|
|
2566
2604
|
lines.push("3. Run `ges audit` to verify the control is now passing");
|
|
2567
|
-
lines.push(`4. Or use \`apply_control_override\` with control_id="${controlId}" if verified manually`);
|
|
2568
2605
|
resultText = lines.join("\n");
|
|
2606
|
+
recordActivity(projectPath, {
|
|
2607
|
+
source: "mcp",
|
|
2608
|
+
action: "implement_control",
|
|
2609
|
+
title: `Control implemented: ${controlId} (${plan.name})`,
|
|
2610
|
+
description: `Auto-implemented control ${controlId} (${plan.name}). ${appliedCount} actions applied, ${skippedCount} skipped. Control marked as pass.`,
|
|
2611
|
+
details: { controls_affected: [controlId], files_created: plan.actions.filter(a => a.type === "create").map(a => a.filePath) },
|
|
2612
|
+
});
|
|
2569
2613
|
break;
|
|
2570
2614
|
}
|
|
2571
2615
|
case "generate_badge": {
|
|
@@ -2725,6 +2769,13 @@ export function handleRequest(request) {
|
|
|
2725
2769
|
lines.push(`3. Run \`ges badge\` to generate a compliance badge for README`);
|
|
2726
2770
|
lines.push(`4. Review and customize documents in compliance/ and security/`);
|
|
2727
2771
|
resultText = lines.join("\n");
|
|
2772
|
+
recordActivity(projectPath, {
|
|
2773
|
+
source: "mcp",
|
|
2774
|
+
action: "init",
|
|
2775
|
+
title: `Project initialized: ${projectName}`,
|
|
2776
|
+
description: `Initialized GESF for ${projectType} project with frameworks: ${frameworks.join(", ")}. Installed ${packs.length} policy packs.`,
|
|
2777
|
+
details: { packs_affected: packs.map(p => p.id), frameworks_added: frameworks.map(f => String(f)) },
|
|
2778
|
+
});
|
|
2728
2779
|
break;
|
|
2729
2780
|
}
|
|
2730
2781
|
case "run_scans": {
|
|
@@ -2755,6 +2806,13 @@ export function handleRequest(request) {
|
|
|
2755
2806
|
lines.push(`\n**${failed.length} scanner(s) reported failures.** Review findings above.`);
|
|
2756
2807
|
}
|
|
2757
2808
|
resultText = lines.join("\n");
|
|
2809
|
+
recordActivity(projectPath, {
|
|
2810
|
+
source: "mcp",
|
|
2811
|
+
action: "scan",
|
|
2812
|
+
title: `MCP security scans completed (${results.length} tools)`,
|
|
2813
|
+
description: `Ran ${results.length} scanner(s) for ${ecosystemDetail} ecosystem. ${results.filter(r => r.status === "pass").length} passed, ${failed.length} failed.`,
|
|
2814
|
+
status: failed.length > 0 ? "partial" : "success",
|
|
2815
|
+
});
|
|
2758
2816
|
break;
|
|
2759
2817
|
}
|
|
2760
2818
|
case "doctor": {
|
|
@@ -2889,6 +2947,13 @@ export function handleRequest(request) {
|
|
|
2889
2947
|
}
|
|
2890
2948
|
lines.push(hasErrors ? "\n❌ **Validation failed.** Fix the issues above." : "\n✅ **All validations passed.**");
|
|
2891
2949
|
resultText = lines.join("\n");
|
|
2950
|
+
recordActivity(projectPath, {
|
|
2951
|
+
source: "mcp",
|
|
2952
|
+
action: "validate",
|
|
2953
|
+
title: `MCP validation ${hasErrors ? "failed" : "passed"}`,
|
|
2954
|
+
description: hasErrors ? "Configuration or directory structure has issues." : "All validations passed.",
|
|
2955
|
+
status: hasErrors ? "failed" : "success",
|
|
2956
|
+
});
|
|
2892
2957
|
break;
|
|
2893
2958
|
}
|
|
2894
2959
|
case "policy_list": {
|
|
@@ -2924,7 +2989,23 @@ export function handleRequest(request) {
|
|
|
2924
2989
|
const packDir = path.join(projectPath, CONTROLS_DIR, pack.id);
|
|
2925
2990
|
fs.mkdirSync(packDir, { recursive: true });
|
|
2926
2991
|
fs.writeFileSync(path.join(packDir, "controls.json"), JSON.stringify(pack.controls, null, 2));
|
|
2927
|
-
|
|
2992
|
+
const addedToConfig = addFrameworkToConfig(projectPath, pack.id.toUpperCase());
|
|
2993
|
+
const lines = [
|
|
2994
|
+
`✅ Installed policy pack: **${pack.id}** (${pack.name})`,
|
|
2995
|
+
`${pack.controls.length} controls written to ${CONTROLS_DIR}/${pack.id}/controls.json`,
|
|
2996
|
+
];
|
|
2997
|
+
if (addedToConfig) {
|
|
2998
|
+
lines.push(`Added ${pack.id.toUpperCase()} to project frameworks in .ges/config.json`);
|
|
2999
|
+
}
|
|
3000
|
+
lines.push(`The web dashboard will now reflect this pack's controls.`);
|
|
3001
|
+
resultText = lines.join("\n");
|
|
3002
|
+
recordActivity(projectPath, {
|
|
3003
|
+
source: "mcp",
|
|
3004
|
+
action: "policy_install",
|
|
3005
|
+
title: `MCP installed pack: ${pack.name}`,
|
|
3006
|
+
description: `Installed ${pack.controls.length} controls from ${pack.id} pack.${addedToConfig ? ` Added ${pack.id.toUpperCase()} to config frameworks.` : ""}`,
|
|
3007
|
+
details: { packs_affected: [pack.id], frameworks_added: addedToConfig ? [pack.id.toUpperCase()] : [] },
|
|
3008
|
+
});
|
|
2928
3009
|
break;
|
|
2929
3010
|
}
|
|
2930
3011
|
case "policy_remove": {
|
|
@@ -2940,7 +3021,15 @@ export function handleRequest(request) {
|
|
|
2940
3021
|
break;
|
|
2941
3022
|
}
|
|
2942
3023
|
fs.rmSync(packDir, { recursive: true, force: true });
|
|
3024
|
+
removeFrameworkFromConfig(projectPath, packId.toUpperCase());
|
|
2943
3025
|
resultText = `✅ Removed policy pack: **${packId}** from ${projectPath}`;
|
|
3026
|
+
recordActivity(projectPath, {
|
|
3027
|
+
source: "mcp",
|
|
3028
|
+
action: "policy_remove",
|
|
3029
|
+
title: `MCP removed pack: ${packId}`,
|
|
3030
|
+
description: `Removed ${packId} pack and its controls from the project.`,
|
|
3031
|
+
details: { packs_affected: [packId] },
|
|
3032
|
+
});
|
|
2944
3033
|
break;
|
|
2945
3034
|
}
|
|
2946
3035
|
case "update_check": {
|
|
@@ -2991,6 +3080,12 @@ export function handleRequest(request) {
|
|
|
2991
3080
|
fs.writeFileSync(hookPath, hookContent);
|
|
2992
3081
|
fs.chmodSync(hookPath, 0o755);
|
|
2993
3082
|
resultText = `✅ Installed pre-commit hook at ${hookPath}\n\nThe hook will run 'ges audit --ci' before allowing commits.\n- To bypass: \`git commit --no-verify\`\n- To remove: use \`install_hooks\` with action: "uninstall"`;
|
|
3083
|
+
recordActivity(projectPath, {
|
|
3084
|
+
source: "mcp",
|
|
3085
|
+
action: "hooks_install",
|
|
3086
|
+
title: `MCP installed pre-commit hook`,
|
|
3087
|
+
description: `Installed pre-commit hook that runs 'ges audit --ci' before each commit.`,
|
|
3088
|
+
});
|
|
2994
3089
|
break;
|
|
2995
3090
|
}
|
|
2996
3091
|
case "start_dashboard": {
|
|
@@ -3029,6 +3124,12 @@ export function handleRequest(request) {
|
|
|
3029
3124
|
lines.push(`- Control status matrix`);
|
|
3030
3125
|
lines.push(`- Audit history timeline`);
|
|
3031
3126
|
resultText = lines.join("\n");
|
|
3127
|
+
recordActivity(projectPath, {
|
|
3128
|
+
source: "mcp",
|
|
3129
|
+
action: "dashboard_start",
|
|
3130
|
+
title: `Dashboard started on ${host}:${port}`,
|
|
3131
|
+
description: `Web dashboard is running at http://${host}:${port}`,
|
|
3132
|
+
});
|
|
3032
3133
|
}
|
|
3033
3134
|
catch (err) {
|
|
3034
3135
|
const msg = err instanceof Error ? err.message : String(err);
|
package/package.json
CHANGED
|
@@ -3,17 +3,17 @@
|
|
|
3
3
|
"ges-mcp": "dist/server.js"
|
|
4
4
|
},
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"@greenarmor/ges-audit-engine": "1.2.
|
|
7
|
-
"@greenarmor/ges-cicd-generator": "1.2.
|
|
8
|
-
"@greenarmor/ges-compliance-engine": "1.2.
|
|
9
|
-
"@greenarmor/ges-core": "1.2.
|
|
10
|
-
"@greenarmor/ges-doc-generator": "1.2.
|
|
11
|
-
"@greenarmor/ges-policy-engine": "1.2.
|
|
12
|
-
"@greenarmor/ges-report-generator": "1.2.
|
|
13
|
-
"@greenarmor/ges-rules-engine": "1.2.
|
|
14
|
-
"@greenarmor/ges-scanner-integration": "1.2.
|
|
15
|
-
"@greenarmor/ges-scoring-engine": "1.2.
|
|
16
|
-
"@greenarmor/ges-web-dashboard": "1.2.
|
|
6
|
+
"@greenarmor/ges-audit-engine": "1.2.5",
|
|
7
|
+
"@greenarmor/ges-cicd-generator": "1.2.5",
|
|
8
|
+
"@greenarmor/ges-compliance-engine": "1.2.5",
|
|
9
|
+
"@greenarmor/ges-core": "1.2.5",
|
|
10
|
+
"@greenarmor/ges-doc-generator": "1.2.5",
|
|
11
|
+
"@greenarmor/ges-policy-engine": "1.2.5",
|
|
12
|
+
"@greenarmor/ges-report-generator": "1.2.5",
|
|
13
|
+
"@greenarmor/ges-rules-engine": "1.2.5",
|
|
14
|
+
"@greenarmor/ges-scanner-integration": "1.2.5",
|
|
15
|
+
"@greenarmor/ges-scoring-engine": "1.2.5",
|
|
16
|
+
"@greenarmor/ges-web-dashboard": "1.2.5"
|
|
17
17
|
},
|
|
18
18
|
"description": "GESF MCP Server - AI Compliance Assistant for GDPR, OWASP, NIST, CIS. Check compliance, generate policies, assess risks via MCP protocol.",
|
|
19
19
|
"devDependencies": {
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
},
|
|
68
68
|
"type": "module",
|
|
69
69
|
"types": "./dist/index.d.ts",
|
|
70
|
-
"version": "1.2.
|
|
70
|
+
"version": "1.2.5",
|
|
71
71
|
"scripts": {
|
|
72
72
|
"build": "tsc",
|
|
73
73
|
"clean": "rm -rf dist bundle tsconfig.tsbuildinfo",
|