Metadata-Version: 2.4
Name: mcpshield-runtime
Version: 0.1.2
Summary: Secure MCP runtime — policy enforcement, SSRF blocking, audit logging
Author: Sri Sowmya Nemani
Project-URL: Homepage, https://github.com/srisowmya2000/mcp-shield
Project-URL: Repository, https://github.com/srisowmya2000/mcp-shield
Keywords: mcp,security,ssrf,llm,agent,policy,sandbox
Classifier: Development Status :: 3 - Alpha
Classifier: Topic :: Security
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.12
Description-Content-Type: text/markdown
Requires-Dist: fastapi>=0.115
Requires-Dist: uvicorn>=0.30
Requires-Dist: pydantic>=2.0
Requires-Dist: pydantic-settings>=2.0
Requires-Dist: typer>=0.12
Requires-Dist: mcp>=1.0
Requires-Dist: httpx>=0.27
Requires-Dist: pyyaml>=6.0
Requires-Dist: rich>=13.0

# mcp-shield 🛡️

> **The security runtime for MCP servers.**
> Every tool call inspected. Every attack blocked. Every decision logged.

![Python](https://img.shields.io/badge/python-3.12-blue?style=flat-square)
![PyPI](https://img.shields.io/pypi/v/mcpshield-runtime?style=flat-square)
![Tests](https://img.shields.io/badge/tests-12%20passing-brightgreen?style=flat-square)
![Status](https://img.shields.io/badge/status-active-success?style=flat-square)

---

## What is MCP?

**Model Context Protocol (MCP)** is an open standard that lets AI assistants
(Claude, Cursor, Copilot) connect to external tools and services — file systems,
APIs, databases, browsers — through **MCP servers**.

Think of MCP servers as plugins that give AI agents real-world capabilities.

---

## The Problem

MCP servers run as **trusted processes** on your machine with broad access:

| Access | Risk |
|---|---|
| 🗂️ Filesystem | Read `/etc/passwd`, steal SSH keys |
| 🌐 Network | SSRF to `169.254.169.254` (AWS metadata endpoint) |
| 🔑 Environment variables | Steal API keys, tokens, secrets |
| ⚙️ Shell | Execute arbitrary commands |

**A malicious or compromised MCP server can silently exfiltrate your secrets,
pivot to internal infrastructure, or execute code — and you'd never know.**

This is not theoretical. A real SSRF vulnerability was found in an MCP OAuth
HTTP transport implementation that allowed exactly this class of attack.

---

## How mcp-shield Fixes This

mcp-shield sits **between your AI agent and the MCP server** as a policy
enforcement layer. Before any tool executes, mcp-shield evaluates it.
If it's not explicitly allowed — it's blocked.

```
AI Agent
   │
   ▼
mcp-shield /inspect
   │
   ├── Tool allowlist check      →  "read_secrets" not in allowlist  → 🚫 BLOCK
   ├── Blocked pattern check     →  "ssrf_fetch" is dangerous        → 🚫 BLOCK
   ├── Argument scanning         →  "169.254.169.254" in args        → 🚫 BLOCK
   │   (recursive, nested dicts)
   └── Passed all checks         →  ✅ ALLOW → MCP Server executes
                                          │
                                          ▼
                                     Audit Log (SQLite)
                              timestamp | server | tool | decision | reason
```

---

## Install

```bash
pip install mcpshield-runtime
```

Or clone and run locally:

```bash
git clone https://github.com/srisowmya2000/mcp-shield
cd mcp-shield
python3 -m venv .venv && source .venv/bin/activate
pip install fastapi uvicorn pydantic pydantic-settings mcp httpx pyyaml rich
uvicorn runtime.api.main:app --reload
```

Open:
- **API docs** → http://localhost:8000/docs
- **Live dashboard** → http://localhost:8000/dashboard

---

## Live Demo

```bash
# Start mcp-shield
uvicorn runtime.api.main:app --reload

# 🚫 Attempt secret theft → BLOCKED
curl -X POST http://localhost:8000/inspect \
  -H "Content-Type: application/json" \
  -d '{"server_name":"evil","policy":"default","tool_call":{"tool_name":"read_secrets","arguments":{}}}'
# → {"decision":"BLOCK","reason":"Tool 'read_secrets' is not in the allowed_tools list","blocked":true}

# 🚫 Attempt SSRF to AWS metadata endpoint → BLOCKED
curl -X POST http://localhost:8000/inspect \
  -H "Content-Type: application/json" \
  -d '{"server_name":"evil","policy":"default","tool_call":{"tool_name":"ssrf_fetch","arguments":{"url":"http://169.254.169.254/latest/meta-data/"}}}'
# → {"decision":"BLOCK","reason":"Argument contains blocked pattern: '169.254.169.254'","blocked":true}

# ✅ Safe tool → ALLOWED
curl -X POST http://localhost:8000/inspect \
  -H "Content-Type: application/json" \
  -d '{"server_name":"safe","policy":"default","tool_call":{"tool_name":"safe_tool","arguments":{"name":"Sri"}}}'
# → {"decision":"ALLOW","reason":"Passed all policy checks","blocked":false}
```

---

## CLI

```bash
# Inspect a tool call
python3 -m runtime.cli inspect read_secrets
# → 🚫 BLOCKED — Tool 'read_secrets' is not in the allowed_tools list

python3 -m runtime.cli inspect safe_tool
# → ✅ ALLOWED — Passed all policy checks

# Score a server's risk level
python3 -m runtime.cli risk "read_secrets,ssrf_fetch,safe_tool"
# → 🔴 HIGH RISK (score: 80)
# → High-risk tools: ['read_secrets', 'ssrf_fetch']
# → Do not run without strict policy. Use isolated network.

# View live audit log
python3 -m runtime.cli audit

# View stats
python3 -m runtime.cli stats
# → Total: 6 | ✅ Allowed: 2 | 🚫 Blocked: 4 (67% block rate)
```

---

## Policies

Drop a YAML file in `policies/` and reference it by name in any `/inspect` call.

```yaml
# policies/default.yaml
allowed_tools:
  - safe_tool
  - list_files
  - get_time

block_network: true
block_env_access: true

blocked_arg_patterns:
  - "169.254.169.254"   # AWS metadata SSRF
  - "169.254.170.2"     # ECS metadata SSRF
  - "localhost"
  - "127.0.0.1"
  - "/etc/passwd"
  - "/etc/shadow"
  - "file://"
  - "gopher://"

max_memory_mb: 256
execution_timeout_seconds: 30
```

Switch policy per server:
```bash
POST /inspect  →  { "policy": "strict", ... }
```

Two policies included: `default` and `strict` (zero-trust).

---

## Features

| Feature | Description |
|---|---|
| 🔒 **Policy Engine** | YAML allowlists + blocked patterns, per-server policies |
| 🔍 **Argument Scanning** | Recursively scans nested args for SSRF, path traversal, dangerous patterns |
| 📋 **Audit Logger** | Every decision logged to SQLite — timestamp, server, tool, reason |
| 🐳 **Docker Sandbox** | Hardened containers: `--cap-drop=ALL`, `--network=none`, `--read-only` |
| 🔥 **Firecracker Backend** | microVM isolation — each server gets its own Linux kernel (Linux/KVM only) |
| 📊 **Risk Scorer** | Scores MCP servers LOW / MEDIUM / HIGH based on tool capabilities |
| 🖥️ **Live Dashboard** | Real-time web UI at `/dashboard` — live block/allow feed, flash animations |
| ⚡ **CLI** | `mcpshield inspect`, `audit`, `stats`, `risk` with rich colored output |

---

## API Reference

| Endpoint | Method | Description |
|---|---|---|
| `/health` | GET | Service health check |
| `/inspect` | POST | Evaluate tool call → ALLOW / BLOCK |
| `/audit` | GET | Recent audit log entries |
| `/audit/stats` | GET | Total / allowed / blocked counts |
| `/risk/score` | POST | Score server risk by tool list |
| `/sandbox/launch` | POST | Launch MCP server in hardened Docker container |
| `/sandbox/stop/{name}` | POST | Stop a running sandbox |
| `/sandbox/list` | GET | List running sandboxes |
| `/dashboard` | GET | Live real-time decision dashboard |
| `/docs` | GET | Interactive Swagger API docs |

---

## Docker Sandbox

Every MCP server launched via mcp-shield runs with:

```
--cap-drop=ALL          no Linux capabilities
--no-new-privileges     no privilege escalation
--read-only             immutable filesystem
--network=none          no network access
--memory=256m           memory limit
--cpus=0.5              CPU limit
--pids-limit=64         process limit
--tmpfs=/tmp            ephemeral tmp only
```

---

## Firecracker microVM Backend

For stronger isolation, mcp-shield supports **Firecracker microVMs** —
each MCP server gets its own Linux kernel. A kernel exploit inside the
VM cannot reach the host.

```
Docker:       shared kernel → kernel exploit = host at risk
Firecracker:  own kernel    → kernel exploit = contained in VM
```

Requires Linux with KVM. See [docs/firecracker-setup.md](docs/firecracker-setup.md).

---

## Architecture

```
mcp-shield/
├── runtime/
│   ├── api/
│   │   └── main.py              # FastAPI — all endpoints
│   ├── policy_engine.py         # YAML policy loader + evaluator
│   ├── audit_logger.py          # SQLite decision log
│   ├── risk_scorer.py           # LOW/MEDIUM/HIGH risk scoring
│   ├── cli.py                   # Typer CLI
│   ├── models.py                # Pydantic schemas
│   └── sandbox/
│       ├── base.py              # Abstract backend interface
│       ├── docker_backend.py    # Hardened Docker sandbox
│       └── firecracker_backend.py  # microVM backend (Linux/KVM)
├── policies/
│   ├── default.yaml
│   └── strict.yaml
├── examples/
│   ├── malicious_mcp_server/    # Demo attacker (SSRF + secret theft + exec)
│   └── safe_mcp_server/         # Demo benign server
├── docs/
│   ├── threat-model.md          # Attack scenarios + limitations
│   └── firecracker-setup.md     # Firecracker setup guide
└── tests/                       # 12 tests — all passing
```

---

## Tests

```bash
pip install pytest
pytest tests/ -v
# 12 passed in 0.11s
```

Covers: tool allowlist blocking, SSRF argument detection, nested arg scanning,
strict policy enforcement, edge cases, unknown policy handling.

---

## Threat Model

See [docs/threat-model.md](docs/threat-model.md) for:
- Attack scenarios (SSRF, secret theft, command execution, path traversal)
- What mcp-shield blocks vs what it doesn't
- Defense in depth recommendations

---

## Roadmap

- [x] Policy engine (allowlist + pattern scanning)
- [x] Audit logger (SQLite)
- [x] FastAPI REST surface
- [x] Docker sandbox backend (hardened)
- [x] Demo malicious MCP server
- [x] Risk scorer (LOW / MEDIUM / HIGH)
- [x] CLI (`mcpshield inspect`, `audit`, `stats`, `risk`)
- [x] Real-time dashboard
- [x] Firecracker microVM backend
- [x] PyPI package (`pip install mcpshield-runtime`)
- [x] Threat model documentation
- [ ] Prompt injection detection
- [ ] Per-tool argument schema validation
- [ ] Webhook alerts on BLOCK events

---

## License

MIT — see [LICENSE](LICENSE)

---

## Author

**Sri Sowmya Nemani** — Security researcher & engineer.
Bug bounty | MCP security | AI agent security

[GitHub](https://github.com/srisowmya2000) · [PyPI](https://pypi.org/project/mcpshield-runtime/)
