@greenarmor/ges-mcp-server 1.2.8 → 1.3.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/server.js +249 -10
- package/package.json +12 -12
package/dist/server.js
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
import * as readline from "node:readline";
|
|
3
3
|
import * as fs from "node:fs";
|
|
4
4
|
import * as path from "node:path";
|
|
5
|
-
import { getAllPacks, getPacksForProjectType, getPack, listPackIds } from "@greenarmor/ges-policy-engine";
|
|
5
|
+
import { getAllPacks, getPacksForProjectType, getPack, listPackIds, PRIVACY_COUNTRIES, getCountryByCode } from "@greenarmor/ges-policy-engine";
|
|
6
6
|
const PE = ["process", "env"].join(".");
|
|
7
7
|
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
11
|
import { appendFixHistory, createFixHistoryEntry } from "@greenarmor/ges-core";
|
|
12
|
-
import { addFrameworkToConfig, removeFrameworkFromConfig, loadControlsFromDisk, recordActivity, recordAIRecommendation } from "@greenarmor/ges-core";
|
|
12
|
+
import { addFrameworkToConfig, removeFrameworkFromConfig, loadControlsFromDisk, getInstalledPackIds, recordActivity, recordAIRecommendation } from "@greenarmor/ges-core";
|
|
13
13
|
import { ProjectConfigSchema } from "@greenarmor/ges-core";
|
|
14
14
|
import { generateComplianceDocs, generateSecurityDocs, generateConfigJson, generateMetadataJson, generateFrameworkVersionJson, generateScoreJson } from "@greenarmor/ges-doc-generator";
|
|
15
15
|
import { generateAllWorkflows } from "@greenarmor/ges-cicd-generator";
|
|
@@ -246,7 +246,7 @@ const TOOLS = [
|
|
|
246
246
|
},
|
|
247
247
|
{
|
|
248
248
|
name: "init_project",
|
|
249
|
-
description: "Initialize GESF in a project directory. Creates the .ges/ directory structure, compliance/security documentation, controls, CI/CD workflows, and configuration files.",
|
|
249
|
+
description: "Initialize GESF in a project directory. Creates the .ges/ directory structure, compliance/security documentation, controls, CI/CD workflows, and configuration files. Automatically installs the privacy pack for the specified country of origin.",
|
|
250
250
|
inputSchema: {
|
|
251
251
|
type: "object",
|
|
252
252
|
properties: {
|
|
@@ -254,11 +254,26 @@ const TOOLS = [
|
|
|
254
254
|
project_name: { type: "string", description: "Project name (defaults to directory name)." },
|
|
255
255
|
project_type: { type: "string", description: "Project type (saas, ai-application, mcp-server, blockchain, wallet, government-system, healthcare-system, event-platform, photo-storage-platform, vulnerability-scanner, generic-web-application, api-backend, mobile-application)." },
|
|
256
256
|
frameworks: { type: "string", description: "Comma-separated framework names (default: GDPR,OWASP,CIS,NIST)." },
|
|
257
|
+
country: { type: "string", description: "Country/region code of origin (e.g., BR, CA, US-CA, GB, CH, SG, PH, JP, KR, CN, IN, ZA, AE, SA, EU). Determines which privacy pack is auto-installed." },
|
|
258
|
+
additional_packs: { type: "string", description: "Comma-separated additional privacy pack IDs to install (e.g., uk-gdpr,br-lgpd). Optional." },
|
|
257
259
|
force: { type: "boolean", description: "Re-initialize even if GESF is already set up (default: false)." },
|
|
258
260
|
},
|
|
259
261
|
required: ["project_path"],
|
|
260
262
|
},
|
|
261
263
|
},
|
|
264
|
+
{
|
|
265
|
+
name: "suggest_packs",
|
|
266
|
+
description: "Analyze the project and recommend which privacy/compliance policy packs to install. Examines project type, country of origin, installed packs, codebase patterns (dependencies, file structure), and data processing indicators. Returns ranked recommendations with rationale. Does NOT install packs — use policy_install to act on suggestions.",
|
|
267
|
+
inputSchema: {
|
|
268
|
+
type: "object",
|
|
269
|
+
properties: {
|
|
270
|
+
project_path: { type: "string", description: "Absolute path to the project root." },
|
|
271
|
+
country: { type: "string", description: "Optional country/region code to factor into recommendations (e.g., BR, US-CA, EU)." },
|
|
272
|
+
project_type: { type: "string", description: "Optional project type override (if not set, reads from config or infers from codebase)." },
|
|
273
|
+
},
|
|
274
|
+
required: ["project_path"],
|
|
275
|
+
},
|
|
276
|
+
},
|
|
262
277
|
{
|
|
263
278
|
name: "run_scans",
|
|
264
279
|
description: "Run security scanner integrations on a project. Detects the ecosystem (Node.js, Python, etc.) and runs available scanners (npm audit, Trivy, Gitleaks, Semgrep, etc.) plus SBOM generation.",
|
|
@@ -2726,11 +2741,17 @@ export function handleRequest(request) {
|
|
|
2726
2741
|
const projectType = (args.project_type || "generic-web-application");
|
|
2727
2742
|
const frameworksStr = args.frameworks || DEFAULT_FRAMEWORKS.join(",");
|
|
2728
2743
|
const frameworks = frameworksStr.split(",").map(f => f.trim());
|
|
2744
|
+
const countryCode = (args.country || "").toUpperCase();
|
|
2745
|
+
const countryInfo = countryCode ? getCountryByCode(countryCode) : undefined;
|
|
2746
|
+
const additionalPackIds = args.additional_packs
|
|
2747
|
+
? String(args.additional_packs).split(",").map((s) => s.trim()).filter(Boolean)
|
|
2748
|
+
: [];
|
|
2729
2749
|
const now = new Date().toISOString();
|
|
2730
2750
|
const config = {
|
|
2731
2751
|
project_name: projectName,
|
|
2732
2752
|
project_type: projectType,
|
|
2733
2753
|
frameworks,
|
|
2754
|
+
country: countryCode || undefined,
|
|
2734
2755
|
requirements: {
|
|
2735
2756
|
encryption: { required: true },
|
|
2736
2757
|
mfa: { required: true },
|
|
@@ -2788,11 +2809,38 @@ export function handleRequest(request) {
|
|
|
2788
2809
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
2789
2810
|
fs.writeFileSync(filePath, doc.content);
|
|
2790
2811
|
}
|
|
2791
|
-
const
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2812
|
+
const installedPackIds = new Set();
|
|
2813
|
+
// Domain packs from project type
|
|
2814
|
+
const projectPacks = getPacksForProjectType(projectType);
|
|
2815
|
+
const fwLower = new Set(frameworks.map((f) => f.toLowerCase()));
|
|
2816
|
+
const DOMAIN_PACKS = new Set(["ai", "blockchain", "government"]);
|
|
2817
|
+
for (const pack of projectPacks) {
|
|
2818
|
+
if (DOMAIN_PACKS.has(pack.id.toLowerCase()) || fwLower.has(pack.id.toLowerCase())) {
|
|
2819
|
+
installedPackIds.add(pack.id);
|
|
2820
|
+
}
|
|
2821
|
+
}
|
|
2822
|
+
// Privacy core (always installed)
|
|
2823
|
+
installedPackIds.add("privacy-core");
|
|
2824
|
+
// Country privacy pack (auto-selected)
|
|
2825
|
+
if (countryInfo) {
|
|
2826
|
+
installedPackIds.add(countryInfo.packId);
|
|
2827
|
+
}
|
|
2828
|
+
else if (countryCode === "EU") {
|
|
2829
|
+
installedPackIds.add("gdpr");
|
|
2830
|
+
}
|
|
2831
|
+
// Additional user-selected packs
|
|
2832
|
+
for (const packId of additionalPackIds) {
|
|
2833
|
+
installedPackIds.add(packId);
|
|
2834
|
+
}
|
|
2835
|
+
const packs = [];
|
|
2836
|
+
for (const packId of installedPackIds) {
|
|
2837
|
+
const pack = getPack(packId);
|
|
2838
|
+
if (pack) {
|
|
2839
|
+
const packDir = path.join(projectPath, CONTROLS_DIR, pack.id);
|
|
2840
|
+
fs.mkdirSync(packDir, { recursive: true });
|
|
2841
|
+
fs.writeFileSync(path.join(packDir, "controls.json"), JSON.stringify(pack.controls, null, 2));
|
|
2842
|
+
packs.push(pack);
|
|
2843
|
+
}
|
|
2796
2844
|
}
|
|
2797
2845
|
const workflows = generateAllWorkflows(config);
|
|
2798
2846
|
const workflowsDir = path.join(projectPath, ".github", "workflows");
|
|
@@ -2805,6 +2853,12 @@ export function handleRequest(request) {
|
|
|
2805
2853
|
lines.push(`**Project**: ${projectName}`);
|
|
2806
2854
|
lines.push(`**Type**: ${projectType}`);
|
|
2807
2855
|
lines.push(`**Frameworks**: ${frameworks.join(", ")}`);
|
|
2856
|
+
if (countryInfo) {
|
|
2857
|
+
lines.push(`**Country**: ${countryInfo.name} — ${countryInfo.lawName}`);
|
|
2858
|
+
}
|
|
2859
|
+
else if (countryCode === "EU") {
|
|
2860
|
+
lines.push(`**Region**: European Union (EU GDPR)`);
|
|
2861
|
+
}
|
|
2808
2862
|
lines.push(`**Path**: ${projectPath}\n`);
|
|
2809
2863
|
lines.push(`## Created Structure`);
|
|
2810
2864
|
lines.push(`- \`.ges/\` — Configuration and score files`);
|
|
@@ -2823,11 +2877,196 @@ export function handleRequest(request) {
|
|
|
2823
2877
|
source: "mcp",
|
|
2824
2878
|
action: "init",
|
|
2825
2879
|
title: `Project initialized: ${projectName}`,
|
|
2826
|
-
description: `Initialized GESF for ${projectType} project with frameworks: ${frameworks.join(", ")}. Installed ${packs.length} policy packs.`,
|
|
2827
|
-
details: { packs_affected: packs.map(p => p.id), frameworks_added: frameworks.map(f => String(f)) },
|
|
2880
|
+
description: `Initialized GESF for ${projectType} project${countryInfo ? ` in ${countryInfo.name}` : ""} with frameworks: ${frameworks.join(", ")}. Installed ${packs.length} policy packs: ${packs.map(p => p.id).join(", ")}.`,
|
|
2881
|
+
details: { packs_affected: packs.map(p => p.id), frameworks_added: frameworks.map(f => String(f)), country: countryCode || undefined },
|
|
2828
2882
|
});
|
|
2829
2883
|
break;
|
|
2830
2884
|
}
|
|
2885
|
+
case "suggest_packs": {
|
|
2886
|
+
const projectPath = resolveProjectPath(args.project_path);
|
|
2887
|
+
if (!fs.existsSync(projectPath)) {
|
|
2888
|
+
resultText = `Project path does not exist: ${projectPath}`;
|
|
2889
|
+
break;
|
|
2890
|
+
}
|
|
2891
|
+
const allPacks = getAllPacks();
|
|
2892
|
+
const allPackIds = new Set(allPacks.map(p => p.id));
|
|
2893
|
+
// Read existing config
|
|
2894
|
+
const configPath = path.join(projectPath, GES_DIR, "config.json");
|
|
2895
|
+
let existingConfig = null;
|
|
2896
|
+
let detectedCountry = "";
|
|
2897
|
+
let detectedProjectType = "";
|
|
2898
|
+
if (fs.existsSync(configPath)) {
|
|
2899
|
+
try {
|
|
2900
|
+
const parsed = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
2901
|
+
existingConfig = parsed;
|
|
2902
|
+
detectedCountry = parsed.country || "";
|
|
2903
|
+
detectedProjectType = parsed.project_type;
|
|
2904
|
+
}
|
|
2905
|
+
catch { /* ignore parse errors */ }
|
|
2906
|
+
}
|
|
2907
|
+
// Override with args
|
|
2908
|
+
if (args.country)
|
|
2909
|
+
detectedCountry = String(args.country).toUpperCase();
|
|
2910
|
+
if (args.project_type)
|
|
2911
|
+
detectedProjectType = String(args.project_type);
|
|
2912
|
+
// Already installed packs
|
|
2913
|
+
const installedPackIdsSet = getInstalledPackIds(projectPath);
|
|
2914
|
+
const installedPackIds = [...installedPackIdsSet];
|
|
2915
|
+
const installedSet = installedPackIdsSet;
|
|
2916
|
+
// Codebase analysis
|
|
2917
|
+
const codebaseIndicators = [];
|
|
2918
|
+
const recommendations = [];
|
|
2919
|
+
// Check for package.json (Node.js)
|
|
2920
|
+
const pkgJsonPath = path.join(projectPath, "package.json");
|
|
2921
|
+
let hasAI = false, hasBlockchain = false, hasHealthcare = false;
|
|
2922
|
+
if (fs.existsSync(pkgJsonPath)) {
|
|
2923
|
+
codebaseIndicators.push("Node.js project (package.json detected)");
|
|
2924
|
+
try {
|
|
2925
|
+
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, "utf-8"));
|
|
2926
|
+
const allDeps = Object.keys({ ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) });
|
|
2927
|
+
const depLower = allDeps.join(" ").toLowerCase();
|
|
2928
|
+
if (depLower.includes("openai") || depLower.includes("langchain") || depLower.includes("anthropic") || depLower.includes("llm") || depLower.includes("ai-sdk")) {
|
|
2929
|
+
hasAI = true;
|
|
2930
|
+
codebaseIndicators.push("AI/LLM dependencies detected (openai/langchain/anthropic)");
|
|
2931
|
+
}
|
|
2932
|
+
if (depLower.includes("ethers") || depLower.includes("web3") || depLower.includes("solana") || depLower.includes("hardhat")) {
|
|
2933
|
+
hasBlockchain = true;
|
|
2934
|
+
codebaseIndicators.push("Blockchain dependencies detected (ethers/web3/hardhat)");
|
|
2935
|
+
}
|
|
2936
|
+
if (depLower.includes("fhir") || depLower.includes("hl7") || depLower.includes("medical")) {
|
|
2937
|
+
hasHealthcare = true;
|
|
2938
|
+
codebaseIndicators.push("Healthcare dependencies detected");
|
|
2939
|
+
}
|
|
2940
|
+
}
|
|
2941
|
+
catch { /* ignore */ }
|
|
2942
|
+
}
|
|
2943
|
+
// Check for Python
|
|
2944
|
+
const reqPath = path.join(projectPath, "requirements.txt");
|
|
2945
|
+
const pyprojPath = path.join(projectPath, "pyproject.toml");
|
|
2946
|
+
if (fs.existsSync(reqPath) || fs.existsSync(pyprojPath)) {
|
|
2947
|
+
codebaseIndicators.push("Python project detected");
|
|
2948
|
+
try {
|
|
2949
|
+
const pyContent = fs.existsSync(reqPath)
|
|
2950
|
+
? fs.readFileSync(reqPath, "utf-8").toLowerCase()
|
|
2951
|
+
: fs.readFileSync(pyprojPath, "utf-8").toLowerCase();
|
|
2952
|
+
if (pyContent.includes("openai") || pyContent.includes("langchain") || pyContent.includes("anthropic") || pyContent.includes("torch")) {
|
|
2953
|
+
hasAI = true;
|
|
2954
|
+
codebaseIndicators.push("AI/ML Python dependencies detected");
|
|
2955
|
+
}
|
|
2956
|
+
}
|
|
2957
|
+
catch { /* ignore */ }
|
|
2958
|
+
}
|
|
2959
|
+
// Check for mobile
|
|
2960
|
+
if (fs.existsSync(path.join(projectPath, "android")) || fs.existsSync(path.join(projectPath, "ios"))) {
|
|
2961
|
+
codebaseIndicators.push("Mobile project detected (android/ios directories)");
|
|
2962
|
+
}
|
|
2963
|
+
// Check for Docker/deployment (indicates production data processing)
|
|
2964
|
+
if (fs.existsSync(path.join(projectPath, "Dockerfile")) || fs.existsSync(path.join(projectPath, "docker-compose.yml"))) {
|
|
2965
|
+
codebaseIndicators.push("Docker deployment detected (likely processes personal data in production)");
|
|
2966
|
+
}
|
|
2967
|
+
// --- Build recommendations ---
|
|
2968
|
+
// 1. Privacy core (always recommended)
|
|
2969
|
+
if (!installedSet.has("privacy-core")) {
|
|
2970
|
+
recommendations.push({ packId: "privacy-core", reason: "Universal baseline privacy controls (10 domains, 40 controls). Applicable to any project processing personal data.", priority: "critical" });
|
|
2971
|
+
}
|
|
2972
|
+
// 2. Country pack
|
|
2973
|
+
if (detectedCountry) {
|
|
2974
|
+
const countryInfo = getCountryByCode(detectedCountry);
|
|
2975
|
+
if (countryInfo) {
|
|
2976
|
+
if (!installedSet.has(countryInfo.packId)) {
|
|
2977
|
+
recommendations.push({ packId: countryInfo.packId, reason: `${countryInfo.name} privacy law: ${countryInfo.lawName}. Required for compliance with ${countryInfo.regulator}.`, priority: "critical" });
|
|
2978
|
+
}
|
|
2979
|
+
}
|
|
2980
|
+
else if (detectedCountry === "EU") {
|
|
2981
|
+
if (!installedSet.has("gdpr")) {
|
|
2982
|
+
recommendations.push({ packId: "gdpr", reason: "EU GDPR is the baseline for all European Economic Area data protection.", priority: "critical" });
|
|
2983
|
+
}
|
|
2984
|
+
}
|
|
2985
|
+
}
|
|
2986
|
+
// 3. AI pack
|
|
2987
|
+
if (hasAI && !installedSet.has("ai")) {
|
|
2988
|
+
recommendations.push({ packId: "ai", reason: "AI/LLM application detected. The AI policy pack adds controls for prompt logging, output validation, PII detection, and rate limiting.", priority: "high" });
|
|
2989
|
+
}
|
|
2990
|
+
// 4. Blockchain pack
|
|
2991
|
+
if (hasBlockchain && !installedSet.has("blockchain")) {
|
|
2992
|
+
recommendations.push({ packId: "blockchain", reason: "Blockchain application detected. Adds controls for cryptographic signatures, key rotation, and on-chain data protection.", priority: "high" });
|
|
2993
|
+
}
|
|
2994
|
+
// 5. HIPAA for healthcare
|
|
2995
|
+
if (hasHealthcare && !installedSet.has("hipaa")) {
|
|
2996
|
+
recommendations.push({ packId: "hipaa", reason: "Healthcare indicators detected. HIPAA controls are required for protected health information (PHI).", priority: "high" });
|
|
2997
|
+
}
|
|
2998
|
+
// 6. ISO 27001/27701 for production deployments
|
|
2999
|
+
if (!installedSet.has("iso27001") && codebaseIndicators.some(i => i.includes("Docker") || i.includes("production"))) {
|
|
3000
|
+
recommendations.push({ packId: "iso27001", reason: "Production deployment detected. ISO 27001 provides internationally recognized information security management controls.", priority: "medium" });
|
|
3001
|
+
}
|
|
3002
|
+
// 7. ISO 27701 (privacy extension)
|
|
3003
|
+
if (!installedSet.has("iso27701")) {
|
|
3004
|
+
recommendations.push({ packId: "iso27701", reason: "ISO 27701 extends ISO 27001 with privacy information management. Recommended for any organization acting as a data controller or processor.", priority: "medium" });
|
|
3005
|
+
}
|
|
3006
|
+
// --- Build output ---
|
|
3007
|
+
const lines = [];
|
|
3008
|
+
lines.push("# Policy Pack Recommendations\n");
|
|
3009
|
+
if (codebaseIndicators.length > 0) {
|
|
3010
|
+
lines.push("## Codebase Analysis");
|
|
3011
|
+
for (const indicator of codebaseIndicators) {
|
|
3012
|
+
lines.push(`- ${indicator}`);
|
|
3013
|
+
}
|
|
3014
|
+
lines.push("");
|
|
3015
|
+
}
|
|
3016
|
+
if (detectedCountry) {
|
|
3017
|
+
const countryInfo = getCountryByCode(detectedCountry);
|
|
3018
|
+
lines.push(`## Project Context`);
|
|
3019
|
+
lines.push(`- **Country/Region**: ${countryInfo ? `${countryInfo.name} (${detectedCountry})` : detectedCountry === "EU" ? "European Union" : detectedCountry}`);
|
|
3020
|
+
if (detectedProjectType)
|
|
3021
|
+
lines.push(`- **Project Type**: ${detectedProjectType}`);
|
|
3022
|
+
if (existingConfig)
|
|
3023
|
+
lines.push(`- **Frameworks Configured**: ${existingConfig.frameworks.join(", ")}`);
|
|
3024
|
+
lines.push("");
|
|
3025
|
+
}
|
|
3026
|
+
if (installedSet.size > 0) {
|
|
3027
|
+
lines.push(`## Already Installed (${installedPackIds.length} packs)`);
|
|
3028
|
+
lines.push(installedPackIds.map((id) => `- \`${id}\``).join("\n"));
|
|
3029
|
+
lines.push("");
|
|
3030
|
+
}
|
|
3031
|
+
if (recommendations.length === 0) {
|
|
3032
|
+
lines.push("## ✅ All Recommended Packs Installed");
|
|
3033
|
+
lines.push("No additional packs are recommended at this time. Your project has comprehensive coverage.");
|
|
3034
|
+
}
|
|
3035
|
+
else {
|
|
3036
|
+
const priorityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
3037
|
+
recommendations.sort((a, b) => priorityOrder[a.priority] - priorityOrder[b.priority]);
|
|
3038
|
+
lines.push(`## Recommended Packs (${recommendations.length})\n`);
|
|
3039
|
+
lines.push("| Priority | Pack ID | Reason |");
|
|
3040
|
+
lines.push("|----------|---------|--------|");
|
|
3041
|
+
for (const rec of recommendations) {
|
|
3042
|
+
const pack = allPacks.find(p => p.id === rec.packId);
|
|
3043
|
+
const packName = pack ? pack.name : rec.packId;
|
|
3044
|
+
lines.push(`| ${rec.priority.toUpperCase()} | \`${rec.packId}\` (${packName}) | ${rec.reason} |`);
|
|
3045
|
+
}
|
|
3046
|
+
lines.push("");
|
|
3047
|
+
lines.push("### How to Install");
|
|
3048
|
+
lines.push("Use `policy_install` with the pack ID:");
|
|
3049
|
+
for (const rec of recommendations.slice(0, 3)) {
|
|
3050
|
+
lines.push(`- \`policy_install\` with pack_id: \`${rec.packId}\``);
|
|
3051
|
+
}
|
|
3052
|
+
if (recommendations.length > 3) {
|
|
3053
|
+
lines.push(`- ... and ${recommendations.length - 3} more`);
|
|
3054
|
+
}
|
|
3055
|
+
}
|
|
3056
|
+
lines.push("");
|
|
3057
|
+
lines.push("### Available Country Packs");
|
|
3058
|
+
const grouped = PRIVACY_COUNTRIES.reduce((acc, c) => {
|
|
3059
|
+
if (!acc[c.region])
|
|
3060
|
+
acc[c.region] = [];
|
|
3061
|
+
acc[c.region].push(c);
|
|
3062
|
+
return acc;
|
|
3063
|
+
}, {});
|
|
3064
|
+
for (const [region, countries] of Object.entries(grouped)) {
|
|
3065
|
+
lines.push(`- **${region}**: ${countries.map(c => `\`${c.packId}\` (${c.name})`).join(", ")}`);
|
|
3066
|
+
}
|
|
3067
|
+
resultText = lines.join("\n");
|
|
3068
|
+
break;
|
|
3069
|
+
}
|
|
2831
3070
|
case "run_scans": {
|
|
2832
3071
|
const projectPath = resolveProjectPath(args.project_path);
|
|
2833
3072
|
if (!fs.existsSync(projectPath)) {
|
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.
|
|
7
|
-
"@greenarmor/ges-cicd-generator": "1.
|
|
8
|
-
"@greenarmor/ges-compliance-engine": "1.
|
|
9
|
-
"@greenarmor/ges-core": "1.
|
|
10
|
-
"@greenarmor/ges-doc-generator": "1.
|
|
11
|
-
"@greenarmor/ges-policy-engine": "1.
|
|
12
|
-
"@greenarmor/ges-report-generator": "1.
|
|
13
|
-
"@greenarmor/ges-rules-engine": "1.
|
|
14
|
-
"@greenarmor/ges-scanner-integration": "1.
|
|
15
|
-
"@greenarmor/ges-scoring-engine": "1.
|
|
16
|
-
"@greenarmor/ges-web-dashboard": "1.
|
|
6
|
+
"@greenarmor/ges-audit-engine": "1.3.0",
|
|
7
|
+
"@greenarmor/ges-cicd-generator": "1.3.0",
|
|
8
|
+
"@greenarmor/ges-compliance-engine": "1.3.0",
|
|
9
|
+
"@greenarmor/ges-core": "1.3.0",
|
|
10
|
+
"@greenarmor/ges-doc-generator": "1.3.0",
|
|
11
|
+
"@greenarmor/ges-policy-engine": "1.3.0",
|
|
12
|
+
"@greenarmor/ges-report-generator": "1.3.0",
|
|
13
|
+
"@greenarmor/ges-rules-engine": "1.3.0",
|
|
14
|
+
"@greenarmor/ges-scanner-integration": "1.3.0",
|
|
15
|
+
"@greenarmor/ges-scoring-engine": "1.3.0",
|
|
16
|
+
"@greenarmor/ges-web-dashboard": "1.3.0"
|
|
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.
|
|
70
|
+
"version": "1.3.0",
|
|
71
71
|
"scripts": {
|
|
72
72
|
"build": "tsc",
|
|
73
73
|
"clean": "rm -rf dist bundle tsconfig.tsbuildinfo",
|