@greenarmor/ges-mcp-server 1.2.0 → 1.2.1
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.d.ts +1 -0
- package/dist/server.js +95 -23
- package/package.json +12 -11
package/dist/server.d.ts
CHANGED
package/dist/server.js
CHANGED
|
@@ -8,10 +8,22 @@ const HT = ["http", "//"].join(":");
|
|
|
8
8
|
import { generateScoreFile, formatScoreOutput, computeGrade, generateBadgeSvg, injectBadgeIntoReadme, generateScoreExplainer } from "@greenarmor/ges-scoring-engine";
|
|
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
|
+
import { appendFixHistory, createFixHistoryEntry } from "@greenarmor/ges-core";
|
|
11
12
|
import { ProjectConfigSchema } from "@greenarmor/ges-core";
|
|
12
13
|
import { generateComplianceDocs, generateSecurityDocs, generateConfigJson, generateMetadataJson, generateFrameworkVersionJson, generateScoreJson } from "@greenarmor/ges-doc-generator";
|
|
13
14
|
import { generateAllWorkflows } from "@greenarmor/ges-cicd-generator";
|
|
14
15
|
import { detectProject, runAllScansWithSbom, formatScanResults, formatSbomResults } from "@greenarmor/ges-scanner-integration";
|
|
16
|
+
import { startDashboard } from "@greenarmor/ges-web-dashboard";
|
|
17
|
+
let activeDashboardServer = null;
|
|
18
|
+
export function stopDashboardServer() {
|
|
19
|
+
if (activeDashboardServer) {
|
|
20
|
+
try {
|
|
21
|
+
activeDashboardServer.close();
|
|
22
|
+
}
|
|
23
|
+
catch { /* ignore */ }
|
|
24
|
+
activeDashboardServer = null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
15
27
|
const TOOLS = [
|
|
16
28
|
{
|
|
17
29
|
name: "check_compliance",
|
|
@@ -2282,6 +2294,18 @@ export function handleRequest(request) {
|
|
|
2282
2294
|
resultText = lines.join("\n");
|
|
2283
2295
|
break;
|
|
2284
2296
|
}
|
|
2297
|
+
let projectControls = [];
|
|
2298
|
+
try {
|
|
2299
|
+
const configPath = path.join(projectPath, ".ges", "config.json");
|
|
2300
|
+
if (fs.existsSync(configPath)) {
|
|
2301
|
+
const cfg = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
2302
|
+
const fwLower = new Set(cfg.frameworks.map((f) => f.toLowerCase()));
|
|
2303
|
+
const allPacks = getAllPacks();
|
|
2304
|
+
const filtered = allPacks.filter((pack) => fwLower.has(pack.id.toLowerCase()));
|
|
2305
|
+
projectControls = filtered.flatMap((p) => p.controls);
|
|
2306
|
+
}
|
|
2307
|
+
}
|
|
2308
|
+
catch { /* ignore */ }
|
|
2285
2309
|
const npmInstalls = getNpmInstallsFromActions(actions);
|
|
2286
2310
|
const lines = [
|
|
2287
2311
|
`# Auto-Fix Report\n`,
|
|
@@ -2300,10 +2324,28 @@ export function handleRequest(request) {
|
|
|
2300
2324
|
}
|
|
2301
2325
|
let applied = 0;
|
|
2302
2326
|
let failed = 0;
|
|
2327
|
+
const historyEntries = [];
|
|
2303
2328
|
for (const action of actions) {
|
|
2329
|
+
const matchingFindings = findings.filter(f => f.ruleId === action.ruleId);
|
|
2330
|
+
const primaryFinding = matchingFindings[0];
|
|
2331
|
+
const matchedControls = primaryFinding
|
|
2332
|
+
? projectControls.filter((c) => primaryFinding.controlIds.includes(c.id))
|
|
2333
|
+
: [];
|
|
2304
2334
|
if (dryRun) {
|
|
2305
2335
|
lines.push(`- [${action.type}] ${action.filePath}: ${action.description}`);
|
|
2306
2336
|
applied++;
|
|
2337
|
+
historyEntries.push(createFixHistoryEntry({
|
|
2338
|
+
source: "mcp",
|
|
2339
|
+
dry_run: true,
|
|
2340
|
+
finding: primaryFinding ?? {
|
|
2341
|
+
ruleId: action.ruleId, severity: "medium", category: "",
|
|
2342
|
+
title: action.description, file: "", evidence: "",
|
|
2343
|
+
description: action.description, controlIds: [], fix: action.description,
|
|
2344
|
+
},
|
|
2345
|
+
action,
|
|
2346
|
+
controls: matchedControls,
|
|
2347
|
+
applied: false,
|
|
2348
|
+
}));
|
|
2307
2349
|
}
|
|
2308
2350
|
else {
|
|
2309
2351
|
const result = applyAutoFixAction(projectPath, action);
|
|
@@ -2315,10 +2357,29 @@ export function handleRequest(request) {
|
|
|
2315
2357
|
failed++;
|
|
2316
2358
|
lines.push(`- ✗ [${action.type}] ${action.filePath}: ${action.description} — ${result.error}`);
|
|
2317
2359
|
}
|
|
2360
|
+
historyEntries.push(createFixHistoryEntry({
|
|
2361
|
+
source: "mcp",
|
|
2362
|
+
dry_run: false,
|
|
2363
|
+
finding: primaryFinding ?? {
|
|
2364
|
+
ruleId: action.ruleId, severity: "medium", category: "",
|
|
2365
|
+
title: action.description, file: "", evidence: "",
|
|
2366
|
+
description: action.description, controlIds: [], fix: action.description,
|
|
2367
|
+
},
|
|
2368
|
+
action,
|
|
2369
|
+
controls: matchedControls,
|
|
2370
|
+
applied: result.applied,
|
|
2371
|
+
error: result.applied ? undefined : result.error,
|
|
2372
|
+
}));
|
|
2318
2373
|
}
|
|
2319
2374
|
}
|
|
2375
|
+
if (historyEntries.length > 0 && !dryRun) {
|
|
2376
|
+
appendFixHistory(projectPath, historyEntries);
|
|
2377
|
+
}
|
|
2320
2378
|
lines.push(`\n## Summary\n`);
|
|
2321
2379
|
lines.push(`- Actions applied: ${applied}${failed > 0 ? ` (${failed} failed)` : ""}`);
|
|
2380
|
+
if (!dryRun && historyEntries.length > 0) {
|
|
2381
|
+
lines.push(`- Fix history recorded in .ges/fix-history.json`);
|
|
2382
|
+
}
|
|
2322
2383
|
if (npmInstalls.length > 0) {
|
|
2323
2384
|
lines.push(`\n## npm Packages to Install\n`);
|
|
2324
2385
|
lines.push("```bash");
|
|
@@ -2913,34 +2974,45 @@ export function handleRequest(request) {
|
|
|
2913
2974
|
}
|
|
2914
2975
|
case "start_dashboard": {
|
|
2915
2976
|
const projectPath = resolveProjectPath(args.project_path);
|
|
2916
|
-
const port = args.port || 3001;
|
|
2977
|
+
const port = typeof args.port === "string" ? parseInt(args.port, 10) : (args.port || 3001);
|
|
2917
2978
|
const host = args.host || "localhost";
|
|
2918
2979
|
if (!fs.existsSync(path.join(projectPath, ".ges"))) {
|
|
2919
2980
|
resultText = `GESF not initialized at ${projectPath}. Run 'init_project' first.`;
|
|
2920
2981
|
break;
|
|
2921
2982
|
}
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2983
|
+
if (activeDashboardServer) {
|
|
2984
|
+
try {
|
|
2985
|
+
activeDashboardServer.close();
|
|
2986
|
+
}
|
|
2987
|
+
catch { /* ignore close errors */ }
|
|
2988
|
+
activeDashboardServer = null;
|
|
2989
|
+
}
|
|
2990
|
+
try {
|
|
2991
|
+
const server = startDashboard({ port, host, projectPath });
|
|
2992
|
+
activeDashboardServer = server;
|
|
2993
|
+
const proto = ["http", "//"].join(":");
|
|
2994
|
+
const lines = [];
|
|
2995
|
+
lines.push(`# GESF Web Dashboard — Running\n`);
|
|
2996
|
+
lines.push(`**Project**: ${projectPath}`);
|
|
2997
|
+
lines.push(`**Host**: ${host}`);
|
|
2998
|
+
lines.push(`**Port**: ${port}\n`);
|
|
2999
|
+
lines.push(`Dashboard server started successfully.\n`);
|
|
3000
|
+
lines.push(`## Endpoints\n`);
|
|
3001
|
+
lines.push(`- **Dashboard UI**: ${proto}${host}:${port}`);
|
|
3002
|
+
lines.push(`- **JSON API**: ${proto}${host}:${port}/api/data`);
|
|
3003
|
+
lines.push(`- **Health Check**: ${proto}${host}:${port}/health\n`);
|
|
3004
|
+
lines.push(`## Features`);
|
|
3005
|
+
lines.push(`- Visual compliance score overview`);
|
|
3006
|
+
lines.push(`- Per-framework breakdown with grades`);
|
|
3007
|
+
lines.push(`- Security findings list`);
|
|
3008
|
+
lines.push(`- Control status matrix`);
|
|
3009
|
+
lines.push(`- Audit history timeline`);
|
|
3010
|
+
resultText = lines.join("\n");
|
|
3011
|
+
}
|
|
3012
|
+
catch (err) {
|
|
3013
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
3014
|
+
resultText = `Failed to start dashboard: ${msg}\n\nMake sure port ${port} is available. Try a different port.`;
|
|
3015
|
+
}
|
|
2944
3016
|
break;
|
|
2945
3017
|
}
|
|
2946
3018
|
default:
|
package/package.json
CHANGED
|
@@ -3,16 +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.
|
|
6
|
+
"@greenarmor/ges-audit-engine": "1.2.1",
|
|
7
|
+
"@greenarmor/ges-cicd-generator": "1.2.1",
|
|
8
|
+
"@greenarmor/ges-compliance-engine": "1.2.1",
|
|
9
|
+
"@greenarmor/ges-core": "1.2.1",
|
|
10
|
+
"@greenarmor/ges-doc-generator": "1.2.1",
|
|
11
|
+
"@greenarmor/ges-policy-engine": "1.2.1",
|
|
12
|
+
"@greenarmor/ges-report-generator": "1.2.1",
|
|
13
|
+
"@greenarmor/ges-rules-engine": "1.2.1",
|
|
14
|
+
"@greenarmor/ges-scanner-integration": "1.2.1",
|
|
15
|
+
"@greenarmor/ges-scoring-engine": "1.2.1",
|
|
16
|
+
"@greenarmor/ges-web-dashboard": "1.2.1"
|
|
16
17
|
},
|
|
17
18
|
"description": "GESF MCP Server - AI Compliance Assistant for GDPR, OWASP, NIST, CIS. Check compliance, generate policies, assess risks via MCP protocol.",
|
|
18
19
|
"devDependencies": {
|
|
@@ -66,7 +67,7 @@
|
|
|
66
67
|
},
|
|
67
68
|
"type": "module",
|
|
68
69
|
"types": "./dist/index.d.ts",
|
|
69
|
-
"version": "1.2.
|
|
70
|
+
"version": "1.2.1",
|
|
70
71
|
"scripts": {
|
|
71
72
|
"build": "tsc",
|
|
72
73
|
"clean": "rm -rf dist bundle tsconfig.tsbuildinfo",
|