@raghulm/aegis-mcp 1.0.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.
Files changed (3) hide show
  1. package/README.md +340 -0
  2. package/bin/aegis-mcp.js +164 -0
  3. package/package.json +39 -0
package/README.md ADDED
@@ -0,0 +1,340 @@
1
+ <div align="center">
2
+ <h1>šŸ›”ļø Aegis MCP Server</h1>
3
+ <p><b>Aegis MCP is an open-source, DevSecOps-focused Model Context Protocol server that allows AI agents to safely interact with cloud infrastructure, CI/CD systems, and security tooling.</b></p>
4
+
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
6
+ [![Python version](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)
7
+ [![MCP Protocol](https://img.shields.io/badge/MCP-Server-green.svg)](https://modelcontextprotocol.io/)
8
+ [![Docker](https://img.shields.io/badge/docker-ready-blue.svg)](https://www.docker.com/)
9
+ </div>
10
+
11
+ ---
12
+
13
+ **Aegis MCP Server** empowers AI assistants (like Claude, Cursor, and GitHub Copilot) to perform cloud architecture administration, security scanning, and network analyses directly from their execution environments. It wraps powerful underlying tools and SDKs into secure, audited MCP tool sets.
14
+
15
+ ---
16
+
17
+ ## šŸ“ø Demo in Action
18
+
19
+ ```text
20
+ AI Agent: "Check if any S3 bucket is publicly accessible"
21
+
22
+ Tool call → aws_check_s3_public_access
23
+ Result → bucket audit report
24
+ ```
25
+
26
+ <p align="center">
27
+ <img src="docs/demo-aegis.gif" width="900"/>
28
+ </p>
29
+
30
+ ---
31
+
32
+ ## 🌟 Key Features
33
+
34
+ - šŸš€ **FastMCP Server** — Exposes domain-specific tools for AWS, Kubernetes, security scanning, Git, network analysis, and CI/CD pipelines.
35
+ - šŸ” **Flexible Authorization** — JWT-based RBAC for production deployments; automatically disabled for local stdio sessions (Claude Desktop, Agent IDEs).
36
+ - šŸ“œ **Structured Audit Logging** — Emits clean JSON audit logs for every invocation, suitable for SIEM integrations.
37
+ - šŸ›  **Expandable Tooling** — Easily add new integrations. Includes ready-to-use scanners for dependencies, secrets, SSL/TLS certs, Semgrep, Trivy, and more.
38
+ - šŸ“¦ **Docker Ready** — Containerized deployment using a non-root runtime with built-in health checks.
39
+ - 🌐 **ASGI Integration** — FastAPI health endpoint alongside MCP streamable-http transport.
40
+
41
+ ---
42
+
43
+ ## šŸ“ Architecture
44
+
45
+ ```mermaid
46
+ flowchart TD
47
+ Client[MCP Client / AI Agent] -->|Tool Call| AuthZ[Auth & RBAC Layer]
48
+
49
+ subgraph aegis-mcp["Aegis MCP Server"]
50
+ AuthZ --> Audit[Audit Logger]
51
+ Audit --> ToolsLayer[Tool Dispatch Layer]
52
+ end
53
+
54
+ ToolsLayer --> AWS[AWS SDK]
55
+ ToolsLayer --> K8s[kubectl / K8s SDK]
56
+ ToolsLayer --> Sec[Trivy / Semgrep]
57
+ ToolsLayer --> Net[Nmap / SSL]
58
+ ToolsLayer --> Git[Git CLI]
59
+ ```
60
+
61
+ The server receives MCP tool-call requests over **streamable HTTP** or **stdio** transport. In HTTP mode, each request requires a JWT bearer token for authorization. In stdio mode (local usage), authorization is automatically disabled.
62
+
63
+ ---
64
+
65
+ ## šŸ“‚ Repository Structure
66
+
67
+ ```text
68
+ aegis-mcp/
69
+ │
70
+ ā”œā”€ā”€ server/
71
+ │ ā”œā”€ā”€ main.py
72
+ │ ā”œā”€ā”€ health.py
73
+ │ ā”œā”€ā”€ auth.py
74
+ │ └── tools/
75
+ │ ā”œā”€ā”€ aws/
76
+ │ ā”œā”€ā”€ kubernetes/
77
+ │ ā”œā”€ā”€ security/
78
+ │ └── network/
79
+ │
80
+ ā”œā”€ā”€ policies/
81
+ ā”œā”€ā”€ tests/
82
+ ā”œā”€ā”€ Dockerfile
83
+ └── run_stdio.py
84
+ ```
85
+
86
+ ---
87
+
88
+ ## 🧰 Available Tools
89
+
90
+ ### Example Tool Invocation
91
+
92
+ ```text
93
+ Tool: security_run_trivy_scan
94
+
95
+ Input:
96
+ image=nginx:latest
97
+
98
+ Output:
99
+ CRITICAL: 2
100
+ HIGH: 4
101
+ MEDIUM: 7
102
+ ```
103
+
104
+ ### Cloud & DevOps
105
+ | Tool | Description |
106
+ |------|-------------|
107
+ | `aws_list_ec2_instances` | List EC2 instances in a specific AWS region |
108
+ | `aws_check_s3_public_access` | Audit S3 buckets for public access settings |
109
+ | `k8s_list_pods` | List Kubernetes pods in a given namespace |
110
+ | `cicd_pipeline_status` | Fetch CI/CD pipeline execution status |
111
+ | `git_recent_commits` | Fetch recent commit history from the active Git repo |
112
+
113
+ ### Application Security & SAST
114
+ | Tool | Description |
115
+ |------|-------------|
116
+ | `security_semgrep_scan` | Run Semgrep SAST scan on a local directory or file |
117
+ | `security_run_trivy_scan` | Run Trivy vulnerability scan on a container image |
118
+ | `security_scan_secrets` | Scan files/directories for exposed secrets |
119
+ | `security_check_dependencies` | Check dependency files for known CVEs via OSV.dev |
120
+
121
+ ### Network & Infrastructure Security
122
+ | Tool | Description |
123
+ |------|-------------|
124
+ | `k8s_security_audit` | Audit Kubernetes clusters (privileged containers, wildcard RBAC, etc.) |
125
+ | `network_port_scan` | TCP port scan to detect exposed services |
126
+ | `security_check_ssl_certificate` | Validate SSL/TLS certificate details and expiry |
127
+ | `security_check_http_headers` | Audit URLs for security headers (HSTS, CSP, etc.) |
128
+
129
+ > [!IMPORTANT]
130
+ > **SAST (Semgrep scan) works only on Agent IDEs (e.g., Antigravity, Cursor) or Claude Co-work.**
131
+ > It does **not** work on Claude Desktop due to Windows subprocess pipe limitations with `semgrep-core.exe`. All other tools (secrets scan, SSL check, port scan, etc.) work on all platforms including Claude Desktop.
132
+
133
+ ---
134
+
135
+ ## šŸš€ Getting Started
136
+
137
+ ### One-Command Install (NPX)
138
+
139
+ ```bash
140
+ npx @raghulm/aegis-mcp
141
+ ```
142
+
143
+ That's it. Aegis will:
144
+ 1. āœ… Check your Python version (3.12+ required)
145
+ 2. šŸ“„ Clone and install the server into `~/.aegis-mcp`
146
+ 3. šŸ–Øļø Print your ready-to-paste MCP config
147
+ 4. šŸš€ Start the server
148
+
149
+ **Additional commands:**
150
+
151
+ ```bash
152
+ npx @raghulm/aegis-mcp --install # Force reinstall / update
153
+ npx @raghulm/aegis-mcp --config # Print MCP config JSON only
154
+ npx @raghulm/aegis-mcp --help # Show all options
155
+ ```
156
+
157
+ ---
158
+
159
+ ### Prerequisites
160
+
161
+ - **Node.js 16+** (for NPX install)
162
+ - **Python 3.12+**
163
+ - **Git**
164
+ - **Semgrep** — `pip install semgrep` (for SAST scanning)
165
+ - Optional: AWS CLI / `boto3`, `kubectl`, Trivy (for their respective tools)
166
+
167
+ ### Manual Installation
168
+
169
+ ```bash
170
+ git clone https://github.com/raghulvj01/aegis-mcp.git
171
+ cd aegis-mcp
172
+
173
+ # Create virtual environment
174
+ python -m venv .venv
175
+
176
+ # Activate it
177
+ # Linux/Mac:
178
+ source .venv/bin/activate
179
+ # Windows:
180
+ .venv\Scripts\activate
181
+
182
+ # Install dependencies
183
+ pip install -r requirements.txt
184
+ ```
185
+
186
+ ---
187
+
188
+ ## šŸ¤– Usage with AI Agents
189
+
190
+ ### Agent IDE / Antigravity (Recommended)
191
+
192
+ Add to your MCP config (e.g., `mcp_config.json`):
193
+
194
+ ```json
195
+ {
196
+ "mcpServers": {
197
+ "aegis": {
198
+ "command": "c:\\path\\to\\aegis-mcp\\.venv\\Scripts\\python.exe",
199
+ "args": ["c:\\path\\to\\aegis-mcp\\run_stdio.py"]
200
+ }
201
+ }
202
+ }
203
+ ```
204
+
205
+ > āœ… **All 12 tools work**, including Semgrep SAST.
206
+
207
+ ### Claude Desktop
208
+
209
+ Add to `claude_desktop_config.json`:
210
+ - **Windows**: `%LOCALAPPDATA%\Packages\Claude_...\LocalCache\Roaming\Claude\`
211
+ - **Mac**: `~/Library/Application Support/Claude/`
212
+
213
+ ```json
214
+ {
215
+ "mcpServers": {
216
+ "aegis": {
217
+ "command": "c:\\path\\to\\aegis-mcp\\.venv\\Scripts\\python.exe",
218
+ "args": ["c:\\path\\to\\aegis-mcp\\run_stdio.py"]
219
+ }
220
+ }
221
+ }
222
+ ```
223
+
224
+ > āš ļø **11 of 12 tools work.** Semgrep SAST does not work due to Windows pipe limitations.
225
+
226
+ ### Cursor / Windsurf (HTTP Mode)
227
+
228
+ Start the server, then add to `.cursor/mcp.json`:
229
+
230
+ ```bash
231
+ uvicorn server.health:app --host 0.0.0.0 --port 8000
232
+ ```
233
+
234
+ ```json
235
+ {
236
+ "mcpServers": {
237
+ "aegis": {
238
+ "url": "http://localhost:8000/mcp"
239
+ }
240
+ }
241
+ }
242
+ ```
243
+
244
+ ### Docker Deployment
245
+
246
+ ```bash
247
+ docker build -t aegis-mcp .
248
+ docker run -p 8000:8000 aegis-mcp
249
+ ```
250
+
251
+ ---
252
+
253
+ ## āš™ļø Configuration
254
+
255
+ | Variable | Description | Default |
256
+ |----------|-------------|---------|
257
+ | `MCP_AUTH_DISABLED` | Disable JWT auth (auto-set for stdio) | `false` |
258
+ | `MCP_SERVICE_NAME` | Name of the MCP service | `aegis` |
259
+ | `MCP_ENV` | Environment (`dev`, `staging`, `prod`) | `dev` |
260
+ | `MCP_ROLES_FILE` | Path to roles policy YAML | `policies/roles.yaml` |
261
+ | `MCP_SCOPES_FILE` | Path to scopes policy YAML | `policies/scope_rules.yaml` |
262
+ | `OIDC_ISSUER` | Expected JWT `iss` claim | *None* |
263
+ | `OIDC_AUDIENCE` | Expected JWT `aud` claim | *None* |
264
+
265
+ ---
266
+
267
+ ## šŸ— Access Control
268
+
269
+ In **HTTP mode**, every tool requires a `token` argument containing a JWT. The authorization layer checks roles and scopes defined in `policies/roles.yaml` and `policies/scope_rules.yaml`.
270
+
271
+ In **stdio mode** (local usage via `run_stdio.py`), authorization is **automatically disabled** — no token required.
272
+
273
+ ### Policy Example (`policies/roles.yaml`)
274
+
275
+ ```yaml
276
+ roles:
277
+ viewer:
278
+ - aws_list_ec2_instances
279
+ - k8s_list_pods
280
+ security:
281
+ - security_run_trivy_scan
282
+ - security_semgrep_scan
283
+ admin:
284
+ - aws_list_ec2_instances
285
+ - k8s_list_pods
286
+ - security_run_trivy_scan
287
+ - security_semgrep_scan
288
+ # ... all tools
289
+ ```
290
+
291
+ ---
292
+
293
+ ## šŸ“ Audit Logging
294
+
295
+ The `@audit_tool_call` decorator emits structured JSON logs for every invocation:
296
+
297
+ ```json
298
+ {
299
+ "timestamp": "2026-03-06T08:00:01+00:00",
300
+ "level": "INFO",
301
+ "event": "tool_call_succeeded",
302
+ "tool": "security_run_trivy_scan",
303
+ "duration_ms": 1204
304
+ }
305
+ ```
306
+
307
+ ---
308
+
309
+ ## šŸ›”ļø Security Best Practices
310
+
311
+ 1. **Enforce JWT Signature Validation** — Update `server/auth.py` to verify RS256 JWTs using your IdP's JWKS endpoint for production.
312
+ 2. **Least-Privilege Credentials** — Assign ReadOnly IAM / K8s roles to the server environment.
313
+ 3. **Monitor Audit Logs** — Forward JSON logs to a SIEM. Set up anomaly detection for aggressive looping.
314
+
315
+ ---
316
+
317
+ ## šŸ›£ļø Roadmap
318
+
319
+ - [ ] Terraform security scanner
320
+ - [ ] IAM policy risk detection
321
+ - [ ] Kubernetes misconfiguration scanner (Basic `k8s_security_audit` implemented!)
322
+ - [ ] GitHub Actions security audit
323
+ - [ ] Cloud cost analysis tools
324
+
325
+ ---
326
+
327
+ ## šŸ¤ Contributing
328
+
329
+ 1. Fork the project
330
+ 2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
331
+ 3. Add your tool into `tools/<domain>/`
332
+ 4. Register it via `@mcp.tool()` in `server/main.py` with `@audit_tool_call` and auth check
333
+ 5. Add tests in `tests/`
334
+ 6. Open a Pull Request
335
+
336
+ ---
337
+
338
+ ## šŸ“„ License
339
+
340
+ Distributed under the MIT License. See `LICENSE` for more information.
@@ -0,0 +1,164 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { execSync, spawn } = require("child_process");
4
+ const fs = require("fs");
5
+ const path = require("path");
6
+ const os = require("os");
7
+
8
+ const REPO_URL = "https://github.com/raghulvj01/aegis-mcp.git";
9
+ const INSTALL_DIR = path.join(os.homedir(), ".aegis-mcp");
10
+ const VERSION = require("../package.json").version;
11
+
12
+ const colors = {
13
+ reset: "\x1b[0m",
14
+ cyan: "\x1b[36m",
15
+ green: "\x1b[32m",
16
+ yellow: "\x1b[33m",
17
+ red: "\x1b[31m",
18
+ bold: "\x1b[1m",
19
+ };
20
+
21
+ function log(msg, color = "reset") {
22
+ console.error(`${colors[color]}${msg}${colors.reset}`);
23
+ }
24
+
25
+ function banner() {
26
+ console.error(`
27
+ ${colors.cyan}${colors.bold}
28
+ šŸ›”ļø Aegis MCP Server v${VERSION}
29
+ Open-source DevSecOps MCP for AI Agents
30
+ ${colors.reset}`);
31
+ }
32
+
33
+ function checkPython() {
34
+ const candidates = ["python3", "python"];
35
+ for (const cmd of candidates) {
36
+ try {
37
+ const version = execSync(`${cmd} --version 2>&1`, { encoding: "utf8" }).trim();
38
+ const match = version.match(/Python (\d+)\.(\d+)/);
39
+ if (match && (parseInt(match[1]) > 3 || (parseInt(match[1]) === 3 && parseInt(match[2]) >= 12))) {
40
+ log(`āœ… Found ${version}`, "green");
41
+ return cmd;
42
+ } else if (match) {
43
+ log(`āš ļø Found ${version} but Python 3.12+ is required.`, "yellow");
44
+ }
45
+ } catch {}
46
+ }
47
+ log("āŒ Python 3.12+ not found. Please install it from https://python.org", "red");
48
+ process.exit(1);
49
+ }
50
+
51
+ function isInstalled() {
52
+ return (
53
+ fs.existsSync(INSTALL_DIR) &&
54
+ fs.existsSync(path.join(INSTALL_DIR, "run_stdio.py"))
55
+ );
56
+ }
57
+
58
+ function install(pythonCmd) {
59
+ log("šŸ“¦ Installing Aegis MCP...", "cyan");
60
+
61
+ if (fs.existsSync(INSTALL_DIR)) {
62
+ log("šŸ”„ Updating existing installation...", "yellow");
63
+ execSync("git pull", { cwd: INSTALL_DIR, stdio: "inherit" });
64
+ } else {
65
+ log(`šŸ“„ Cloning from ${REPO_URL}...`, "cyan");
66
+ execSync(`git clone ${REPO_URL} "${INSTALL_DIR}"`, { stdio: "inherit" });
67
+ }
68
+
69
+ log("šŸ“¦ Creating virtual environment...", "cyan");
70
+ execSync(`${pythonCmd} -m venv .venv`, { cwd: INSTALL_DIR, stdio: "inherit" });
71
+
72
+ const pip = process.platform === "win32"
73
+ ? path.join(INSTALL_DIR, ".venv", "Scripts", "pip.exe")
74
+ : path.join(INSTALL_DIR, ".venv", "bin", "pip");
75
+
76
+ log("šŸ“¦ Installing Python dependencies...", "cyan");
77
+ execSync(`"${pip}" install -r requirements.txt`, { cwd: INSTALL_DIR, stdio: "inherit" });
78
+
79
+ log("āœ… Aegis MCP installed successfully!", "green");
80
+ }
81
+
82
+ function run() {
83
+ const pythonExe = process.platform === "win32"
84
+ ? path.join(INSTALL_DIR, ".venv", "Scripts", "python.exe")
85
+ : path.join(INSTALL_DIR, ".venv", "bin", "python");
86
+
87
+ const scriptPath = path.join(INSTALL_DIR, "run_stdio.py");
88
+
89
+ log("šŸš€ Starting Aegis MCP Server...\n", "green");
90
+
91
+ const child = spawn(pythonExe, [scriptPath], {
92
+ stdio: "inherit",
93
+ env: { ...process.env, MCP_AUTH_DISABLED: "true" },
94
+ });
95
+
96
+ child.on("error", (err) => {
97
+ log(`\nāŒ Failed to start Aegis MCP: ${err.message}`, "red");
98
+ process.exit(1);
99
+ });
100
+
101
+ child.on("exit", (code) => {
102
+ process.exit(code || 0);
103
+ });
104
+
105
+ process.on("SIGINT", () => child.kill("SIGINT"));
106
+ process.on("SIGTERM", () => child.kill("SIGTERM"));
107
+ }
108
+
109
+ function printMCPConfig() {
110
+ const pythonExe = process.platform === "win32"
111
+ ? path.join(INSTALL_DIR, ".venv", "Scripts", "python.exe")
112
+ : path.join(INSTALL_DIR, ".venv", "bin", "python");
113
+
114
+ const scriptPath = path.join(INSTALL_DIR, "run_stdio.py");
115
+
116
+ log("\nšŸ“‹ Add this to your MCP config (claude_desktop_config.json / mcp_config.json):\n", "cyan");
117
+ console.error(JSON.stringify({
118
+ mcpServers: {
119
+ aegis: {
120
+ command: pythonExe,
121
+ args: [scriptPath],
122
+ },
123
+ },
124
+ }, null, 2));
125
+ console.error();
126
+ }
127
+
128
+ // ── Main ──────────────────────────────────────────────────────────────────────
129
+
130
+ const args = process.argv.slice(2);
131
+
132
+ banner();
133
+
134
+ if (args.includes("--help") || args.includes("-h")) {
135
+ console.error(`Usage: npx aegis-mcp [options]
136
+
137
+ Options:
138
+ (no args) Install (if needed) and start the MCP server
139
+ --install Force reinstall
140
+ --config Print MCP config JSON and exit
141
+ --version, -v Show version
142
+ --help, -h Show this help
143
+ `);
144
+ process.exit(0);
145
+ }
146
+
147
+ if (args.includes("--version") || args.includes("-v")) {
148
+ console.log(VERSION);
149
+ process.exit(0);
150
+ }
151
+
152
+ const pythonCmd = checkPython();
153
+
154
+ if (args.includes("--install") || !isInstalled()) {
155
+ install(pythonCmd);
156
+ }
157
+
158
+ if (args.includes("--config")) {
159
+ printMCPConfig();
160
+ process.exit(0);
161
+ }
162
+
163
+ printMCPConfig();
164
+ run();
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@raghulm/aegis-mcp",
3
+ "version": "1.0.0",
4
+ "description": "šŸ›”ļø Open-source DevSecOps MCP server — gives AI agents real hands in your cloud infrastructure",
5
+ "homepage": "https://github.com/raghulvj01/aegis-mcp",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/raghulvj01/aegis-mcp.git"
9
+ },
10
+ "bugs": {
11
+ "url": "https://github.com/raghulvj01/aegis-mcp/issues"
12
+ },
13
+ "author": "Raghul VJ <raghulvj01@gmail.com>",
14
+ "license": "MIT",
15
+ "keywords": [
16
+ "mcp",
17
+ "devsecops",
18
+ "aws",
19
+ "kubernetes",
20
+ "security",
21
+ "ai-agents",
22
+ "claude",
23
+ "trivy",
24
+ "semgrep",
25
+ "open-source",
26
+ "fastmcp",
27
+ "docker",
28
+ "cloud-security"
29
+ ],
30
+ "bin": {
31
+ "aegis-mcp": "bin/aegis-mcp.js"
32
+ },
33
+ "engines": {
34
+ "node": ">=16.0.0"
35
+ },
36
+ "files": [
37
+ "bin/"
38
+ ]
39
+ }