Aegis
A blast-radius auditor for AI agents that computes combined effective permissions across all connected MCP tools, detects dangerous capability combinations deterministically, and provides a live risk graph and one-click policy fixes.
README
Aegis 🛡️
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
- See It Work
- System Architecture
- Detection & Remediation Lifecycle
- Tool & Capability Registry
- Toxic-Combination Policy Rules
- MCP Interface Reference
- Try It Yourself
- Quickstart
- FAQ
- 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 PathREAD_PRIVATE_DATA(Postgres) +WRITE_PUBLIC(Slack) = 🟠 Public Leak PathDELETE_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:

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

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
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
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 inOAuthGuard(scaffolded — enforced only ifOAUTH_REQUIRED=trueis 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— takesagentId+ruleId, returns a plain-English explanation via Groq (llama-3.1-8b-instant). Only fires on an already-detected path, cached bySHA-256(ruleId + sorted(viaTools))— this is the only step in the entire system that spends a token.
MCP surface map
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:
- Connect a tool. "Connect gmail to demo-agent." →
connect_toolfires. One tool, nothing alarming yet. - Connect a second tool. "Now connect dropbox to demo-agent." → the agent can now both read private data and send it externally.
- See the risk. "Show me its capability graph." →
get_capability_graphrenders — the exfiltration edge is red. This step is pure deterministic rule matching: zero LLM tokens spent to catch it. - Get a plain-English explanation. "What does this mean?" →
explain_attack_pathfires — the only step in the whole system that calls an LLM, and only because a rule already matched. - Fix it. "Fix it." →
apply_policy_fixdisconnects every tool supplying the dangerous capability. The graph goes back toriskScore: 0.
Use any agentId you like — it's just an in-memory key, not a real account.
🚀 Quickstart (run it locally)
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 scripts/test-mcp.sh
Or connect NitroStack Studio → Add Server → Nitro Project → select this folder, then run through the walkthrough above 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
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。