Skip to main content
Glama
README.md
# Aegis šŸ›”ļø

[![NitroStack Framework](https://img.shields.io/badge/Framework-NitroStack_1.0-blueviolet?style=for-the-badge&logo=typescript)](https://nitrostack.ai)
[![MCP Server](https://img.shields.io/badge/Protocol-MCP-blue?style=for-the-badge)](https://modelcontextprotocol.io)
[![Zero Token Core](https://img.shields.io/badge/Detector_Cost-0_Tokens-brightgreen?style=for-the-badge)](https://groq.com)
[![Live Demo](https://img.shields.io/badge/Status-Live_on_NitroCloud-success?style=for-the-badge)](https://aegis-6a6d76ee-teamx-srmist.app.nitrocloud.ai/mcp)
[![License](https://img.shields.io/badge/License-MIT-green?style=for-the-badge)](LICENSE)

> **A Blast-Radius Auditor for AI Agents**
> *Track 03: Enterprise AI & Workplace Automation — NitroStack Hackathon*

Aegis is a Model Context Protocol (MCP) server built on **NitroStack** that audits the *combined* effective permissions of an AI agent across all connected tools. It deterministically detects toxic capability combinations and data-exfiltration vectors before deployment — **at zero LLM token cost**.

**šŸ”“ Live server:** `https://aegis-6a6d76ee-teamx-srmist.app.nitrocloud.ai/mcp` — connect it to Claude, ChatGPT, or NitroStack Studio and try the walkthrough below for real.

---

## šŸ“‹ Table of Contents

- [The Problem](#-the-problem)
- [See It Work](#-see-it-work)
- [System Architecture](#-system-architecture)
- [Detection & Remediation Lifecycle](#-detection--remediation-lifecycle)
- [Tool & Capability Registry](#-tool--capability-registry)
- [Toxic-Combination Policy Rules](#-toxic-combination-policy-rules)
- [MCP Interface Reference](#-mcp-interface-reference)
- [Try It Yourself](#-try-it-yourself)
- [Quickstart](#-quickstart)
- [FAQ](#-faq)
- [Project Structure](#-project-structure)

---

## šŸ† The Problem

Enterprises connect AI agents to dozens of tools — Gmail, Dropbox, Postgres databases, Slack, filesystem execution. Each integration gets approved individually on its own merits, but **nobody audits what the agent can do when tools are combined**.

```
  ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”        ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
  │  Dropbox MCP   │        │   Gmail MCP    │
  │ (Read Private) │        │ (Send External)│
  ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜        ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
          │                         │
          ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
                       ā–¼
         ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
         │      Support Agent      │
         ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
                       ā–¼
   🚨 TOXIC COMBINATION: DATA EXFILTRATION PATH
```

> [!WARNING]
> - `READ_PRIVATE_DATA` (Dropbox) + `SEND_EXTERNAL` (Gmail) = šŸ”“ **Data Exfiltration Path**
> - `READ_PRIVATE_DATA` (Postgres) + `WRITE_PUBLIC` (Slack) = 🟠 **Public Leak Path**
> - `DELETE_DATA` (Postgres) + `EXECUTE` (Filesystem) = 🟠 **Destructive Automation Vector**

This isn't hypothetical — it's how the **Supabase MCP leak** happened (an agent with legitimate database read access was steered via prompt injection into exfiltrating private records through an external channel), how the **`postmark-mcp` supply-chain compromise** turned an ordinary "send email" tool into a covert BCC-to-attacker exfiltration path, and the exact mechanism behind documented **tool-poisoning attacks**, where malicious instructions hidden in a tool's own description hijack agent behavior without ever calling an obviously malicious endpoint. Individually-reasonable permissions become dangerous the moment they're combined, and nothing in the stack today computes that union before it's exploited.

---

## šŸ“ø See It Work

Real, live-rendered screenshots — the actual widgets, fed the actual output of `get_capability_graph` / `detect_attack_paths` after connecting `gmail` + `dropbox` to one agent.

**The graph — dangerous capability paths render in red:**

![Capability graph showing a critical exfiltration path between Gmail and Dropbox](docs/screenshots/capability-graph-danger.png)

**The alert — severity, affected tools, and one-click remediation:**

![Attack path alert showing a critical exfiltration finding with a terminate button](docs/screenshots/attack-path-alert.png)

After clicking **Fix**, `apply_policy_fix` disconnects every tool supplying the sink capability and the graph goes back to `riskScore: 0` — no attack paths, clean state.

---

## šŸ“ System Architecture

```mermaid
flowchart TD
    subgraph Host["Chat Host / Client"]
        Client["User / AI Agent Host\n(NitroStudio, ChatGPT, Claude)"]
    end

    subgraph MCP["Aegis MCP Server (NitroStack)"]
        Tools["Governance Tools Controller\n(connect_tool, get_capability_graph,\ndetect_attack_paths, apply_policy_fix)"]
        Guard["OAuthGuard\n(scaffolded, opt-in via OAUTH_REQUIRED —\nopen by default for the hackathon build)"]
        Resources["Resource Server\n(aegis://policies)"]
        Prompts["Prompt Controller\n(explain_attack_path)"]

        Guard -. wraps connect_tool only .-> Tools
    end

    subgraph Engine["Deterministic Engine — 0 Tokens"]
        Registry["Tool Capability Registry\n(gmail, dropbox, postgres, slack,\nfilesystem, calendar)"]
        Store["Per-Agent Connected-Tool Store\n(in-memory)"]
        Union["Effective Capability Union\n(getEffectiveCapabilities)"]
        Detector["Policy Rule Matcher\n(detectAttackPaths)"]

        Registry --> Store --> Union --> Detector
    end

    subgraph UI["NitroStack Widgets"]
        GraphWidget["capability-graph\n(live risk graph)"]
        AlertWidget["attack-path-alert\n(severity + one-click Fix)"]
    end

    subgraph LLM["Groq Explanation Layer — only LLM spend"]
        Groq["Llama 3.1 8B Instant\ncached by SHA-256(ruleId + sorted(viaTools))"]
    end

    Client -->|STDIO / HTTP JSON-RPC| Tools
    Tools --> Engine
    Detector -->|risk score + danger edges| GraphWidget
    Detector -->|threat path list| AlertWidget
    Prompts -->|only on a detected path, cache miss| Groq
    Groq -->|plain-English finding| Client
    AlertWidget -->|Fix click| Tools
```

---

## šŸ”„ Detection & Remediation Lifecycle

```mermaid
flowchart LR
    A["1. Connect Gmail"] -->|connect_tool| B["READ_PRIVATE_DATA + SEND_EXTERNAL"]
    B --> C["🟢 SAFE — riskScore 0"]
    C --> D["2. Connect Dropbox"]
    D -->|connect_tool| E["+ WRITE_DATA"]
    E --> F["Detector checks policy table"]
    F -->|source+sink both present| G["🚨 exfiltration DETECTED"]
    G --> H["3. Render widgets"]
    H -->|get_capability_graph| I["Graph edge turns RED — riskScore 1"]
    H -->|explain_attack_path| J["Groq: plain-English summary"]
    I --> K["4. Remediate"]
    K -->|apply_policy_fix| L["Every tool supplying the sink\ncapability is disconnected"]
    L --> M["Status cleared — riskScore 0"]
```

---

## šŸ› ļø Tool & Capability Registry

| Tool | Tool ID | Granted Capabilities | Risk Profile |
|:---:|---|---|:---:|
| šŸ“§ | `gmail` | `READ_PRIVATE_DATA`, `SEND_EXTERNAL` | 🟠 High |
| šŸ“¦ | `dropbox` | `READ_PRIVATE_DATA`, `WRITE_DATA`, `SEND_EXTERNAL` | 🟠 High |
| šŸ—„ļø | `postgres` | `READ_PRIVATE_DATA`, `WRITE_DATA`, `DELETE_DATA` | šŸ”“ Critical |
| šŸ’¬ | `slack` | `WRITE_PUBLIC`, `SEND_EXTERNAL` | 🟔 Medium |
| šŸ’» | `filesystem` | `READ_PRIVATE_DATA`, `WRITE_DATA`, `EXECUTE` | šŸ”“ Critical |
| šŸ“… | `calendar` | `READ_PRIVATE_DATA`, `WRITE_DATA` | 🟢 Low |

## šŸŽÆ Toxic-Combination Policy Rules

| Rule ID | Source | Sink | Severity | Violation |
|---|---|---|:---:|---|
| `exfiltration` | `READ_PRIVATE_DATA` | `SEND_EXTERNAL` | šŸ”“ **Critical** | Agent can read private data AND transmit it externally. |
| `public-leak` | `READ_PRIVATE_DATA` | `WRITE_PUBLIC` | 🟠 **High** | Agent can read private records AND post them publicly. |
| `destructive` | `DELETE_DATA` | `EXECUTE` | 🟠 **High** | Agent can delete data AND execute unvalidated actions. |

Both tables are just data (`TOOL_REGISTRY` and `POLICY_RULES`) — adding a 7th tool or a 4th rule is a one-line change, not new logic.

---

## šŸ”Œ MCP Interface Reference

**Tools**
- **`connect_tool`** — connects a tool (`gmail`, `dropbox`, `postgres`, `slack`, `filesystem`, `calendar`) to an agent. Wrapped in `OAuthGuard` (scaffolded — enforced only if `OAUTH_REQUIRED=true` is set; open by default for local/demo use).
- **`get_capability_graph`** — `@Widget('capability-graph')`. Returns nodes, danger edges, active attack paths, and risk score.
- **`detect_attack_paths`** — `@Widget('attack-path-alert')`. Runs the deterministic rule engine.
- **`apply_policy_fix`** — disconnects every tool supplying a detected rule's sink capability.

**Resource**
- **`aegis://policies`** — the toxic-combination policy table as JSON.

**Prompt**
- **`explain_attack_path`** — takes `agentId` + `ruleId`, returns a plain-English explanation via Groq (`llama-3.1-8b-instant`). Only fires on an already-detected path, cached by `SHA-256(ruleId + sorted(viaTools))` — this is the *only* step in the entire system that spends a token.

### MCP surface map

```mermaid
flowchart LR
    Agent(("šŸ›”ļø Aegis"))

    Agent --> T1["šŸ”§ connect_tool"]
    Agent --> T2["šŸ”§ get_capability_graph"]
    Agent --> T3["šŸ”§ detect_attack_paths"]
    Agent --> T4["šŸ”§ apply_policy_fix"]
    Agent --> R1["šŸ“„ aegis://policies"]
    Agent --> P1["šŸ’¬ explain_attack_path"]

    T2 -.renders.-> W1["šŸŽØ capability-graph widget"]
    T3 -.renders.-> W2["šŸŽØ attack-path-alert widget"]
```

---

## ā–¶ļø Try It Yourself

Every step below works against the live server — no local setup needed. Connect `https://aegis-6a6d76ee-teamx-srmist.app.nitrocloud.ai/mcp` to Claude (Settings → Connectors → Add custom connector) or ChatGPT (Developer Mode → Plugins → Add), or point NitroStack Studio at this repo locally, then walk through the same scenario the screenshots above were taken from:

1. **Connect a tool.** *"Connect gmail to demo-agent."* → `connect_tool` fires. One tool, nothing alarming yet.
2. **Connect a second tool.** *"Now connect dropbox to demo-agent."* → the agent can now both read private data and send it externally.
3. **See the risk.** *"Show me its capability graph."* → `get_capability_graph` renders — the exfiltration edge is red. This step is pure deterministic rule matching: zero LLM tokens spent to catch it.
4. **Get a plain-English explanation.** *"What does this mean?"* → `explain_attack_path` fires — the *only* step in the whole system that calls an LLM, and only because a rule already matched.
5. **Fix it.** *"Fix it."* → `apply_policy_fix` disconnects every tool supplying the dangerous capability. The graph goes back to `riskScore: 0`.

Use any `agentId` you like — it's just an in-memory key, not a real account.

---

## šŸš€ Quickstart (run it locally)

```bash
git clone https://github.com/prince-rai88/aegis-mcp.git
cd aegis-mcp
npm install
cp .env.example .env   # add GROQ_API_KEY — free at console.groq.com
npm run dev
```

Verify without any GUI:
```bash
bash scripts/test-mcp.sh
```

Or connect [NitroStack Studio](https://nitrostack.ai/studio) → **Add Server** → **Nitro Project** → select this folder, then run through the [walkthrough above](#-try-it-yourself) against your local server instead of the live one.

---

## ā“ FAQ

**Why deterministic rules instead of having the model decide what's risky?**
Because then the audit trail is "the model thought so." Detection here is a fixed rule table (`source capability → sink capability`), so every flag is reproducible and explainable without re-running an LLM.

**Does this scale beyond 6 tools and 3 rules?**
`TOOL_REGISTRY` and the policy rules are both just data — adding a 7th tool or a 4th rule is a one-line addition, not new logic.

**What does the LLM actually do, then?**
Only `explain_attack_path`, only after a rule has already fired, cached by `SHA-256(ruleId + sorted(viaTools))` so the same finding is never re-explained twice.

---

## šŸ“ Project Structure

```
aegis-mcp/
ā”œā”€ā”€ src/
│   ā”œā”€ā”€ app.module.ts                  # NitroStack root module
│   ā”œā”€ā”€ index.ts                       # Server bootstrap
│   ā”œā”€ā”€ modules/governance/            # Security governance engine
│   │   ā”œā”€ā”€ capability.ts              # Capability model + TOOL_REGISTRY
│   │   ā”œā”€ā”€ detector.ts                # 0-token deterministic detector
│   │   ā”œā”€ā”€ policies.ts                # Toxic-combination policy rules
│   │   ā”œā”€ā”€ oauth.guard.ts             # Scaffolded OAuth guard
│   │   ā”œā”€ā”€ governance.tools.ts        # The 4 MCP tools
│   │   ā”œā”€ā”€ governance.resources.ts    # aegis://policies
│   │   ā”œā”€ā”€ governance.prompts.ts      # Groq explanation prompt
│   │   └── governance.module.ts
│   └── widgets/app/
│       ā”œā”€ā”€ capability-graph/          # Capability graph widget
│       └── attack-path-alert/         # Attack path alert widget
ā”œā”€ā”€ docs/screenshots/                  # Real rendered widget screenshots
ā”œā”€ā”€ scripts/
│   ā”œā”€ā”€ test-mcp.sh                    # Stdio JSON-RPC smoke test
│   └── preview-widgets.html           # Local widget preview, no Studio needed
└── README.md
```

---

## šŸ“œ License

[MIT](LICENSE)

TDQS

A4.2/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: connect_tool adds capabilities, get_capability_graph inspects state, detect_attack_paths analyzes for risks, and apply_policy_fix remediates. There is no overlap or ambiguity.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern with underscore separation: connect_tool, get_capability_graph, detect_attack_paths, apply_policy_fix. The style is uniform and predictable.

Tool Count5/5

Four tools is well-scoped for a focused security/capability management server. Each tool covers a necessary step and none feel extraneous.

Completeness4/5

The set covers the core lifecycle: connect, inspect, detect, and remediate. The only minor gap is the lack of a direct 'disconnect_tool' independent of attack-path remediation, but apply_policy_fix effectively serves that purpose.

Maintenance

ActivityStale
ResponsivenessNo issues