mcpshield-runtime 0.1.0__tar.gz

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.
@@ -0,0 +1,279 @@
1
+ Metadata-Version: 2.4
2
+ Name: mcpshield-runtime
3
+ Version: 0.1.0
4
+ Summary: Secure MCP runtime — policy enforcement, SSRF blocking, audit logging
5
+ Author: Sri Sowmya Nemani
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/srisowmya2000/mcp-shield
8
+ Project-URL: Repository, https://github.com/srisowmya2000/mcp-shield
9
+ Keywords: mcp,security,ssrf,llm,agent,policy,sandbox
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Topic :: Security
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Requires-Python: >=3.12
15
+ Description-Content-Type: text/markdown
16
+ Requires-Dist: fastapi>=0.115
17
+ Requires-Dist: uvicorn>=0.30
18
+ Requires-Dist: pydantic>=2.0
19
+ Requires-Dist: pydantic-settings>=2.0
20
+ Requires-Dist: typer>=0.12
21
+ Requires-Dist: mcp>=1.0
22
+ Requires-Dist: httpx>=0.27
23
+ Requires-Dist: pyyaml>=6.0
24
+ Requires-Dist: rich>=13.0
25
+
26
+ # mcp-shield 🛡️
27
+
28
+ > **The security runtime for MCP servers.**
29
+ > Every tool call inspected. Every attack blocked. Every decision logged.
30
+
31
+ ![Python](https://img.shields.io/badge/python-3.12-blue?style=flat-square)
32
+ ![License](https://img.shields.io/badge/license-MIT-green?style=flat-square)
33
+ ![Tests](https://img.shields.io/badge/tests-12%20passing-brightgreen?style=flat-square)
34
+ ![Status](https://img.shields.io/badge/status-active-success?style=flat-square)
35
+
36
+ ---
37
+
38
+ ## What is MCP?
39
+
40
+ **Model Context Protocol (MCP)** is an open standard that lets AI assistants (like Claude, Cursor, Copilot) connect to external tools and services — file systems, APIs, databases, browsers — through **MCP servers**.
41
+
42
+ Think of MCP servers as plugins that give AI agents real-world capabilities.
43
+
44
+ ---
45
+
46
+ ## The Problem
47
+
48
+ MCP servers run as **trusted processes** on your machine with access to:
49
+
50
+ | Access | Risk |
51
+ |---|---|
52
+ | 🗂️ Your filesystem | Read `/etc/passwd`, steal SSH keys |
53
+ | 🌐 Your network | SSRF to `169.254.169.254` (AWS metadata) |
54
+ | 🔑 Your environment variables | Steal API keys, tokens, secrets |
55
+ | ⚙️ Shell execution | Run arbitrary commands |
56
+
57
+ **A malicious or compromised MCP server can silently exfiltrate your secrets, pivot to internal infrastructure, or execute code — and you'd never know.**
58
+
59
+ This is not theoretical. A real SSRF vulnerability was found in an MCP OAuth HTTP transport implementation that allowed exactly this class of attack.
60
+
61
+ ---
62
+
63
+ ## How mcp-shield Fixes This
64
+
65
+ mcp-shield sits **between your AI agent and the MCP server** as a policy enforcement layer.
66
+ Before any tool executes, mcp-shield evaluates it. If it's not allowed — it's blocked.
67
+
68
+ ```
69
+ AI Agent
70
+
71
+
72
+ mcp-shield /inspect
73
+
74
+ ├── Tool allowlist check → "read_secrets" not allowed → 🚫 BLOCK
75
+ ├── Blocked pattern check → "ssrf_fetch" is dangerous → 🚫 BLOCK
76
+ ├── Argument scanning → "169.254.169.254" in args → 🚫 BLOCK
77
+
78
+ └── Passed all checks → ✅ ALLOW → MCP Server executes
79
+
80
+
81
+ Audit Log (SQLite)
82
+ ```
83
+
84
+ Every decision — ALLOW or BLOCK — is logged with a full audit trail.
85
+
86
+ ---
87
+
88
+ ## Live Demo
89
+
90
+ ```bash
91
+ # Start mcp-shield
92
+ uvicorn runtime.api.main:app --reload
93
+
94
+ # 🚫 Attempt secret theft → BLOCKED
95
+ curl -X POST http://localhost:8000/inspect \
96
+ -H "Content-Type: application/json" \
97
+ -d '{"server_name":"evil","policy":"default","tool_call":{"tool_name":"read_secrets","arguments":{}}}'
98
+
99
+ # → {"decision":"BLOCK","reason":"Tool 'read_secrets' is not in the allowed_tools list","blocked":true}
100
+
101
+ # 🚫 Attempt SSRF to AWS metadata endpoint → BLOCKED
102
+ curl -X POST http://localhost:8000/inspect \
103
+ -H "Content-Type: application/json" \
104
+ -d '{"server_name":"evil","policy":"default","tool_call":{"tool_name":"ssrf_fetch","arguments":{"url":"http://169.254.169.254/latest/meta-data/"}}}'
105
+
106
+ # → {"decision":"BLOCK","reason":"Argument contains blocked pattern: '169.254.169.254'","blocked":true}
107
+
108
+ # ✅ Safe tool → ALLOWED
109
+ curl -X POST http://localhost:8000/inspect \
110
+ -H "Content-Type: application/json" \
111
+ -d '{"server_name":"safe","policy":"default","tool_call":{"tool_name":"safe_tool","arguments":{"name":"Sri"}}}'
112
+
113
+ # → {"decision":"ALLOW","reason":"Passed all policy checks","blocked":false}
114
+ ```
115
+
116
+ ---
117
+
118
+ ## Key Features
119
+
120
+ | Feature | Description |
121
+ |---|---|
122
+ | 🔒 **Policy Engine** | YAML-based allowlists + blocked patterns, per-server policies |
123
+ | 🔍 **Argument Scanning** | Recursively scans nested args for SSRF, path traversal, dangerous patterns |
124
+ | 📋 **Audit Logger** | Every decision logged to SQLite with timestamp, server, tool, reason |
125
+ | 🐳 **Docker Sandbox** | Hardened containers: `--cap-drop=ALL`, `--network=none`, `--read-only` |
126
+ | 📊 **Risk Scorer** | Scores MCP servers LOW / MEDIUM / HIGH based on tool capabilities |
127
+ | 🖥️ **Live Dashboard** | Real-time web UI showing live block/allow feed at `/dashboard` |
128
+ | ⚡ **CLI** | `mcpshield inspect`, `mcpshield audit`, `mcpshield stats`, `mcpshield risk` |
129
+
130
+ ---
131
+
132
+ ## Policies
133
+
134
+ Policies are simple YAML files. Drop one in `policies/` and reference it by name.
135
+
136
+ ```yaml
137
+ # policies/default.yaml
138
+ allowed_tools:
139
+ - safe_tool
140
+ - list_files
141
+ - get_time
142
+
143
+ block_network: true
144
+ block_env_access: true
145
+
146
+ blocked_arg_patterns:
147
+ - "169.254.169.254" # AWS metadata SSRF
148
+ - "169.254.170.2" # ECS metadata SSRF
149
+ - "localhost"
150
+ - "127.0.0.1"
151
+ - "/etc/passwd"
152
+ - "/etc/shadow"
153
+ - "file://"
154
+ - "gopher://"
155
+
156
+ max_memory_mb: 256
157
+ execution_timeout_seconds: 30
158
+ ```
159
+
160
+ Switch policy per server:
161
+ ```bash
162
+ POST /inspect → { "policy": "strict", ... }
163
+ ```
164
+
165
+ ---
166
+
167
+ ## Architecture
168
+
169
+ ```
170
+ mcp-shield/
171
+ ├── runtime/
172
+ │ ├── api/
173
+ │ │ └── main.py # FastAPI — /inspect /audit /sandbox /dashboard
174
+ │ ├── policy_engine.py # YAML policy loader + evaluator
175
+ │ ├── audit_logger.py # SQLite decision log
176
+ │ ├── risk_scorer.py # LOW/MEDIUM/HIGH risk scoring
177
+ │ ├── cli.py # Typer CLI — inspect/audit/stats/risk
178
+ │ ├── models.py # Pydantic schemas
179
+ │ └── sandbox/
180
+ │ ├── base.py # Abstract backend interface
181
+ │ └── docker_backend.py # Hardened Docker sandbox
182
+ ├── policies/
183
+ │ ├── default.yaml # Standard policy
184
+ │ └── strict.yaml # Zero-trust policy
185
+ ├── examples/
186
+ │ ├── malicious_mcp_server/ # Demo attacker (SSRF + secret theft + exec)
187
+ │ └── safe_mcp_server/ # Demo benign server
188
+ └── tests/ # 12 tests — all passing
189
+ ```
190
+
191
+ ---
192
+
193
+ ## Quickstart
194
+
195
+ ```bash
196
+ # 1. Clone
197
+ git clone https://github.com/srisowmya2000/mcp-shield
198
+ cd mcp-shield
199
+
200
+ # 2. Install
201
+ python3 -m venv .venv && source .venv/bin/activate
202
+ pip install fastapi uvicorn pydantic pydantic-settings mcp httpx pyyaml
203
+
204
+ # 3. Start
205
+ uvicorn runtime.api.main:app --reload
206
+
207
+ # 4. Open
208
+ # API docs → http://localhost:8000/docs
209
+ # Dashboard → http://localhost:8000/dashboard
210
+ ```
211
+
212
+ ---
213
+
214
+ ## CLI
215
+
216
+ ```bash
217
+ # Inspect a tool call
218
+ python3 -m runtime.cli inspect read_secrets
219
+ # → 🚫 BLOCKED — Tool 'read_secrets' is not in the allowed_tools list
220
+
221
+ # Score a server's risk
222
+ python3 -m runtime.cli risk "read_secrets,ssrf_fetch,safe_tool"
223
+ # → 🔴 HIGH RISK (score: 80)
224
+
225
+ # View audit log
226
+ python3 -m runtime.cli audit
227
+
228
+ # View stats
229
+ python3 -m runtime.cli stats
230
+ # → Total: 6 | Allowed: 2 | Blocked: 4 (67% block rate)
231
+ ```
232
+
233
+ ---
234
+
235
+ ## API Reference
236
+
237
+ | Endpoint | Method | Description |
238
+ |---|---|---|
239
+ | `/health` | GET | Service health check |
240
+ | `/inspect` | POST | Evaluate tool call → ALLOW / BLOCK |
241
+ | `/audit` | GET | Recent audit log entries |
242
+ | `/audit/stats` | GET | Total / allowed / blocked counts |
243
+ | `/risk/score` | POST | Score server risk by tool list |
244
+ | `/sandbox/launch` | POST | Launch MCP server in hardened Docker |
245
+ | `/sandbox/stop/{name}` | POST | Stop a running sandbox |
246
+ | `/sandbox/list` | GET | List running sandboxes |
247
+ | `/dashboard` | GET | Live real-time dashboard |
248
+
249
+ ---
250
+
251
+ ## Tests
252
+
253
+ ```bash
254
+ pip install pytest
255
+ pytest tests/ -v
256
+ # 12 passed in 0.11s
257
+ ```
258
+
259
+ Covers: tool allowlist blocking, SSRF argument detection, nested arg scanning, strict policy, edge cases.
260
+
261
+ ---
262
+
263
+ ## Roadmap
264
+
265
+ - [x] Policy engine (allowlist + pattern scanning)
266
+ - [x] Audit logger (SQLite)
267
+ - [x] FastAPI REST surface
268
+ - [x] Docker sandbox backend (hardened)
269
+ - [x] Demo malicious MCP server
270
+ - [x] Risk scorer (LOW / MEDIUM / HIGH)
271
+ - [x] CLI (`mcpshield inspect`, `audit`, `stats`, `risk`)
272
+ - [x] Real-time dashboard
273
+ - [ ] Firecracker microVM backend
274
+ - [ ] PyPI package (`pip install mcp-shield`)
275
+ - [ ] `threat-model.md`
276
+
277
+ ---
278
+
279
+
@@ -0,0 +1,254 @@
1
+ # mcp-shield 🛡️
2
+
3
+ > **The security runtime for MCP servers.**
4
+ > Every tool call inspected. Every attack blocked. Every decision logged.
5
+
6
+ ![Python](https://img.shields.io/badge/python-3.12-blue?style=flat-square)
7
+ ![License](https://img.shields.io/badge/license-MIT-green?style=flat-square)
8
+ ![Tests](https://img.shields.io/badge/tests-12%20passing-brightgreen?style=flat-square)
9
+ ![Status](https://img.shields.io/badge/status-active-success?style=flat-square)
10
+
11
+ ---
12
+
13
+ ## What is MCP?
14
+
15
+ **Model Context Protocol (MCP)** is an open standard that lets AI assistants (like Claude, Cursor, Copilot) connect to external tools and services — file systems, APIs, databases, browsers — through **MCP servers**.
16
+
17
+ Think of MCP servers as plugins that give AI agents real-world capabilities.
18
+
19
+ ---
20
+
21
+ ## The Problem
22
+
23
+ MCP servers run as **trusted processes** on your machine with access to:
24
+
25
+ | Access | Risk |
26
+ |---|---|
27
+ | 🗂️ Your filesystem | Read `/etc/passwd`, steal SSH keys |
28
+ | 🌐 Your network | SSRF to `169.254.169.254` (AWS metadata) |
29
+ | 🔑 Your environment variables | Steal API keys, tokens, secrets |
30
+ | ⚙️ Shell execution | Run arbitrary commands |
31
+
32
+ **A malicious or compromised MCP server can silently exfiltrate your secrets, pivot to internal infrastructure, or execute code — and you'd never know.**
33
+
34
+ This is not theoretical. A real SSRF vulnerability was found in an MCP OAuth HTTP transport implementation that allowed exactly this class of attack.
35
+
36
+ ---
37
+
38
+ ## How mcp-shield Fixes This
39
+
40
+ mcp-shield sits **between your AI agent and the MCP server** as a policy enforcement layer.
41
+ Before any tool executes, mcp-shield evaluates it. If it's not allowed — it's blocked.
42
+
43
+ ```
44
+ AI Agent
45
+
46
+
47
+ mcp-shield /inspect
48
+
49
+ ├── Tool allowlist check → "read_secrets" not allowed → 🚫 BLOCK
50
+ ├── Blocked pattern check → "ssrf_fetch" is dangerous → 🚫 BLOCK
51
+ ├── Argument scanning → "169.254.169.254" in args → 🚫 BLOCK
52
+
53
+ └── Passed all checks → ✅ ALLOW → MCP Server executes
54
+
55
+
56
+ Audit Log (SQLite)
57
+ ```
58
+
59
+ Every decision — ALLOW or BLOCK — is logged with a full audit trail.
60
+
61
+ ---
62
+
63
+ ## Live Demo
64
+
65
+ ```bash
66
+ # Start mcp-shield
67
+ uvicorn runtime.api.main:app --reload
68
+
69
+ # 🚫 Attempt secret theft → BLOCKED
70
+ curl -X POST http://localhost:8000/inspect \
71
+ -H "Content-Type: application/json" \
72
+ -d '{"server_name":"evil","policy":"default","tool_call":{"tool_name":"read_secrets","arguments":{}}}'
73
+
74
+ # → {"decision":"BLOCK","reason":"Tool 'read_secrets' is not in the allowed_tools list","blocked":true}
75
+
76
+ # 🚫 Attempt SSRF to AWS metadata endpoint → BLOCKED
77
+ curl -X POST http://localhost:8000/inspect \
78
+ -H "Content-Type: application/json" \
79
+ -d '{"server_name":"evil","policy":"default","tool_call":{"tool_name":"ssrf_fetch","arguments":{"url":"http://169.254.169.254/latest/meta-data/"}}}'
80
+
81
+ # → {"decision":"BLOCK","reason":"Argument contains blocked pattern: '169.254.169.254'","blocked":true}
82
+
83
+ # ✅ Safe tool → ALLOWED
84
+ curl -X POST http://localhost:8000/inspect \
85
+ -H "Content-Type: application/json" \
86
+ -d '{"server_name":"safe","policy":"default","tool_call":{"tool_name":"safe_tool","arguments":{"name":"Sri"}}}'
87
+
88
+ # → {"decision":"ALLOW","reason":"Passed all policy checks","blocked":false}
89
+ ```
90
+
91
+ ---
92
+
93
+ ## Key Features
94
+
95
+ | Feature | Description |
96
+ |---|---|
97
+ | 🔒 **Policy Engine** | YAML-based allowlists + blocked patterns, per-server policies |
98
+ | 🔍 **Argument Scanning** | Recursively scans nested args for SSRF, path traversal, dangerous patterns |
99
+ | 📋 **Audit Logger** | Every decision logged to SQLite with timestamp, server, tool, reason |
100
+ | 🐳 **Docker Sandbox** | Hardened containers: `--cap-drop=ALL`, `--network=none`, `--read-only` |
101
+ | 📊 **Risk Scorer** | Scores MCP servers LOW / MEDIUM / HIGH based on tool capabilities |
102
+ | 🖥️ **Live Dashboard** | Real-time web UI showing live block/allow feed at `/dashboard` |
103
+ | ⚡ **CLI** | `mcpshield inspect`, `mcpshield audit`, `mcpshield stats`, `mcpshield risk` |
104
+
105
+ ---
106
+
107
+ ## Policies
108
+
109
+ Policies are simple YAML files. Drop one in `policies/` and reference it by name.
110
+
111
+ ```yaml
112
+ # policies/default.yaml
113
+ allowed_tools:
114
+ - safe_tool
115
+ - list_files
116
+ - get_time
117
+
118
+ block_network: true
119
+ block_env_access: true
120
+
121
+ blocked_arg_patterns:
122
+ - "169.254.169.254" # AWS metadata SSRF
123
+ - "169.254.170.2" # ECS metadata SSRF
124
+ - "localhost"
125
+ - "127.0.0.1"
126
+ - "/etc/passwd"
127
+ - "/etc/shadow"
128
+ - "file://"
129
+ - "gopher://"
130
+
131
+ max_memory_mb: 256
132
+ execution_timeout_seconds: 30
133
+ ```
134
+
135
+ Switch policy per server:
136
+ ```bash
137
+ POST /inspect → { "policy": "strict", ... }
138
+ ```
139
+
140
+ ---
141
+
142
+ ## Architecture
143
+
144
+ ```
145
+ mcp-shield/
146
+ ├── runtime/
147
+ │ ├── api/
148
+ │ │ └── main.py # FastAPI — /inspect /audit /sandbox /dashboard
149
+ │ ├── policy_engine.py # YAML policy loader + evaluator
150
+ │ ├── audit_logger.py # SQLite decision log
151
+ │ ├── risk_scorer.py # LOW/MEDIUM/HIGH risk scoring
152
+ │ ├── cli.py # Typer CLI — inspect/audit/stats/risk
153
+ │ ├── models.py # Pydantic schemas
154
+ │ └── sandbox/
155
+ │ ├── base.py # Abstract backend interface
156
+ │ └── docker_backend.py # Hardened Docker sandbox
157
+ ├── policies/
158
+ │ ├── default.yaml # Standard policy
159
+ │ └── strict.yaml # Zero-trust policy
160
+ ├── examples/
161
+ │ ├── malicious_mcp_server/ # Demo attacker (SSRF + secret theft + exec)
162
+ │ └── safe_mcp_server/ # Demo benign server
163
+ └── tests/ # 12 tests — all passing
164
+ ```
165
+
166
+ ---
167
+
168
+ ## Quickstart
169
+
170
+ ```bash
171
+ # 1. Clone
172
+ git clone https://github.com/srisowmya2000/mcp-shield
173
+ cd mcp-shield
174
+
175
+ # 2. Install
176
+ python3 -m venv .venv && source .venv/bin/activate
177
+ pip install fastapi uvicorn pydantic pydantic-settings mcp httpx pyyaml
178
+
179
+ # 3. Start
180
+ uvicorn runtime.api.main:app --reload
181
+
182
+ # 4. Open
183
+ # API docs → http://localhost:8000/docs
184
+ # Dashboard → http://localhost:8000/dashboard
185
+ ```
186
+
187
+ ---
188
+
189
+ ## CLI
190
+
191
+ ```bash
192
+ # Inspect a tool call
193
+ python3 -m runtime.cli inspect read_secrets
194
+ # → 🚫 BLOCKED — Tool 'read_secrets' is not in the allowed_tools list
195
+
196
+ # Score a server's risk
197
+ python3 -m runtime.cli risk "read_secrets,ssrf_fetch,safe_tool"
198
+ # → 🔴 HIGH RISK (score: 80)
199
+
200
+ # View audit log
201
+ python3 -m runtime.cli audit
202
+
203
+ # View stats
204
+ python3 -m runtime.cli stats
205
+ # → Total: 6 | Allowed: 2 | Blocked: 4 (67% block rate)
206
+ ```
207
+
208
+ ---
209
+
210
+ ## API Reference
211
+
212
+ | Endpoint | Method | Description |
213
+ |---|---|---|
214
+ | `/health` | GET | Service health check |
215
+ | `/inspect` | POST | Evaluate tool call → ALLOW / BLOCK |
216
+ | `/audit` | GET | Recent audit log entries |
217
+ | `/audit/stats` | GET | Total / allowed / blocked counts |
218
+ | `/risk/score` | POST | Score server risk by tool list |
219
+ | `/sandbox/launch` | POST | Launch MCP server in hardened Docker |
220
+ | `/sandbox/stop/{name}` | POST | Stop a running sandbox |
221
+ | `/sandbox/list` | GET | List running sandboxes |
222
+ | `/dashboard` | GET | Live real-time dashboard |
223
+
224
+ ---
225
+
226
+ ## Tests
227
+
228
+ ```bash
229
+ pip install pytest
230
+ pytest tests/ -v
231
+ # 12 passed in 0.11s
232
+ ```
233
+
234
+ Covers: tool allowlist blocking, SSRF argument detection, nested arg scanning, strict policy, edge cases.
235
+
236
+ ---
237
+
238
+ ## Roadmap
239
+
240
+ - [x] Policy engine (allowlist + pattern scanning)
241
+ - [x] Audit logger (SQLite)
242
+ - [x] FastAPI REST surface
243
+ - [x] Docker sandbox backend (hardened)
244
+ - [x] Demo malicious MCP server
245
+ - [x] Risk scorer (LOW / MEDIUM / HIGH)
246
+ - [x] CLI (`mcpshield inspect`, `audit`, `stats`, `risk`)
247
+ - [x] Real-time dashboard
248
+ - [ ] Firecracker microVM backend
249
+ - [ ] PyPI package (`pip install mcp-shield`)
250
+ - [ ] `threat-model.md`
251
+
252
+ ---
253
+
254
+