@greenarmor/ges-mcp-server 1.1.7 → 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 CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import type { Finding } from "@greenarmor/ges-audit-engine";
3
+ export declare function stopDashboardServer(): void;
3
4
  export type AutoFixAction = {
4
5
  type: "create" | "modify" | "append" | "npm-install";
5
6
  filePath: string;
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
- const lines = [];
2923
- lines.push(`# GESF Web Dashboard\n`);
2924
- lines.push(`**Project**: ${projectPath}`);
2925
- lines.push(`**Host**: ${host}`);
2926
- lines.push(`**Port**: ${port}\n`);
2927
- lines.push(`## Starting the Dashboard\n`);
2928
- lines.push(`The dashboard must be started via the GESF CLI. Run:\n`);
2929
- lines.push(`\`\`\`bash`);
2930
- lines.push(`cd ${projectPath}`);
2931
- lines.push(`ges dashboard --port ${port} --host ${host}`);
2932
- lines.push(`\`\`\`\n`);
2933
- lines.push(`## Available Endpoints\n`);
2934
- lines.push(`- **Dashboard UI**: ${HT}${host}:${port}`);
2935
- lines.push(`- **JSON API**: ${HT}${host}:${port}/api/data`);
2936
- lines.push(`- **Health Check**: ${HT}${host}:${port}/health\n`);
2937
- lines.push(`## Dashboard Features`);
2938
- lines.push(`- Visual compliance score overview`);
2939
- lines.push(`- Per-framework breakdown with grades`);
2940
- lines.push(`- Security findings list`);
2941
- lines.push(`- Control status matrix`);
2942
- lines.push(`- Audit history timeline`);
2943
- resultText = lines.join("\n");
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
@@ -1,7 +1,42 @@
1
1
  {
2
- "name": "@greenarmor/ges-mcp-server",
3
- "version": "1.1.7",
2
+ "bin": {
3
+ "ges-mcp": "dist/server.js"
4
+ },
5
+ "dependencies": {
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"
17
+ },
4
18
  "description": "GESF MCP Server - AI Compliance Assistant for GDPR, OWASP, NIST, CIS. Check compliance, generate policies, assess risks via MCP protocol.",
19
+ "devDependencies": {
20
+ "@types/node": "^22.0.0",
21
+ "esbuild": "^0.28.0",
22
+ "typescript": "^6.0.0",
23
+ "vitest": "^4.1.8"
24
+ },
25
+ "engines": {
26
+ "node": ">=20.0.0"
27
+ },
28
+ "exports": {
29
+ ".": {
30
+ "import": "./dist/index.js",
31
+ "types": "./dist/index.d.ts"
32
+ }
33
+ },
34
+ "files": [
35
+ "dist",
36
+ "LICENSE",
37
+ "README.md"
38
+ ],
39
+ "homepage": "https://github.com/greenarmor/gesf",
5
40
  "keywords": [
6
41
  "ai",
7
42
  "audit",
@@ -19,54 +54,20 @@
19
54
  "privacy",
20
55
  "security"
21
56
  ],
22
- "homepage": "https://github.com/greenarmor/gesf",
23
57
  "license": "MIT",
24
- "repository": {
25
- "type": "git",
26
- "url": "git+https://github.com/greenarmor/gesf.git"
27
- },
28
- "bin": {
29
- "ges-mcp": "dist/server.js"
30
- },
31
- "files": [
32
- "dist",
33
- "LICENSE",
34
- "README.md"
35
- ],
36
- "type": "module",
37
58
  "main": "./dist/index.js",
38
- "types": "./dist/index.d.ts",
39
- "exports": {
40
- ".": {
41
- "import": "./dist/index.js",
42
- "types": "./dist/index.d.ts"
43
- }
44
- },
59
+ "name": "@greenarmor/ges-mcp-server",
45
60
  "publishConfig": {
46
61
  "access": "public",
47
62
  "registry": "https://registry.npmjs.org/"
48
63
  },
49
- "dependencies": {
50
- "@greenarmor/ges-audit-engine": "1.1.5",
51
- "@greenarmor/ges-compliance-engine": "1.1.5",
52
- "@greenarmor/ges-core": "1.1.5",
53
- "@greenarmor/ges-cicd-generator": "1.1.5",
54
- "@greenarmor/ges-doc-generator": "1.1.5",
55
- "@greenarmor/ges-policy-engine": "1.1.5",
56
- "@greenarmor/ges-report-generator": "1.1.5",
57
- "@greenarmor/ges-rules-engine": "1.1.5",
58
- "@greenarmor/ges-scanner-integration": "1.1.5",
59
- "@greenarmor/ges-scoring-engine": "1.1.5"
60
- },
61
- "devDependencies": {
62
- "@types/node": "^22.0.0",
63
- "esbuild": "^0.28.0",
64
- "typescript": "^6.0.0",
65
- "vitest": "^4.1.8"
66
- },
67
- "engines": {
68
- "node": ">=20.0.0"
64
+ "repository": {
65
+ "type": "git",
66
+ "url": "git+https://github.com/greenarmor/gesf.git"
69
67
  },
68
+ "type": "module",
69
+ "types": "./dist/index.d.ts",
70
+ "version": "1.2.1",
70
71
  "scripts": {
71
72
  "build": "tsc",
72
73
  "clean": "rm -rf dist bundle tsconfig.tsbuildinfo",