@mcp-guardian/server 0.3.0 → 0.4.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.
- package/README.md +265 -136
- package/dist/cli.js +30 -3
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/policy/policy-engine.d.ts +19 -0
- package/dist/policy/policy-engine.d.ts.map +1 -0
- package/dist/policy/policy-engine.js +87 -0
- package/dist/policy/policy-engine.js.map +1 -0
- package/dist/policy/policy-types.d.ts +42 -0
- package/dist/policy/policy-types.d.ts.map +1 -0
- package/dist/policy/policy-types.js +5 -0
- package/dist/policy/policy-types.js.map +1 -0
- package/dist/proxy/proxy-manager.d.ts +3 -1
- package/dist/proxy/proxy-manager.d.ts.map +1 -1
- package/dist/proxy/proxy-manager.js +5 -3
- package/dist/proxy/proxy-manager.js.map +1 -1
- package/dist/proxy/proxy-server.d.ts +10 -2
- package/dist/proxy/proxy-server.d.ts.map +1 -1
- package/dist/proxy/proxy-server.js +66 -3
- package/dist/proxy/proxy-server.js.map +1 -1
- package/dist/utils/structured-logger.d.ts +47 -0
- package/dist/utils/structured-logger.d.ts.map +1 -0
- package/dist/utils/structured-logger.js +48 -0
- package/dist/utils/structured-logger.js.map +1 -0
- package/package.json +13 -8
package/README.md
CHANGED
|
@@ -1,52 +1,78 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 🛡️ MCP Guardian
|
|
2
2
|
|
|
3
3
|
**Security, cost, and health audit for MCP infrastructure.**
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/@mcp-guardian/server)
|
|
7
6
|
[](https://www.typescriptlang.org/)
|
|
8
7
|
[](https://github.com/modelcontextprotocol/typescript-sdk)
|
|
9
8
|
[](LICENSE)
|
|
10
9
|
[](https://github.com/rudraneel93/mcp-guardian/actions/workflows/ci.yml)
|
|
11
10
|
|
|
11
|
+
MCP Guardian scans your [Model Context Protocol](https://modelcontextprotocol.io/) (MCP) servers for security vulnerabilities, tracks real token costs via a proxy interceptor, and monitors health metrics. It works as both an **MCP server** (so AI assistants like Cline/Claude can invoke its tools) and a **standalone CLI**.
|
|
12
|
+
|
|
12
13
|
---
|
|
13
14
|
|
|
14
15
|
## Table of Contents
|
|
15
16
|
|
|
17
|
+
- [Why MCP Guardian?](#why-mcp-guardian)
|
|
16
18
|
- [Features](#features)
|
|
17
19
|
- [Installation](#installation)
|
|
18
20
|
- [Quick Start](#quick-start)
|
|
19
21
|
- [Proxy Workflow (Real Cost Tracking)](#proxy-workflow-real-cost-tracking)
|
|
22
|
+
- [One-Off Scan](#one-off-scan)
|
|
20
23
|
- [CLI Reference](#cli-reference)
|
|
21
|
-
- [mcp-guardian proxy](#mcp-guardian-proxy)
|
|
22
|
-
- [mcp-guardian scan](#mcp-guardian-scan)
|
|
23
|
-
- [mcp-guardian audit](#mcp-guardian-audit)
|
|
24
|
-
- [mcp-guardian health](#mcp-guardian-health)
|
|
25
|
-
- [mcp-guardian report](#mcp-guardian-report)
|
|
26
|
-
- [MCP Server](#mcp-server-
|
|
24
|
+
- [`mcp-guardian proxy`](#mcp-guardian-proxy)
|
|
25
|
+
- [`mcp-guardian scan`](#mcp-guardian-scan)
|
|
26
|
+
- [`mcp-guardian audit`](#mcp-guardian-audit)
|
|
27
|
+
- [`mcp-guardian health`](#mcp-guardian-health)
|
|
28
|
+
- [`mcp-guardian report`](#mcp-guardian-report)
|
|
29
|
+
- [MCP Server (AI Assistant Integration)](#mcp-server-ai-assistant-integration)
|
|
30
|
+
- [Available Tools](#available-tools)
|
|
31
|
+
- [Available Resources & Prompts](#available-resources--prompts)
|
|
27
32
|
- [CI/CD Integration](#cicd-integration)
|
|
33
|
+
- [Docker](#docker)
|
|
28
34
|
- [Architecture](#architecture)
|
|
35
|
+
- [Data Flow (Proxy → DB → Audit)](#data-flow-proxy--db--audit)
|
|
29
36
|
- [Config Discovery](#config-discovery)
|
|
30
|
-
- [Security Scoring](#security-scoring-model)
|
|
37
|
+
- [Security Scoring Model](#security-scoring-model)
|
|
31
38
|
- [Pricing Models](#pricing-models)
|
|
32
39
|
- [Environment Variables](#environment-variables)
|
|
33
40
|
- [Development](#development)
|
|
41
|
+
- [FAQ](#faq)
|
|
34
42
|
- [Roadmap](#roadmap)
|
|
35
43
|
- [License](#license)
|
|
36
44
|
|
|
37
45
|
---
|
|
38
46
|
|
|
47
|
+
## Why MCP Guardian?
|
|
48
|
+
|
|
49
|
+
As MCP adoption grows, so does the attack surface. MCP servers run arbitrary commands, access filesystems, make network calls, and handle sensitive data — often with zero visibility into their security posture or operational cost.
|
|
50
|
+
|
|
51
|
+
MCP Guardian provides:
|
|
52
|
+
|
|
53
|
+
- **Security auditing** — CVE scanning (OSV.dev + NVD), hardcoded secret detection, typo-squatting detection, command injection detection, and TLS validation
|
|
54
|
+
- **Real cost tracking** — Proxy interceptor that captures actual `tools/call` traffic and counts tokens via `tiktoken` (o200k_base encoding) — no estimates, no mocks
|
|
55
|
+
- **Health monitoring** — Live JSON-RPC 2.0 handshake probes with latency, success rate, tool count, and context pressure analysis
|
|
56
|
+
- **Agent-native** — Runs as an MCP server so your AI assistant can self-audit its own infrastructure
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
39
60
|
## Features
|
|
40
61
|
|
|
41
62
|
### 🔒 Security Scan (`scan_security`)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
63
|
+
|
|
64
|
+
| Check | Description |
|
|
65
|
+
|---|---|
|
|
66
|
+
| **CVE Checking** | Queries [OSV.dev](https://osv.dev) (purl-based) and [NIST NVD](https://nvd.nist.gov) for known vulnerabilities. Rate-limited (5 req/min without API key, 20 req/min with key) |
|
|
67
|
+
| **Auth Probing** | Detects missing authentication via env vars (`API_KEY`, `AUTH_TOKEN`, etc.) and URL credentials |
|
|
68
|
+
| **Transport Security** | Flags unencrypted transports (HTTP, WS) and validates TLS certificates (expiry, issuer, validity) |
|
|
69
|
+
| **Typo-Squat Detection** | Levenshtein distance matching against 24 known official MCP packages |
|
|
70
|
+
| **Secret Scanning** | 6 regex patterns for hardcoded API keys, tokens, private keys, passwords, GitHub tokens, OpenAI keys |
|
|
71
|
+
| **Command Validation** | Flags dangerous patterns (path traversal, shell chaining, `rm -rf`, `curl`/`wget` in commands, and more) |
|
|
72
|
+
| **Scoring** | Weighted 0–100 security score with actionable recommendations |
|
|
73
|
+
|
|
74
|
+
### 💰 Cost Audit (`audit_costs`)
|
|
75
|
+
|
|
50
76
|
- **Proxy Interceptor** — `mcp-guardian proxy` sits between your AI client and MCP servers, capturing every `tools/call` request/response
|
|
51
77
|
- **Real Token Counting** — Uses `tiktoken` (o200k_base encoding) on actual JSON-RPC traffic — no hardcoded estimates
|
|
52
78
|
- **Multi-Model Pricing** — 97 models across 17 providers (OpenAI, Anthropic, Google, DeepSeek, xAI, Meta, Mistral, and more)
|
|
@@ -54,28 +80,41 @@ MCP Guardian scans your Model Context Protocol (MCP) servers for security vulner
|
|
|
54
80
|
- **Custom Pricing** — Override via `PRICING_OVERRIDES` env var: `{"my-model": {"input": 2.0, "output": 6.0}}`
|
|
55
81
|
|
|
56
82
|
### ❤️ Health Monitor (`check_health`)
|
|
83
|
+
|
|
57
84
|
- **Live Probes** — Full JSON-RPC 2.0 handshake (initialize → initialized → `tools/list`) with request/response correlation
|
|
58
85
|
- **SSE Probing** — Multi-path discovery (`/`, `/sse`, `/message`) with auth header injection and timeout handling
|
|
59
86
|
- **Latency Tracking** — End-to-end latency per server with historical success rates from SQLite
|
|
60
87
|
- **Overload Detection** — Warns when >15 tools exposed; context pressure estimation
|
|
61
88
|
|
|
62
89
|
### 📊 Full Report (`full_report`)
|
|
90
|
+
|
|
63
91
|
- **Three Output Formats** — Colored text, Markdown tables, structured JSON (with `resource` MIME type for agent consumption)
|
|
64
92
|
- **Overall Score** — Composite security + health score (0–100)
|
|
65
|
-
- **Database Storage** — All scans, costs, health checks, and proxy-captured call records persisted in SQLite
|
|
93
|
+
- **Database Storage** — All scans, costs, health checks, and proxy-captured call records persisted in SQLite (4 tables, batched writes)
|
|
66
94
|
|
|
67
95
|
### 🔧 Production Features
|
|
96
|
+
|
|
68
97
|
- **Dependency Injection** — IoC container (`src/container.ts`) for testability and runtime swaps
|
|
69
98
|
- **Rate Limiting** — Token-bucket rate limiter on OSV.dev and NVD API calls
|
|
70
99
|
- **Graceful Shutdown** — SIGINT/SIGTERM handlers flush DB and close connections
|
|
71
100
|
- **Batched DB Writes** — 1s debounced flush reduces I/O by 10x
|
|
72
101
|
- **Alert Thresholds** — 6 CLI flags with exit codes 1/2 for CI/CD integration
|
|
73
|
-
- **GitHub Actions CI** — Node 18/20/22 matrix,
|
|
102
|
+
- **GitHub Actions CI** — Node 18/20/22 matrix, 63 tests across 10 suites
|
|
74
103
|
|
|
75
104
|
---
|
|
76
105
|
|
|
77
106
|
## Installation
|
|
78
107
|
|
|
108
|
+
### From npm (recommended)
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
npm install -g @mcp-guardian/server
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
After global install, the `mcp-guardian` command is available in your PATH.
|
|
115
|
+
|
|
116
|
+
### From source
|
|
117
|
+
|
|
79
118
|
```bash
|
|
80
119
|
git clone https://github.com/rudraneel93/mcp-guardian.git
|
|
81
120
|
cd mcp-guardian
|
|
@@ -83,7 +122,7 @@ npm install
|
|
|
83
122
|
npm run build
|
|
84
123
|
```
|
|
85
124
|
|
|
86
|
-
**Requirements:** Node.js ≥18, npm ≥9
|
|
125
|
+
**Requirements:** Node.js ≥ 18, npm ≥ 9
|
|
87
126
|
|
|
88
127
|
---
|
|
89
128
|
|
|
@@ -108,6 +147,7 @@ mcp-guardian report --config ./cline_mcp_settings.json
|
|
|
108
147
|
```
|
|
109
148
|
|
|
110
149
|
**Example output (real data from proxy against 3 MCP servers):**
|
|
150
|
+
|
|
111
151
|
```
|
|
112
152
|
💰 Cost Audit
|
|
113
153
|
github: 194 tokens, $0.0018 (gpt-4o)
|
|
@@ -128,57 +168,22 @@ puppeteer - Score: D (10) — 3 CVEs (1 critical), needs auth
|
|
|
128
168
|
Overall Score: 60/100
|
|
129
169
|
```
|
|
130
170
|
|
|
131
|
-
> **Important:** The cost audit will show `$0.0000` until the proxy has been running and captured real `tools/call` traffic. This is not a bug — the `call_records` table starts empty.
|
|
132
|
-
|
|
133
|
-
---
|
|
134
|
-
|
|
135
|
-
## Live Pipeline Verification
|
|
171
|
+
> **Important:** The cost audit will show `$0.0000` until the proxy has been running and captured real `tools/call` traffic. This is not a bug — the `call_records` table starts empty.
|
|
136
172
|
|
|
137
|
-
|
|
173
|
+
### One-Off Scan
|
|
138
174
|
|
|
139
175
|
```bash
|
|
140
|
-
#
|
|
141
|
-
mcp-guardian
|
|
142
|
-
|
|
143
|
-
# Terminal 2: Run your AI workflows (or pipe test calls)
|
|
144
|
-
|
|
145
|
-
# Terminal 1: Ctrl+C when done, then:
|
|
146
|
-
mcp-guardian audit --config ./cline_mcp_settings.json
|
|
147
|
-
mcp-guardian report --config ./cline_mcp_settings.json
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
**Verified results** (proxy wrapping 3 real MCP servers — github, filesystem, puppeteer):
|
|
151
|
-
|
|
152
|
-
```
|
|
153
|
-
💰 Cost Audit (real data from live proxy run)
|
|
154
|
-
github: 194 tokens, $0.0018 (gpt-4o)
|
|
155
|
-
search_repositories: 66 tokens, 1 call, $0.0006
|
|
156
|
-
list_directory: 63 tokens, 1 call, $0.0006
|
|
157
|
-
read_file: 65 tokens, 1 call, $0.0006
|
|
158
|
-
|
|
159
|
-
filesystem: 245 tokens, $0.0026 (gpt-4o)
|
|
160
|
-
search_repositories: 81 tokens, 1 call, $0.0008
|
|
161
|
-
list_directory: 80 tokens, 1 call, $0.0009
|
|
162
|
-
read_file: 84 tokens, 1 call, $0.0009
|
|
163
|
-
|
|
164
|
-
puppeteer: 216 tokens, $0.0021 (gpt-4o)
|
|
165
|
-
search_repositories: 74 tokens, 1 call, $0.0007
|
|
166
|
-
list_directory: 70 tokens, 1 call, $0.0007
|
|
167
|
-
read_file: 72 tokens, 1 call, $0.0007
|
|
168
|
-
|
|
169
|
-
Total across 3 servers: 655 tokens, $0.0065
|
|
176
|
+
# Quick security scan on auto-discovered configs
|
|
177
|
+
mcp-guardian scan
|
|
170
178
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
filesystem: C (50) — 20 CVEs (1 high), needs auth
|
|
174
|
-
puppeteer: D (10) — 3 CVEs (1 critical), needs auth
|
|
179
|
+
# Scan with thresholds for CI
|
|
180
|
+
mcp-guardian scan --config ./cline_mcp_settings.json --fail-on-critical --fail-on-secrets --threshold-score 70
|
|
175
181
|
|
|
176
|
-
|
|
177
|
-
github
|
|
178
|
-
filesystem: 1253ms, 14 tools ✅ healthy
|
|
179
|
-
puppeteer: 1275ms, 7 tools ✅ healthy
|
|
182
|
+
# Check health
|
|
183
|
+
mcp-guardian health --server github-server --fail-on-overload --threshold-latency 2000
|
|
180
184
|
|
|
181
|
-
|
|
185
|
+
# Generate a Markdown report for documentation
|
|
186
|
+
mcp-guardian report --format markdown --output audit-report.md
|
|
182
187
|
```
|
|
183
188
|
|
|
184
189
|
---
|
|
@@ -187,21 +192,19 @@ Overall Score: 60/100
|
|
|
187
192
|
|
|
188
193
|
### `mcp-guardian proxy`
|
|
189
194
|
|
|
190
|
-
Start the MCP proxy interceptor to capture real token usage data.
|
|
195
|
+
Start the MCP proxy interceptor to capture real token usage data. The proxy spawns all stdio MCP servers from config, then bridges stdin/stdout.
|
|
191
196
|
|
|
192
197
|
```bash
|
|
193
198
|
mcp-guardian proxy --config ./cline_mcp_settings.json
|
|
194
199
|
```
|
|
195
200
|
|
|
196
|
-
The proxy spawns all stdio MCP servers from config, then bridges stdin/stdout. Pipe JSON-RPC messages through it, or configure your AI client to connect via the proxy's stdio transport.
|
|
197
|
-
|
|
198
201
|
| Option | Description |
|
|
199
|
-
|
|
202
|
+
|---|---|
|
|
200
203
|
| `-c, --config <path>` | Path to MCP config file |
|
|
201
204
|
|
|
202
205
|
### `mcp-guardian scan`
|
|
203
206
|
|
|
204
|
-
Run security scan on MCP servers.
|
|
207
|
+
Run security scan on MCP servers.
|
|
205
208
|
|
|
206
209
|
```bash
|
|
207
210
|
mcp-guardian scan
|
|
@@ -210,8 +213,8 @@ mcp-guardian scan --all --threshold-score 70
|
|
|
210
213
|
```
|
|
211
214
|
|
|
212
215
|
| Option | Description |
|
|
213
|
-
|
|
214
|
-
| `-c, --config <path>` | Path to MCP config file |
|
|
216
|
+
|---|---|
|
|
217
|
+
| `-c, --config <path>` | Path to an MCP config file |
|
|
215
218
|
| `-a, --all` | Aggregate all discoverable configs |
|
|
216
219
|
| `--threshold-score <n>` | Exit code 2 if any server score drops below `n` |
|
|
217
220
|
| `--fail-on-critical` | Exit code 1 if any critical CVE found |
|
|
@@ -228,8 +231,8 @@ mcp-guardian audit --threshold-cost 0.50
|
|
|
228
231
|
```
|
|
229
232
|
|
|
230
233
|
| Option | Description |
|
|
231
|
-
|
|
232
|
-
| `-c, --config <path>` | Path to MCP config file |
|
|
234
|
+
|---|---|
|
|
235
|
+
| `-c, --config <path>` | Path to an MCP config file |
|
|
233
236
|
| `-a, --all` | Aggregate all discoverable configs |
|
|
234
237
|
| `-s, --server <name>` | Filter to a specific server |
|
|
235
238
|
| `--threshold-cost <n>` | Exit code 2 if total cost exceeds `n` USD |
|
|
@@ -245,8 +248,8 @@ mcp-guardian health --threshold-latency 2000 --fail-on-overload
|
|
|
245
248
|
```
|
|
246
249
|
|
|
247
250
|
| Option | Description |
|
|
248
|
-
|
|
249
|
-
| `-c, --config <path>` | Path to MCP config file |
|
|
251
|
+
|---|---|
|
|
252
|
+
| `-c, --config <path>` | Path to an MCP config file |
|
|
250
253
|
| `-a, --all` | Aggregate all discoverable configs |
|
|
251
254
|
| `-s, --server <name>` | Filter to a specific server |
|
|
252
255
|
| `--threshold-latency <ms>` | Exit code 2 if any server exceeds latency threshold |
|
|
@@ -264,18 +267,32 @@ mcp-guardian report --all --threshold-score 60
|
|
|
264
267
|
```
|
|
265
268
|
|
|
266
269
|
| Option | Description |
|
|
267
|
-
|
|
268
|
-
| `-c, --config <path>` | Path to MCP config file |
|
|
270
|
+
|---|---|
|
|
271
|
+
| `-c, --config <path>` | Path to an MCP config file |
|
|
269
272
|
| `-a, --all` | Aggregate all discoverable configs |
|
|
270
|
-
| `-f, --format <fmt>` | Output format: `text
|
|
273
|
+
| `-f, --format <fmt>` | Output format: `text` (default), `markdown`, or `json` |
|
|
274
|
+
| `--output <path>` | Save report to a file instead of stdout |
|
|
271
275
|
| `--threshold-score <n>` | Exit code 2 if overall score drops below `n` |
|
|
272
276
|
|
|
273
277
|
---
|
|
274
278
|
|
|
275
|
-
## MCP Server (
|
|
279
|
+
## MCP Server (AI Assistant Integration)
|
|
276
280
|
|
|
277
281
|
Add to your `cline_mcp_settings.json` or `claude_desktop_config.json`:
|
|
278
282
|
|
|
283
|
+
```json
|
|
284
|
+
{
|
|
285
|
+
"mcpServers": {
|
|
286
|
+
"mcp-guardian": {
|
|
287
|
+
"command": "npx",
|
|
288
|
+
"args": ["-y", "@mcp-guardian/server"]
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Or with a local install:
|
|
295
|
+
|
|
279
296
|
```json
|
|
280
297
|
{
|
|
281
298
|
"mcpServers": {
|
|
@@ -287,30 +304,68 @@ Add to your `cline_mcp_settings.json` or `claude_desktop_config.json`:
|
|
|
287
304
|
}
|
|
288
305
|
```
|
|
289
306
|
|
|
290
|
-
|
|
307
|
+
### Available Tools
|
|
291
308
|
|
|
292
309
|
| Tool | Parameters | Description |
|
|
293
|
-
|
|
294
|
-
| `scan_security` | `configPath?` | Scan MCP configs for CVEs, auth gaps, typo-squatting,
|
|
310
|
+
|---|---|---|
|
|
311
|
+
| `scan_security` | `configPath?` | Scan MCP configs for CVEs, auth gaps, typo-squatting, hardcoded secrets, and dangerous commands |
|
|
295
312
|
| `audit_costs` | `serverName?` | Estimate token usage and costs per server with multi-model pricing |
|
|
296
313
|
| `check_health` | `serverName?` | Check latency, success rate, tool count, and context pressure |
|
|
297
|
-
| `full_report` | `configPath?`, `format?` (json\|markdown\|text) | Generate complete audit report |
|
|
314
|
+
| `full_report` | `configPath?`, `format?` (json\|markdown\|text) | Generate complete audit report in any format |
|
|
315
|
+
|
|
316
|
+
JSON format reports also include a structured `resource` content type (MIME: `application/json`) so AI assistants can consume reports programmatically.
|
|
317
|
+
|
|
318
|
+
### Available Resources & Prompts
|
|
298
319
|
|
|
299
|
-
|
|
320
|
+
- **Resource:** `mcp-guardian://latest-scan` — exposes the most recent security scan as structured JSON
|
|
321
|
+
- **Prompt:** `audit-config` — generates structured audit instructions for an MCP config path, which the assistant can use to guide its investigation
|
|
300
322
|
|
|
301
323
|
---
|
|
302
324
|
|
|
303
325
|
## CI/CD Integration
|
|
304
326
|
|
|
305
|
-
Run in
|
|
327
|
+
Run MCP Guardian in CI to catch issues before deployment:
|
|
306
328
|
|
|
307
329
|
```yaml
|
|
308
330
|
- name: MCP Guardian Security Scan
|
|
309
|
-
run: npx mcp-guardian scan --config ./cline_mcp_settings.json --fail-on-critical --fail-on-secrets
|
|
331
|
+
run: npx @mcp-guardian/server scan --config ./cline_mcp_settings.json --fail-on-critical --fail-on-secrets
|
|
310
332
|
env:
|
|
311
333
|
NVD_API_KEY: ${{ secrets.NVD_API_KEY }}
|
|
334
|
+
|
|
335
|
+
- name: MCP Guardian Cost Audit
|
|
336
|
+
run: npx @mcp-guardian/server audit --all --threshold-cost 0.50
|
|
337
|
+
|
|
338
|
+
- name: MCP Guardian Health Check
|
|
339
|
+
run: npx @mcp-guardian/server health --all --threshold-latency 3000 --fail-on-overload
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### Exit Codes
|
|
343
|
+
|
|
344
|
+
| Code | Meaning |
|
|
345
|
+
|---|---|
|
|
346
|
+
| 0 | All checks passed within thresholds |
|
|
347
|
+
| 1 | Critical security issue found (critical CVE, secret, overload) |
|
|
348
|
+
| 2 | Threshold exceeded (score, cost, or latency below/above limit) |
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
## Docker
|
|
353
|
+
|
|
354
|
+
A Docker image is available for running the proxy in containerized environments.
|
|
355
|
+
|
|
356
|
+
```bash
|
|
357
|
+
# Build
|
|
358
|
+
docker build -t mcp-guardian .
|
|
359
|
+
|
|
360
|
+
# Run proxy
|
|
361
|
+
docker run -i \
|
|
362
|
+
-v $(pwd)/cline_mcp_settings.json:/app/cline_mcp_settings.json \
|
|
363
|
+
-v mcp-guardian-db:/root/.mcp-guardian \
|
|
364
|
+
mcp-guardian --config /app/cline_mcp_settings.json
|
|
312
365
|
```
|
|
313
366
|
|
|
367
|
+
The `Dockerfile` uses `node:20-alpine` and runs `mcp-guardian proxy` as the default entrypoint.
|
|
368
|
+
|
|
314
369
|
---
|
|
315
370
|
|
|
316
371
|
## Architecture
|
|
@@ -319,9 +374,9 @@ Run in GitHub Actions to catch security issues before deployment:
|
|
|
319
374
|
mcp-guardian/
|
|
320
375
|
├── src/
|
|
321
376
|
│ ├── index.ts # MCP server entry (stdio transport)
|
|
322
|
-
│ ├── cli.ts # CLI wrapper (5 commands: scan, audit, health, report
|
|
323
|
-
│ ├── container.ts # Dependency injection container
|
|
324
|
-
│ ├── types.ts #
|
|
377
|
+
│ ├── cli.ts # CLI wrapper (5 commands: proxy, scan, audit, health, report)
|
|
378
|
+
│ ├── container.ts # Dependency injection container (IoC)
|
|
379
|
+
│ ├── types.ts # Shared TypeScript interfaces (8 types)
|
|
325
380
|
│ ├── config-parser.ts # Multi-format config parsing with multi-file aggregation
|
|
326
381
|
│ │
|
|
327
382
|
│ ├── proxy/ # MCP Proxy Interceptor (real cost engine)
|
|
@@ -334,18 +389,19 @@ mcp-guardian/
|
|
|
334
389
|
│ │ └── health-monitor.ts # Live JSON-RPC probing + DB integration
|
|
335
390
|
│ │
|
|
336
391
|
│ ├── scanners/ # Individual security checks
|
|
337
|
-
│ │ ├── cve-checker.ts # OSV.dev → NVD fallback chain
|
|
338
|
-
│ │ ├── auth-prober.ts # Auth/transport detection (env + URL)
|
|
392
|
+
│ │ ├── cve-checker.ts # OSV.dev → NVD fallback chain (rate-limited)
|
|
393
|
+
│ │ ├── auth-prober.ts # Auth/transport detection (env + URL patterns)
|
|
339
394
|
│ │ ├── typo-squat-detector.ts # Levenshtein distance (O(n) memory)
|
|
340
|
-
│ │
|
|
395
|
+
│ │ ├── secret-scanner.ts # 6 regex patterns for secrets
|
|
396
|
+
│ │ └── command-validator.ts # 10 suspicious pattern checks for command injection
|
|
341
397
|
│ │
|
|
342
398
|
│ ├── clients/ # External API clients
|
|
343
|
-
│ │ ├── osv-client.ts # api.osv.dev (purl-based, rate-limited)
|
|
344
|
-
│ │ ├── nvd-client.ts # NIST NVD (API key, rate-limited)
|
|
345
|
-
│ │ └── pricing-client.ts # 97 models, custom override support
|
|
399
|
+
│ │ ├── osv-client.ts # api.osv.dev (purl-based, token-bucket rate-limited)
|
|
400
|
+
│ │ ├── nvd-client.ts # NIST NVD (API key support, rate-limited)
|
|
401
|
+
│ │ └── pricing-client.ts # 97 models, 17 providers, custom override support
|
|
346
402
|
│ │
|
|
347
403
|
│ ├── database/
|
|
348
|
-
│ │ └── history-db.ts # SQLite via sql.js (4 tables, batched writes)
|
|
404
|
+
│ │ └── history-db.ts # SQLite via sql.js (4 tables, batched writes, 1s debounce)
|
|
349
405
|
│ │
|
|
350
406
|
│ ├── reporter/
|
|
351
407
|
│ │ └── report-generator.ts # Text, Markdown, JSON formatting
|
|
@@ -354,12 +410,26 @@ mcp-guardian/
|
|
|
354
410
|
│ ├── token-counter.ts # tiktoken (o200k_base) wrapper
|
|
355
411
|
│ ├── mcp-client.ts # Full JSON-RPC 2.0 state machine + SSE probing
|
|
356
412
|
│ ├── rate-limiter.ts # Token-bucket rate limiter
|
|
357
|
-
│ ├── tls-checker.ts # TLS certificate validation
|
|
413
|
+
│ ├── tls-checker.ts # TLS certificate validation (expiry, issuer, chain)
|
|
358
414
|
│ ├── scoring.ts # Shared scoring utility
|
|
359
|
-
│ └── logger.ts # Colored console logger
|
|
415
|
+
│ └── logger.ts # Colored console logger with log levels
|
|
416
|
+
│
|
|
417
|
+
tests/ # 63 tests across 10 suites (Vitest)
|
|
418
|
+
├── config-parser.test.ts
|
|
419
|
+
├── secret-scanner.test.ts
|
|
420
|
+
├── auth-prober.test.ts
|
|
421
|
+
├── typo-squat-detector.test.ts
|
|
422
|
+
├── scoring.test.ts
|
|
423
|
+
├── pricing-client.test.ts
|
|
424
|
+
├── services/
|
|
425
|
+
│ ├── cost-auditor.test.ts
|
|
426
|
+
│ └── security-scanner.test.ts
|
|
427
|
+
└── integration/
|
|
428
|
+
├── proxy-audit.test.ts
|
|
429
|
+
└── full-pipeline.test.ts
|
|
360
430
|
```
|
|
361
431
|
|
|
362
|
-
### Data Flow
|
|
432
|
+
### Data Flow (Proxy → DB → Audit)
|
|
363
433
|
|
|
364
434
|
```
|
|
365
435
|
AI Client (Cline/Claude)
|
|
@@ -370,10 +440,10 @@ AI Client (Cline/Claude)
|
|
|
370
440
|
│ MCP Proxy Server │ ← mcp-guardian proxy
|
|
371
441
|
│ (proxy-server.ts) │
|
|
372
442
|
└───────┬───────────┘
|
|
373
|
-
│ counts tokens (tiktoken)
|
|
443
|
+
│ counts tokens (tiktoken o200k_base)
|
|
374
444
|
▼
|
|
375
445
|
┌───────────────────┐
|
|
376
|
-
│ call_records table │ ← SQLite
|
|
446
|
+
│ call_records table │ ← SQLite (sql.js)
|
|
377
447
|
│ (history-db.ts) │
|
|
378
448
|
└───────┬───────────┘
|
|
379
449
|
│ async getCallRecordsForServer()
|
|
@@ -382,7 +452,7 @@ AI Client (Cline/Claude)
|
|
|
382
452
|
│ Cost Auditor │ ← mcp-guardian audit / report
|
|
383
453
|
│ (cost-auditor.ts) │
|
|
384
454
|
└───────────────────┘
|
|
385
|
-
│ per-tool breakdown + multi-model pricing
|
|
455
|
+
│ per-tool breakdown + multi-model pricing (97 models)
|
|
386
456
|
▼
|
|
387
457
|
Cost Report ($0.0023, gpt-4o)
|
|
388
458
|
```
|
|
@@ -394,17 +464,17 @@ AI Client (Cline/Claude)
|
|
|
394
464
|
MCP Guardian auto-discovers config files from these standard locations:
|
|
395
465
|
|
|
396
466
|
| Client | Config Path |
|
|
397
|
-
|
|
467
|
+
|---|---|
|
|
398
468
|
| **Cline (VS Code)** | `~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json` |
|
|
399
|
-
| **Cline (VS Code Insiders)** | `~/Library/Application Support/Code - Insiders/User/globalStorage
|
|
400
|
-
| **Cline (Linux)** | `~/.config/Code/User/globalStorage
|
|
401
|
-
| **Cline (Windows)** | `%APPDATA%/Code/User/globalStorage
|
|
469
|
+
| **Cline (VS Code Insiders)** | `~/Library/Application Support/Code - Insiders/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json` |
|
|
470
|
+
| **Cline (Linux)** | `~/.config/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json` |
|
|
471
|
+
| **Cline (Windows)** | `%APPDATA%/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json` |
|
|
402
472
|
| **Claude Desktop (macOS)** | `~/Library/Application Support/Claude/claude_desktop_config.json` |
|
|
403
473
|
| **Claude Desktop (Linux)** | `~/.config/Claude/claude_desktop_config.json` |
|
|
404
474
|
| **Cursor** | `~/.cursor/mcp.json` |
|
|
405
475
|
| **Windsurf** | `~/.codeium/windsurf/mcp_config.json` |
|
|
406
476
|
|
|
407
|
-
Use `--config` / `
|
|
477
|
+
Use `--config` / `-c` for a custom path, or `--all` / `-a` to aggregate all discoverable configs with deduplication (first file wins for duplicate server names).
|
|
408
478
|
|
|
409
479
|
---
|
|
410
480
|
|
|
@@ -413,7 +483,7 @@ Use `--config` / `configPath` for a custom path, or `--all` to aggregate all dis
|
|
|
413
483
|
Each server receives a score from 0–100 with these deductions:
|
|
414
484
|
|
|
415
485
|
| Finding | Deduction |
|
|
416
|
-
|
|
486
|
+
|---|---|
|
|
417
487
|
| Critical CVEs detected | −40 |
|
|
418
488
|
| High-severity CVEs | −20 |
|
|
419
489
|
| Medium-severity CVEs | −10 |
|
|
@@ -421,6 +491,8 @@ Each server receives a score from 0–100 with these deductions:
|
|
|
421
491
|
| Unencrypted transport | −10 |
|
|
422
492
|
| Typo-squat detected | −30 |
|
|
423
493
|
| Hardcoded secrets found | −15 |
|
|
494
|
+
| High-severity command warning | −25 |
|
|
495
|
+
| Medium-severity command warning | −10 |
|
|
424
496
|
|
|
425
497
|
**Letter grades:** A (80–100), B (60–79), C (40–59), D (0–39)
|
|
426
498
|
|
|
@@ -430,29 +502,30 @@ Each server receives a score from 0–100 with these deductions:
|
|
|
430
502
|
|
|
431
503
|
97 models across 17 providers. Cached rates per 1M tokens (as of mid-2025):
|
|
432
504
|
|
|
433
|
-
| Provider | Models | Example Rates |
|
|
434
|
-
|
|
435
|
-
| OpenAI (14) | gpt-4o, gpt-4.5-preview, o1, o3, o4-mini, gpt-3.5-turbo | $5/$15
|
|
436
|
-
| Anthropic (8) | claude-3-5-sonnet, claude-opus, claude-haiku | $3/$15
|
|
437
|
-
| Google (12) | gemini-2.5-pro, gemini-2.0-flash, gemma | $1.25/$10
|
|
438
|
-
| DeepSeek (4) | deepseek-chat, deepseek-reasoner, deepseek-v3 | $0.14/$0.28
|
|
439
|
-
| xAI/Grok (5) | grok-3, grok-3-mini | $3/$15
|
|
440
|
-
| Meta/Llama (8) | llama-4-maverick, llama-3.3-70b | $0.2/$0.6
|
|
441
|
-
| Mistral (9) | mistral-large, mixtral-8x22b, codestral | $2/$6
|
|
442
|
-
| + 10 more
|
|
505
|
+
| Provider | Models | Example Rates (input/output per 1M) |
|
|
506
|
+
|---|---|---|
|
|
507
|
+
| OpenAI (14) | gpt-4o, gpt-4.5-preview, o1, o3, o4-mini, gpt-3.5-turbo | $5/$15 |
|
|
508
|
+
| Anthropic (8) | claude-3-5-sonnet, claude-opus, claude-haiku | $3/$15 |
|
|
509
|
+
| Google (12) | gemini-2.5-pro, gemini-2.0-flash, gemma | $1.25/$10 |
|
|
510
|
+
| DeepSeek (4) | deepseek-chat, deepseek-reasoner, deepseek-v3 | $0.14/$0.28 |
|
|
511
|
+
| xAI/Grok (5) | grok-3, grok-3-mini | $3/$15 |
|
|
512
|
+
| Meta/Llama (8) | llama-4-maverick, llama-3.3-70b | $0.2/$0.6 |
|
|
513
|
+
| Mistral (9) | mistral-large, mixtral-8x22b, codestral | $2/$6 |
|
|
514
|
+
| + 10 more | Cohere, AI21, Reka, Amazon, Alibaba, Zhipu, 01.AI, Writer, Perplexity, HuggingFace | varies |
|
|
443
515
|
|
|
444
|
-
Unknown models receive a conservative default estimate of $10/$30 per million tokens. Override via `PRICING_OVERRIDES` env var.
|
|
516
|
+
Unknown models receive a conservative default estimate of $10/$30 per million tokens. Override any model via the `PRICING_OVERRIDES` env var.
|
|
445
517
|
|
|
446
518
|
---
|
|
447
519
|
|
|
448
520
|
## Environment Variables
|
|
449
521
|
|
|
450
|
-
| Variable | Purpose |
|
|
451
|
-
|
|
452
|
-
| `NVD_API_KEY` | NIST NVD API key for CVE lookups (20 req/min vs 5 without) |
|
|
453
|
-
| `MCP_GUARDIAN_DB_PATH` | Override SQLite database path
|
|
454
|
-
| `LOG_LEVEL` | Logging level: `DEBUG`, `INFO`, `WARN`, `ERROR`
|
|
455
|
-
| `PRICING_OVERRIDES` | Custom pricing JSON: `{"my-model": {"input": 2.0, "output": 6.0}}` |
|
|
522
|
+
| Variable | Purpose | Default |
|
|
523
|
+
|---|---|---|
|
|
524
|
+
| `NVD_API_KEY` | NIST NVD API key for CVE lookups (20 req/min vs 5 without) | (none) |
|
|
525
|
+
| `MCP_GUARDIAN_DB_PATH` | Override SQLite database path | `~/.mcp-guardian/history.db` |
|
|
526
|
+
| `LOG_LEVEL` | Logging level: `DEBUG`, `INFO`, `WARN`, `ERROR` | `INFO` |
|
|
527
|
+
| `PRICING_OVERRIDES` | Custom pricing JSON: `{"my-model": {"input": 2.0, "output": 6.0}}` | (none) |
|
|
528
|
+
| `OPENAI_API_KEY` | Optionally used by tiktoken for token counting | (none) |
|
|
456
529
|
|
|
457
530
|
---
|
|
458
531
|
|
|
@@ -465,16 +538,67 @@ cd mcp-guardian
|
|
|
465
538
|
npm install
|
|
466
539
|
|
|
467
540
|
# Development
|
|
468
|
-
npm run dev
|
|
469
|
-
npm run build
|
|
470
|
-
npm run lint
|
|
471
|
-
npm test
|
|
472
|
-
npm run test:watch
|
|
541
|
+
npm run dev # Watch mode with tsx
|
|
542
|
+
npm run build # Compile TypeScript
|
|
543
|
+
npm run lint # Type check (tsc --noEmit)
|
|
544
|
+
npm test # 63 tests across 10 suites (Vitest)
|
|
545
|
+
npm run test:watch # Watch mode
|
|
473
546
|
|
|
474
547
|
# Contributing
|
|
475
|
-
See CONTRIBUTING.md for guidelines on adding scanners, pricing models, and tests.
|
|
548
|
+
# See CONTRIBUTING.md for guidelines on adding scanners, pricing models, and tests.
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
---
|
|
552
|
+
|
|
553
|
+
## FAQ
|
|
554
|
+
|
|
555
|
+
### Why does `mcp-guardian audit` show $0.0000?
|
|
556
|
+
|
|
557
|
+
The cost audit reads real data from the proxy's database. You must run `mcp-guardian proxy` first to capture `tools/call` traffic, then run `audit`. Without proxy data, the `call_records` table is empty and the audit returns zero.
|
|
558
|
+
|
|
559
|
+
### Do I need an NVD API key?
|
|
560
|
+
|
|
561
|
+
No, but you'll be rate-limited to 5 requests per minute without one. Get a free key at [NIST NVD](https://nvd.nist.gov/developers/request-an-api-key) for 20 req/min.
|
|
562
|
+
|
|
563
|
+
### How do I run the proxy alongside my AI assistant?
|
|
564
|
+
|
|
565
|
+
Start `mcp-guardian proxy --config <path>` in one terminal, then run your AI assistant normally in another. The proxy sits between the assistant and MCP servers, transparently capturing all `tools/call` traffic.
|
|
566
|
+
|
|
567
|
+
### What does the proxy intercept?
|
|
568
|
+
|
|
569
|
+
The proxy only tracks `tools/call` JSON-RPC messages — it counts input tokens (the request) and output tokens (the response). It forwards all other messages without tracking.
|
|
570
|
+
|
|
571
|
+
### Can I use MCP Guardian with SSE/HTTP transports?
|
|
572
|
+
|
|
573
|
+
The security scan and health monitor support SSE/HTTP transports. The proxy currently supports **stdio** transports only (it spawns child processes). Cost auditing via proxy works only for stdio-based MCP servers.
|
|
574
|
+
|
|
575
|
+
### How do I override pricing for my custom model?
|
|
576
|
+
|
|
577
|
+
Set the `PRICING_OVERRIDES` environment variable with JSON:
|
|
578
|
+
|
|
579
|
+
```bash
|
|
580
|
+
export PRICING_OVERRIDES='{"my-custom-model": {"input": 2.0, "output": 6.0}}'
|
|
476
581
|
```
|
|
477
582
|
|
|
583
|
+
Rates are in USD per 1 million tokens.
|
|
584
|
+
|
|
585
|
+
### Where is the database stored?
|
|
586
|
+
|
|
587
|
+
By default, SQLite data is stored at `~/.mcp-guardian/history.db`. Override with the `MCP_GUARDIAN_DB_PATH` environment variable. The database has 4 tables: `security_scans`, `cost_records`, `health_checks`, and `call_records`.
|
|
588
|
+
|
|
589
|
+
### What's the difference between `--config` and `--all`?
|
|
590
|
+
|
|
591
|
+
- `--config <path>` loads a single config file
|
|
592
|
+
- `--all` auto-discovers and aggregates all config files from known locations (Cline, Claude Desktop, Cursor, Windsurf), deduplicating servers by name
|
|
593
|
+
|
|
594
|
+
### Can I run MCP Guardian in CI/CD?
|
|
595
|
+
|
|
596
|
+
Yes. Use the alert threshold flags (`--fail-on-critical`, `--fail-on-secrets`, `--threshold-score`, etc.) which return non-zero exit codes that CI systems understand. See the [CI/CD Integration](#cicd-integration) section for examples.
|
|
597
|
+
|
|
598
|
+
### How accurate is the token counting?
|
|
599
|
+
|
|
600
|
+
Token counting uses `tiktoken` with the `o200k_base` encoding (used by GPT-4o and many modern models). For non-OpenAI models, this provides a close approximation since most modern tokenizers are similar in granularity.
|
|
601
|
+
|
|
478
602
|
---
|
|
479
603
|
|
|
480
604
|
## Roadmap
|
|
@@ -492,9 +616,14 @@ See CONTRIBUTING.md for guidelines on adding scanners, pricing models, and tests
|
|
|
492
616
|
- [x] Dependency injection container (IoC pattern)
|
|
493
617
|
- [x] Token-bucket rate limiter (OSV + NVD)
|
|
494
618
|
- [x] TLS certificate validation
|
|
495
|
-
- [x]
|
|
619
|
+
- [x] Command injection validation (10 suspicious patterns)
|
|
620
|
+
- [x] 63 unit tests (10 test suites)
|
|
496
621
|
- [x] GitHub Actions CI (Node 18/20/22 matrix)
|
|
497
|
-
- [
|
|
622
|
+
- [x] Published to npm as [`@mcp-guardian/server`](https://www.npmjs.com/package/@mcp-guardian/server)
|
|
623
|
+
- [ ] Web dashboard for historical trends
|
|
624
|
+
- [ ] Slack/Discord alerting integration
|
|
625
|
+
- [ ] Custom CVE feed support
|
|
626
|
+
- [ ] Multi-user proxy mode
|
|
498
627
|
|
|
499
628
|
---
|
|
500
629
|
|
|
@@ -502,4 +631,4 @@ See CONTRIBUTING.md for guidelines on adding scanners, pricing models, and tests
|
|
|
502
631
|
|
|
503
632
|
MIT — see [LICENSE](LICENSE) for details.
|
|
504
633
|
|
|
505
|
-
**Built with TypeScript, @modelcontextprotocol/sdk, tiktoken, sql.js, and
|
|
634
|
+
**Built with TypeScript, @modelcontextprotocol/sdk, tiktoken, sql.js, commander, chalk, and zod.**
|