@mcp-guardian/server 0.3.0 → 0.5.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 +362 -136
- package/dist/auth/auth-types.d.ts +40 -0
- package/dist/auth/auth-types.d.ts.map +1 -0
- package/dist/auth/auth-types.js +5 -0
- package/dist/auth/auth-types.js.map +1 -0
- package/dist/auth/dashboard-auth.d.ts +97 -0
- package/dist/auth/dashboard-auth.d.ts.map +1 -0
- package/dist/auth/dashboard-auth.js +319 -0
- package/dist/auth/dashboard-auth.js.map +1 -0
- package/dist/auth/dpop.d.ts +38 -0
- package/dist/auth/dpop.d.ts.map +1 -0
- package/dist/auth/dpop.js +72 -0
- package/dist/auth/dpop.js.map +1 -0
- package/dist/auth/oauth.d.ts +25 -0
- package/dist/auth/oauth.d.ts.map +1 -0
- package/dist/auth/oauth.js +96 -0
- package/dist/auth/oauth.js.map +1 -0
- package/dist/auth/redis-session-cache.d.ts +21 -0
- package/dist/auth/redis-session-cache.d.ts.map +1 -0
- package/dist/auth/redis-session-cache.js +74 -0
- package/dist/auth/redis-session-cache.js.map +1 -0
- package/dist/auth/session-cache.d.ts +47 -0
- package/dist/auth/session-cache.d.ts.map +1 -0
- package/dist/auth/session-cache.js +91 -0
- package/dist/auth/session-cache.js.map +1 -0
- package/dist/cli.js +48 -3
- package/dist/cli.js.map +1 -1
- package/dist/database/database-interface.d.ts +17 -0
- package/dist/database/database-interface.d.ts.map +1 -0
- package/dist/database/database-interface.js +2 -0
- package/dist/database/database-interface.js.map +1 -0
- package/dist/database/postgres-db.d.ts +18 -0
- package/dist/database/postgres-db.d.ts.map +1 -0
- package/dist/database/postgres-db.js +118 -0
- package/dist/database/postgres-db.js.map +1 -0
- 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/policy/policy-watcher.d.ts +24 -0
- package/dist/policy/policy-watcher.d.ts.map +1 -0
- package/dist/policy/policy-watcher.js +68 -0
- package/dist/policy/policy-watcher.js.map +1 -0
- package/dist/policy/shell-tokenizer.d.ts +92 -0
- package/dist/policy/shell-tokenizer.d.ts.map +1 -0
- package/dist/policy/shell-tokenizer.js +300 -0
- package/dist/policy/shell-tokenizer.js.map +1 -0
- package/dist/proxy/http-proxy-server.d.ts +26 -0
- package/dist/proxy/http-proxy-server.d.ts.map +1 -0
- package/dist/proxy/http-proxy-server.js +172 -0
- package/dist/proxy/http-proxy-server.js.map +1 -0
- package/dist/proxy/proxy-manager.d.ts +5 -1
- package/dist/proxy/proxy-manager.d.ts.map +1 -1
- package/dist/proxy/proxy-manager.js +12 -3
- package/dist/proxy/proxy-manager.js.map +1 -1
- package/dist/proxy/proxy-server.d.ts +20 -5
- package/dist/proxy/proxy-server.d.ts.map +1 -1
- package/dist/proxy/proxy-server.js +126 -9
- package/dist/proxy/proxy-server.js.map +1 -1
- package/dist/utils/circuit-breaker.d.ts +29 -0
- package/dist/utils/circuit-breaker.d.ts.map +1 -0
- package/dist/utils/circuit-breaker.js +81 -0
- package/dist/utils/circuit-breaker.js.map +1 -0
- package/dist/utils/dashboard-server.d.ts +19 -0
- package/dist/utils/dashboard-server.d.ts.map +1 -0
- package/dist/utils/dashboard-server.js +258 -0
- package/dist/utils/dashboard-server.js.map +1 -0
- package/dist/utils/metrics.d.ts +17 -0
- package/dist/utils/metrics.d.ts.map +1 -0
- package/dist/utils/metrics.js +79 -0
- package/dist/utils/metrics.js.map +1 -0
- package/dist/utils/mtls-config.d.ts +27 -0
- package/dist/utils/mtls-config.d.ts.map +1 -0
- package/dist/utils/mtls-config.js +82 -0
- package/dist/utils/mtls-config.js.map +1 -0
- package/dist/utils/payload-normalizer.d.ts +62 -0
- package/dist/utils/payload-normalizer.d.ts.map +1 -0
- package/dist/utils/payload-normalizer.js +240 -0
- package/dist/utils/payload-normalizer.js.map +1 -0
- package/dist/utils/policy-auditor.d.ts +24 -0
- package/dist/utils/policy-auditor.d.ts.map +1 -0
- package/dist/utils/policy-auditor.js +58 -0
- package/dist/utils/policy-auditor.js.map +1 -0
- package/dist/utils/redis-rate-limiter.d.ts +22 -0
- package/dist/utils/redis-rate-limiter.d.ts.map +1 -0
- package/dist/utils/redis-rate-limiter.js +61 -0
- package/dist/utils/redis-rate-limiter.js.map +1 -0
- 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/dist/utils/tracing.d.ts +7 -0
- package/dist/utils/tracing.d.ts.map +1 -0
- package/dist/utils/tracing.js +34 -0
- package/dist/utils/tracing.js.map +1 -0
- package/package.json +14 -8
package/README.md
CHANGED
|
@@ -1,52 +1,84 @@
|
|
|
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
|
-
- [
|
|
23
|
-
- [mcp-guardian
|
|
24
|
-
- [mcp-guardian
|
|
25
|
-
- [mcp-guardian
|
|
26
|
-
- [
|
|
24
|
+
- [`mcp-guardian proxy`](#mcp-guardian-proxy)
|
|
25
|
+
- [Policy Engine (v0.4+)](#policy-engine-v04)
|
|
26
|
+
- [`mcp-guardian scan`](#mcp-guardian-scan)
|
|
27
|
+
- [`mcp-guardian audit`](#mcp-guardian-audit)
|
|
28
|
+
- [`mcp-guardian health`](#mcp-guardian-health)
|
|
29
|
+
- [`mcp-guardian report`](#mcp-guardian-report)
|
|
30
|
+
- [MCP Server (AI Assistant Integration)](#mcp-server-ai-assistant-integration)
|
|
31
|
+
- [Available Tools](#available-tools)
|
|
32
|
+
- [Available Resources & Prompts](#available-resources--prompts)
|
|
27
33
|
- [CI/CD Integration](#cicd-integration)
|
|
34
|
+
- [Production Deployment (K8s + Helm)](#production-deployment-k8s--helm)
|
|
35
|
+
- [Docker](#docker)
|
|
28
36
|
- [Architecture](#architecture)
|
|
37
|
+
- [Data Flow (Proxy → DB → Audit)](#data-flow-proxy--db--audit)
|
|
29
38
|
- [Config Discovery](#config-discovery)
|
|
30
|
-
- [Security Scoring](#security-scoring-model)
|
|
39
|
+
- [Security Scoring Model](#security-scoring-model)
|
|
31
40
|
- [Pricing Models](#pricing-models)
|
|
32
41
|
- [Environment Variables](#environment-variables)
|
|
33
42
|
- [Development](#development)
|
|
43
|
+
- [SECURITY.md](#securitymd)
|
|
44
|
+
- [FAQ](#faq)
|
|
34
45
|
- [Roadmap](#roadmap)
|
|
35
46
|
- [License](#license)
|
|
36
47
|
|
|
37
48
|
---
|
|
38
49
|
|
|
50
|
+
## Why MCP Guardian?
|
|
51
|
+
|
|
52
|
+
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.
|
|
53
|
+
|
|
54
|
+
MCP Guardian provides:
|
|
55
|
+
|
|
56
|
+
- **Active policy enforcement (v0.4+)** — YAML-configurable policy engine that blocks, flags, or passes every `tools/call` in real time based on tool allowlists/denylists, regex patterns, rate limits, and token budgets
|
|
57
|
+
- **Security auditing** — CVE scanning (OSV.dev + NVD), hardcoded secret detection, typo-squatting detection, command injection detection, and TLS validation
|
|
58
|
+
- **Real cost tracking** — Proxy interceptor that captures actual `tools/call` traffic and counts tokens via `tiktoken` (o200k_base encoding) — no estimates, no mocks
|
|
59
|
+
- **Health monitoring** — Live JSON-RPC 2.0 handshake probes with latency, success rate, tool count, and context pressure analysis
|
|
60
|
+
- **Agent-native** — Runs as an MCP server so your AI assistant can self-audit its own infrastructure
|
|
61
|
+
- **Enterprise SIEM logging (v0.4+)** — Structured JSON logs via pino with request-ID tracing, policy decision audit trails, and block events at WARN level
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
39
65
|
## Features
|
|
40
66
|
|
|
41
67
|
### 🔒 Security Scan (`scan_security`)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
68
|
+
|
|
69
|
+
| Check | Description |
|
|
70
|
+
|---|---|
|
|
71
|
+
| **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) |
|
|
72
|
+
| **Auth Probing** | Detects missing authentication via env vars (`API_KEY`, `AUTH_TOKEN`, etc.) and URL credentials |
|
|
73
|
+
| **Transport Security** | Flags unencrypted transports (HTTP, WS) and validates TLS certificates (expiry, issuer, validity) |
|
|
74
|
+
| **Typo-Squat Detection** | Levenshtein distance matching against 24 known official MCP packages |
|
|
75
|
+
| **Secret Scanning** | 6 regex patterns for hardcoded API keys, tokens, private keys, passwords, GitHub tokens, OpenAI keys |
|
|
76
|
+
| **Command Validation** | Flags dangerous patterns (path traversal, shell chaining, `rm -rf`, `curl`/`wget` in commands, and more) |
|
|
77
|
+
| **🔴 Active Policy Engine (v0.4+)** | YAML-configurable rules: tool allowlist/denylist, regex pattern blocking, rate limiting, token budgets. Operates in `audit` (passive), `warn` (flag only), or `block` (active enforcement) modes |
|
|
78
|
+
| **Scoring** | Weighted 0–100 security score with actionable recommendations |
|
|
79
|
+
|
|
80
|
+
### 💰 Cost Audit (`audit_costs`)
|
|
81
|
+
|
|
50
82
|
- **Proxy Interceptor** — `mcp-guardian proxy` sits between your AI client and MCP servers, capturing every `tools/call` request/response
|
|
51
83
|
- **Real Token Counting** — Uses `tiktoken` (o200k_base encoding) on actual JSON-RPC traffic — no hardcoded estimates
|
|
52
84
|
- **Multi-Model Pricing** — 97 models across 17 providers (OpenAI, Anthropic, Google, DeepSeek, xAI, Meta, Mistral, and more)
|
|
@@ -54,28 +86,41 @@ MCP Guardian scans your Model Context Protocol (MCP) servers for security vulner
|
|
|
54
86
|
- **Custom Pricing** — Override via `PRICING_OVERRIDES` env var: `{"my-model": {"input": 2.0, "output": 6.0}}`
|
|
55
87
|
|
|
56
88
|
### ❤️ Health Monitor (`check_health`)
|
|
89
|
+
|
|
57
90
|
- **Live Probes** — Full JSON-RPC 2.0 handshake (initialize → initialized → `tools/list`) with request/response correlation
|
|
58
91
|
- **SSE Probing** — Multi-path discovery (`/`, `/sse`, `/message`) with auth header injection and timeout handling
|
|
59
92
|
- **Latency Tracking** — End-to-end latency per server with historical success rates from SQLite
|
|
60
93
|
- **Overload Detection** — Warns when >15 tools exposed; context pressure estimation
|
|
61
94
|
|
|
62
95
|
### 📊 Full Report (`full_report`)
|
|
96
|
+
|
|
63
97
|
- **Three Output Formats** — Colored text, Markdown tables, structured JSON (with `resource` MIME type for agent consumption)
|
|
64
98
|
- **Overall Score** — Composite security + health score (0–100)
|
|
65
|
-
- **Database Storage** — All scans, costs, health checks, and proxy-captured call records persisted in SQLite
|
|
99
|
+
- **Database Storage** — All scans, costs, health checks, and proxy-captured call records persisted in SQLite (4 tables, batched writes)
|
|
66
100
|
|
|
67
101
|
### 🔧 Production Features
|
|
102
|
+
|
|
68
103
|
- **Dependency Injection** — IoC container (`src/container.ts`) for testability and runtime swaps
|
|
69
104
|
- **Rate Limiting** — Token-bucket rate limiter on OSV.dev and NVD API calls
|
|
70
105
|
- **Graceful Shutdown** — SIGINT/SIGTERM handlers flush DB and close connections
|
|
71
106
|
- **Batched DB Writes** — 1s debounced flush reduces I/O by 10x
|
|
72
107
|
- **Alert Thresholds** — 6 CLI flags with exit codes 1/2 for CI/CD integration
|
|
73
|
-
- **GitHub Actions CI** — Node 18/20/22 matrix,
|
|
108
|
+
- **GitHub Actions CI** — Node 18/20/22 matrix, 74 tests across 11 suites
|
|
74
109
|
|
|
75
110
|
---
|
|
76
111
|
|
|
77
112
|
## Installation
|
|
78
113
|
|
|
114
|
+
### From npm (recommended)
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
npm install -g @mcp-guardian/server
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
After global install, the `mcp-guardian` command is available in your PATH.
|
|
121
|
+
|
|
122
|
+
### From source
|
|
123
|
+
|
|
79
124
|
```bash
|
|
80
125
|
git clone https://github.com/rudraneel93/mcp-guardian.git
|
|
81
126
|
cd mcp-guardian
|
|
@@ -83,7 +128,7 @@ npm install
|
|
|
83
128
|
npm run build
|
|
84
129
|
```
|
|
85
130
|
|
|
86
|
-
**Requirements:** Node.js ≥18, npm ≥9
|
|
131
|
+
**Requirements:** Node.js ≥ 18, npm ≥ 9
|
|
87
132
|
|
|
88
133
|
---
|
|
89
134
|
|
|
@@ -108,6 +153,7 @@ mcp-guardian report --config ./cline_mcp_settings.json
|
|
|
108
153
|
```
|
|
109
154
|
|
|
110
155
|
**Example output (real data from proxy against 3 MCP servers):**
|
|
156
|
+
|
|
111
157
|
```
|
|
112
158
|
💰 Cost Audit
|
|
113
159
|
github: 194 tokens, $0.0018 (gpt-4o)
|
|
@@ -128,57 +174,22 @@ puppeteer - Score: D (10) — 3 CVEs (1 critical), needs auth
|
|
|
128
174
|
Overall Score: 60/100
|
|
129
175
|
```
|
|
130
176
|
|
|
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
|
-
---
|
|
177
|
+
> **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.
|
|
134
178
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
To verify the full pipeline works end-to-end with real data (no mocks):
|
|
179
|
+
### One-Off Scan
|
|
138
180
|
|
|
139
181
|
```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
|
|
182
|
+
# Quick security scan on auto-discovered configs
|
|
183
|
+
mcp-guardian scan
|
|
170
184
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
filesystem: C (50) — 20 CVEs (1 high), needs auth
|
|
174
|
-
puppeteer: D (10) — 3 CVEs (1 critical), needs auth
|
|
185
|
+
# Scan with thresholds for CI
|
|
186
|
+
mcp-guardian scan --config ./cline_mcp_settings.json --fail-on-critical --fail-on-secrets --threshold-score 70
|
|
175
187
|
|
|
176
|
-
|
|
177
|
-
github
|
|
178
|
-
filesystem: 1253ms, 14 tools ✅ healthy
|
|
179
|
-
puppeteer: 1275ms, 7 tools ✅ healthy
|
|
188
|
+
# Check health
|
|
189
|
+
mcp-guardian health --server github-server --fail-on-overload --threshold-latency 2000
|
|
180
190
|
|
|
181
|
-
|
|
191
|
+
# Generate a Markdown report for documentation
|
|
192
|
+
mcp-guardian report --format markdown --output audit-report.md
|
|
182
193
|
```
|
|
183
194
|
|
|
184
195
|
---
|
|
@@ -187,21 +198,68 @@ Overall Score: 60/100
|
|
|
187
198
|
|
|
188
199
|
### `mcp-guardian proxy`
|
|
189
200
|
|
|
190
|
-
Start the MCP proxy interceptor
|
|
201
|
+
Start the MCP proxy interceptor with optional active policy enforcement.
|
|
191
202
|
|
|
192
203
|
```bash
|
|
204
|
+
# Audit-only (passive)
|
|
193
205
|
mcp-guardian proxy --config ./cline_mcp_settings.json
|
|
194
|
-
```
|
|
195
206
|
|
|
196
|
-
|
|
207
|
+
# Active blocking with default policy
|
|
208
|
+
mcp-guardian proxy --config ./cline_mcp_settings.json --policy ./default-policy.yaml
|
|
209
|
+
|
|
210
|
+
# Active blocking with custom policy + mode override
|
|
211
|
+
mcp-guardian proxy --config ./cline_mcp_settings.json --policy ./my-policy.yaml --blocking-mode block
|
|
212
|
+
```
|
|
197
213
|
|
|
198
214
|
| Option | Description |
|
|
199
|
-
|
|
215
|
+
|---|---|
|
|
200
216
|
| `-c, --config <path>` | Path to MCP config file |
|
|
217
|
+
| `--policy <path>` | Path to policy YAML file (enables active blocking) |
|
|
218
|
+
| `--blocking-mode <mode>` | Override policy mode: `audit` (passive), `warn` (flag), `block` (enforce) |
|
|
219
|
+
|
|
220
|
+
### Policy Engine (v0.4+)
|
|
221
|
+
|
|
222
|
+
The policy engine evaluates every intercepted `tools/call` before it reaches the MCP server. Define rules in YAML:
|
|
223
|
+
|
|
224
|
+
```yaml
|
|
225
|
+
# my-policy.yaml
|
|
226
|
+
version: "1.0"
|
|
227
|
+
policy:
|
|
228
|
+
mode: block
|
|
229
|
+
rules:
|
|
230
|
+
- name: "deny-shell-tools"
|
|
231
|
+
action: block
|
|
232
|
+
tools: { deny: ["execute_command", "bash", "sh", "eval", "exec"] }
|
|
233
|
+
- name: "block-injection"
|
|
234
|
+
action: block
|
|
235
|
+
patterns:
|
|
236
|
+
- "rm\\s+-rf"
|
|
237
|
+
- "curl\\s|wget\\s"
|
|
238
|
+
- ";\\s*\\w"
|
|
239
|
+
- "&&|\\|\\|"
|
|
240
|
+
- name: "rate-limit"
|
|
241
|
+
action: flag
|
|
242
|
+
maxCallsPerMinute: 60
|
|
243
|
+
- name: "token-budget"
|
|
244
|
+
action: flag
|
|
245
|
+
maxTokens: 50000
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
**Blocked calls** return a JSON-RPC 2.0 error to the client:
|
|
249
|
+
```json
|
|
250
|
+
{"jsonrpc":"2.0","id":"abc-123","error":{"code":-32001,"message":"Blocked by MCP Guardian policy: Tool 'execute_command' is explicitly denied"}}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
**Policy modes:**
|
|
254
|
+
| Mode | Behavior |
|
|
255
|
+
|---|---|
|
|
256
|
+
| `audit` | Pass all calls; log decisions only (passive) |
|
|
257
|
+
| `warn` | Downgrade `block` actions to `flag`; log warnings |
|
|
258
|
+
| `block` | Full active enforcement — blocked calls never reach the MCP server |
|
|
201
259
|
|
|
202
260
|
### `mcp-guardian scan`
|
|
203
261
|
|
|
204
|
-
Run security scan on MCP servers.
|
|
262
|
+
Run security scan on MCP servers.
|
|
205
263
|
|
|
206
264
|
```bash
|
|
207
265
|
mcp-guardian scan
|
|
@@ -210,8 +268,8 @@ mcp-guardian scan --all --threshold-score 70
|
|
|
210
268
|
```
|
|
211
269
|
|
|
212
270
|
| Option | Description |
|
|
213
|
-
|
|
214
|
-
| `-c, --config <path>` | Path to MCP config file |
|
|
271
|
+
|---|---|
|
|
272
|
+
| `-c, --config <path>` | Path to an MCP config file |
|
|
215
273
|
| `-a, --all` | Aggregate all discoverable configs |
|
|
216
274
|
| `--threshold-score <n>` | Exit code 2 if any server score drops below `n` |
|
|
217
275
|
| `--fail-on-critical` | Exit code 1 if any critical CVE found |
|
|
@@ -228,8 +286,8 @@ mcp-guardian audit --threshold-cost 0.50
|
|
|
228
286
|
```
|
|
229
287
|
|
|
230
288
|
| Option | Description |
|
|
231
|
-
|
|
232
|
-
| `-c, --config <path>` | Path to MCP config file |
|
|
289
|
+
|---|---|
|
|
290
|
+
| `-c, --config <path>` | Path to an MCP config file |
|
|
233
291
|
| `-a, --all` | Aggregate all discoverable configs |
|
|
234
292
|
| `-s, --server <name>` | Filter to a specific server |
|
|
235
293
|
| `--threshold-cost <n>` | Exit code 2 if total cost exceeds `n` USD |
|
|
@@ -245,8 +303,8 @@ mcp-guardian health --threshold-latency 2000 --fail-on-overload
|
|
|
245
303
|
```
|
|
246
304
|
|
|
247
305
|
| Option | Description |
|
|
248
|
-
|
|
249
|
-
| `-c, --config <path>` | Path to MCP config file |
|
|
306
|
+
|---|---|
|
|
307
|
+
| `-c, --config <path>` | Path to an MCP config file |
|
|
250
308
|
| `-a, --all` | Aggregate all discoverable configs |
|
|
251
309
|
| `-s, --server <name>` | Filter to a specific server |
|
|
252
310
|
| `--threshold-latency <ms>` | Exit code 2 if any server exceeds latency threshold |
|
|
@@ -264,18 +322,32 @@ mcp-guardian report --all --threshold-score 60
|
|
|
264
322
|
```
|
|
265
323
|
|
|
266
324
|
| Option | Description |
|
|
267
|
-
|
|
268
|
-
| `-c, --config <path>` | Path to MCP config file |
|
|
325
|
+
|---|---|
|
|
326
|
+
| `-c, --config <path>` | Path to an MCP config file |
|
|
269
327
|
| `-a, --all` | Aggregate all discoverable configs |
|
|
270
|
-
| `-f, --format <fmt>` | Output format: `text
|
|
328
|
+
| `-f, --format <fmt>` | Output format: `text` (default), `markdown`, or `json` |
|
|
329
|
+
| `--output <path>` | Save report to a file instead of stdout |
|
|
271
330
|
| `--threshold-score <n>` | Exit code 2 if overall score drops below `n` |
|
|
272
331
|
|
|
273
332
|
---
|
|
274
333
|
|
|
275
|
-
## MCP Server (
|
|
334
|
+
## MCP Server (AI Assistant Integration)
|
|
276
335
|
|
|
277
336
|
Add to your `cline_mcp_settings.json` or `claude_desktop_config.json`:
|
|
278
337
|
|
|
338
|
+
```json
|
|
339
|
+
{
|
|
340
|
+
"mcpServers": {
|
|
341
|
+
"mcp-guardian": {
|
|
342
|
+
"command": "npx",
|
|
343
|
+
"args": ["-y", "@mcp-guardian/server"]
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
Or with a local install:
|
|
350
|
+
|
|
279
351
|
```json
|
|
280
352
|
{
|
|
281
353
|
"mcpServers": {
|
|
@@ -287,30 +359,103 @@ Add to your `cline_mcp_settings.json` or `claude_desktop_config.json`:
|
|
|
287
359
|
}
|
|
288
360
|
```
|
|
289
361
|
|
|
290
|
-
|
|
362
|
+
### Available Tools
|
|
291
363
|
|
|
292
364
|
| Tool | Parameters | Description |
|
|
293
|
-
|
|
294
|
-
| `scan_security` | `configPath?` | Scan MCP configs for CVEs, auth gaps, typo-squatting,
|
|
365
|
+
|---|---|---|
|
|
366
|
+
| `scan_security` | `configPath?` | Scan MCP configs for CVEs, auth gaps, typo-squatting, hardcoded secrets, and dangerous commands |
|
|
295
367
|
| `audit_costs` | `serverName?` | Estimate token usage and costs per server with multi-model pricing |
|
|
296
368
|
| `check_health` | `serverName?` | Check latency, success rate, tool count, and context pressure |
|
|
297
|
-
| `full_report` | `configPath?`, `format?` (json\|markdown\|text) | Generate complete audit report |
|
|
369
|
+
| `full_report` | `configPath?`, `format?` (json\|markdown\|text) | Generate complete audit report in any format |
|
|
298
370
|
|
|
299
|
-
JSON format reports also include a structured `resource` content type
|
|
371
|
+
JSON format reports also include a structured `resource` content type (MIME: `application/json`) so AI assistants can consume reports programmatically.
|
|
372
|
+
|
|
373
|
+
### Available Resources & Prompts
|
|
374
|
+
|
|
375
|
+
- **Resource:** `mcp-guardian://latest-scan` — exposes the most recent security scan as structured JSON
|
|
376
|
+
- **Prompt:** `audit-config` — generates structured audit instructions for an MCP config path, which the assistant can use to guide its investigation
|
|
300
377
|
|
|
301
378
|
---
|
|
302
379
|
|
|
303
380
|
## CI/CD Integration
|
|
304
381
|
|
|
305
|
-
Run in
|
|
382
|
+
Run MCP Guardian in CI to catch issues before deployment:
|
|
306
383
|
|
|
307
384
|
```yaml
|
|
308
385
|
- name: MCP Guardian Security Scan
|
|
309
|
-
run: npx mcp-guardian scan --config ./cline_mcp_settings.json --fail-on-critical --fail-on-secrets
|
|
386
|
+
run: npx @mcp-guardian/server scan --config ./cline_mcp_settings.json --fail-on-critical --fail-on-secrets
|
|
310
387
|
env:
|
|
311
388
|
NVD_API_KEY: ${{ secrets.NVD_API_KEY }}
|
|
389
|
+
|
|
390
|
+
- name: MCP Guardian Cost Audit
|
|
391
|
+
run: npx @mcp-guardian/server audit --all --threshold-cost 0.50
|
|
392
|
+
|
|
393
|
+
- name: MCP Guardian Health Check
|
|
394
|
+
run: npx @mcp-guardian/server health --all --threshold-latency 3000 --fail-on-overload
|
|
312
395
|
```
|
|
313
396
|
|
|
397
|
+
### Exit Codes
|
|
398
|
+
|
|
399
|
+
| Code | Meaning |
|
|
400
|
+
|---|---|
|
|
401
|
+
| 0 | All checks passed within thresholds |
|
|
402
|
+
| 1 | Critical security issue found (critical CVE, secret, overload) |
|
|
403
|
+
| 2 | Threshold exceeded (score, cost, or latency below/above limit) |
|
|
404
|
+
|
|
405
|
+
---
|
|
406
|
+
|
|
407
|
+
## Production Deployment (K8s + Helm)
|
|
408
|
+
|
|
409
|
+
See the full guide at **[deploy/PRODUCTION.md](deploy/PRODUCTION.md)**.
|
|
410
|
+
|
|
411
|
+
### Quick Helm Install
|
|
412
|
+
|
|
413
|
+
```bash
|
|
414
|
+
# Install from local chart
|
|
415
|
+
helm install mcp-guardian ./deploy/helm/mcp-guardian \
|
|
416
|
+
--set config.policy.mode=block \
|
|
417
|
+
--set config.mcpConfigPath=/etc/mcp-guardian/cline_mcp_settings.json
|
|
418
|
+
|
|
419
|
+
# Or from the repo (future)
|
|
420
|
+
helm repo add mcp-guardian https://rudraneel93.github.io/mcp-guardian
|
|
421
|
+
helm install mcp-guardian mcp-guardian/mcp-guardian
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
### Key Features
|
|
425
|
+
- **Helm chart** with ConfigMap-backed policies, PVC persistence, and safe defaults
|
|
426
|
+
- **Fail-closed** by default (block traffic if proxy crashes) — configurable to fail-open
|
|
427
|
+
- **Sidecar injection pattern** documented for stdio MCP servers
|
|
428
|
+
- **Scaling guide** with CPU/memory recommendations per traffic level
|
|
429
|
+
- **Pod Disruption Budget** for HA, anti-affinity for multi-AZ
|
|
430
|
+
- **SIEM integration** via pino structured JSON logs (Splunk, Datadog, Elasticsearch)
|
|
431
|
+
|
|
432
|
+
### Performance Overhead
|
|
433
|
+
|
|
434
|
+
| Scenario | p50 | p99 | Overhead |
|
|
435
|
+
|----------|-----|-----|----------|
|
|
436
|
+
| Direct MCP (no proxy) | 5ms | 7ms | — |
|
|
437
|
+
| Proxy (no policy) | 27ms | 77ms | +25.78ms |
|
|
438
|
+
| Proxy (blocking policy) | 27ms | 74ms | +25.93ms |
|
|
439
|
+
|
|
440
|
+
Policy engine adds **~0.15ms** — negligible. The ~26ms is Node.js child process stdio overhead.
|
|
441
|
+
|
|
442
|
+
## Docker
|
|
443
|
+
|
|
444
|
+
A Docker image is available for running the proxy in containerized environments.
|
|
445
|
+
|
|
446
|
+
```bash
|
|
447
|
+
# Build
|
|
448
|
+
docker build -t mcp-guardian .
|
|
449
|
+
|
|
450
|
+
# Run proxy
|
|
451
|
+
docker run -i \
|
|
452
|
+
-v $(pwd)/cline_mcp_settings.json:/app/cline_mcp_settings.json \
|
|
453
|
+
-v mcp-guardian-db:/root/.mcp-guardian \
|
|
454
|
+
mcp-guardian --config /app/cline_mcp_settings.json
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
The `Dockerfile` uses `node:20-alpine` and runs `mcp-guardian proxy` as the default entrypoint.
|
|
458
|
+
|
|
314
459
|
---
|
|
315
460
|
|
|
316
461
|
## Architecture
|
|
@@ -319,9 +464,9 @@ Run in GitHub Actions to catch security issues before deployment:
|
|
|
319
464
|
mcp-guardian/
|
|
320
465
|
├── src/
|
|
321
466
|
│ ├── 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 #
|
|
467
|
+
│ ├── cli.ts # CLI wrapper (5 commands: proxy, scan, audit, health, report)
|
|
468
|
+
│ ├── container.ts # Dependency injection container (IoC)
|
|
469
|
+
│ ├── types.ts # Shared TypeScript interfaces (8 types)
|
|
325
470
|
│ ├── config-parser.ts # Multi-format config parsing with multi-file aggregation
|
|
326
471
|
│ │
|
|
327
472
|
│ ├── proxy/ # MCP Proxy Interceptor (real cost engine)
|
|
@@ -334,18 +479,19 @@ mcp-guardian/
|
|
|
334
479
|
│ │ └── health-monitor.ts # Live JSON-RPC probing + DB integration
|
|
335
480
|
│ │
|
|
336
481
|
│ ├── scanners/ # Individual security checks
|
|
337
|
-
│ │ ├── cve-checker.ts # OSV.dev → NVD fallback chain
|
|
338
|
-
│ │ ├── auth-prober.ts # Auth/transport detection (env + URL)
|
|
482
|
+
│ │ ├── cve-checker.ts # OSV.dev → NVD fallback chain (rate-limited)
|
|
483
|
+
│ │ ├── auth-prober.ts # Auth/transport detection (env + URL patterns)
|
|
339
484
|
│ │ ├── typo-squat-detector.ts # Levenshtein distance (O(n) memory)
|
|
340
|
-
│ │
|
|
485
|
+
│ │ ├── secret-scanner.ts # 6 regex patterns for secrets
|
|
486
|
+
│ │ └── command-validator.ts # 10 suspicious pattern checks for command injection
|
|
341
487
|
│ │
|
|
342
488
|
│ ├── 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
|
|
489
|
+
│ │ ├── osv-client.ts # api.osv.dev (purl-based, token-bucket rate-limited)
|
|
490
|
+
│ │ ├── nvd-client.ts # NIST NVD (API key support, rate-limited)
|
|
491
|
+
│ │ └── pricing-client.ts # 97 models, 17 providers, custom override support
|
|
346
492
|
│ │
|
|
347
493
|
│ ├── database/
|
|
348
|
-
│ │ └── history-db.ts # SQLite via sql.js (4 tables, batched writes)
|
|
494
|
+
│ │ └── history-db.ts # SQLite via sql.js (4 tables, batched writes, 1s debounce)
|
|
349
495
|
│ │
|
|
350
496
|
│ ├── reporter/
|
|
351
497
|
│ │ └── report-generator.ts # Text, Markdown, JSON formatting
|
|
@@ -354,12 +500,26 @@ mcp-guardian/
|
|
|
354
500
|
│ ├── token-counter.ts # tiktoken (o200k_base) wrapper
|
|
355
501
|
│ ├── mcp-client.ts # Full JSON-RPC 2.0 state machine + SSE probing
|
|
356
502
|
│ ├── rate-limiter.ts # Token-bucket rate limiter
|
|
357
|
-
│ ├── tls-checker.ts # TLS certificate validation
|
|
503
|
+
│ ├── tls-checker.ts # TLS certificate validation (expiry, issuer, chain)
|
|
358
504
|
│ ├── scoring.ts # Shared scoring utility
|
|
359
|
-
│ └── logger.ts # Colored console logger
|
|
505
|
+
│ └── logger.ts # Colored console logger with log levels
|
|
506
|
+
│
|
|
507
|
+
tests/ # 74 tests across 11 suites (Vitest)
|
|
508
|
+
├── config-parser.test.ts
|
|
509
|
+
├── secret-scanner.test.ts
|
|
510
|
+
├── auth-prober.test.ts
|
|
511
|
+
├── typo-squat-detector.test.ts
|
|
512
|
+
├── scoring.test.ts
|
|
513
|
+
├── pricing-client.test.ts
|
|
514
|
+
├── services/
|
|
515
|
+
│ ├── cost-auditor.test.ts
|
|
516
|
+
│ └── security-scanner.test.ts
|
|
517
|
+
└── integration/
|
|
518
|
+
├── proxy-audit.test.ts
|
|
519
|
+
└── full-pipeline.test.ts
|
|
360
520
|
```
|
|
361
521
|
|
|
362
|
-
### Data Flow
|
|
522
|
+
### Data Flow (Proxy → DB → Audit)
|
|
363
523
|
|
|
364
524
|
```
|
|
365
525
|
AI Client (Cline/Claude)
|
|
@@ -370,10 +530,10 @@ AI Client (Cline/Claude)
|
|
|
370
530
|
│ MCP Proxy Server │ ← mcp-guardian proxy
|
|
371
531
|
│ (proxy-server.ts) │
|
|
372
532
|
└───────┬───────────┘
|
|
373
|
-
│ counts tokens (tiktoken)
|
|
533
|
+
│ counts tokens (tiktoken o200k_base)
|
|
374
534
|
▼
|
|
375
535
|
┌───────────────────┐
|
|
376
|
-
│ call_records table │ ← SQLite
|
|
536
|
+
│ call_records table │ ← SQLite (sql.js)
|
|
377
537
|
│ (history-db.ts) │
|
|
378
538
|
└───────┬───────────┘
|
|
379
539
|
│ async getCallRecordsForServer()
|
|
@@ -382,7 +542,7 @@ AI Client (Cline/Claude)
|
|
|
382
542
|
│ Cost Auditor │ ← mcp-guardian audit / report
|
|
383
543
|
│ (cost-auditor.ts) │
|
|
384
544
|
└───────────────────┘
|
|
385
|
-
│ per-tool breakdown + multi-model pricing
|
|
545
|
+
│ per-tool breakdown + multi-model pricing (97 models)
|
|
386
546
|
▼
|
|
387
547
|
Cost Report ($0.0023, gpt-4o)
|
|
388
548
|
```
|
|
@@ -394,17 +554,17 @@ AI Client (Cline/Claude)
|
|
|
394
554
|
MCP Guardian auto-discovers config files from these standard locations:
|
|
395
555
|
|
|
396
556
|
| Client | Config Path |
|
|
397
|
-
|
|
557
|
+
|---|---|
|
|
398
558
|
| **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
|
|
559
|
+
| **Cline (VS Code Insiders)** | `~/Library/Application Support/Code - Insiders/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json` |
|
|
560
|
+
| **Cline (Linux)** | `~/.config/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json` |
|
|
561
|
+
| **Cline (Windows)** | `%APPDATA%/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json` |
|
|
402
562
|
| **Claude Desktop (macOS)** | `~/Library/Application Support/Claude/claude_desktop_config.json` |
|
|
403
563
|
| **Claude Desktop (Linux)** | `~/.config/Claude/claude_desktop_config.json` |
|
|
404
564
|
| **Cursor** | `~/.cursor/mcp.json` |
|
|
405
565
|
| **Windsurf** | `~/.codeium/windsurf/mcp_config.json` |
|
|
406
566
|
|
|
407
|
-
Use `--config` / `
|
|
567
|
+
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
568
|
|
|
409
569
|
---
|
|
410
570
|
|
|
@@ -413,7 +573,7 @@ Use `--config` / `configPath` for a custom path, or `--all` to aggregate all dis
|
|
|
413
573
|
Each server receives a score from 0–100 with these deductions:
|
|
414
574
|
|
|
415
575
|
| Finding | Deduction |
|
|
416
|
-
|
|
576
|
+
|---|---|
|
|
417
577
|
| Critical CVEs detected | −40 |
|
|
418
578
|
| High-severity CVEs | −20 |
|
|
419
579
|
| Medium-severity CVEs | −10 |
|
|
@@ -421,6 +581,8 @@ Each server receives a score from 0–100 with these deductions:
|
|
|
421
581
|
| Unencrypted transport | −10 |
|
|
422
582
|
| Typo-squat detected | −30 |
|
|
423
583
|
| Hardcoded secrets found | −15 |
|
|
584
|
+
| High-severity command warning | −25 |
|
|
585
|
+
| Medium-severity command warning | −10 |
|
|
424
586
|
|
|
425
587
|
**Letter grades:** A (80–100), B (60–79), C (40–59), D (0–39)
|
|
426
588
|
|
|
@@ -430,29 +592,30 @@ Each server receives a score from 0–100 with these deductions:
|
|
|
430
592
|
|
|
431
593
|
97 models across 17 providers. Cached rates per 1M tokens (as of mid-2025):
|
|
432
594
|
|
|
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
|
|
595
|
+
| Provider | Models | Example Rates (input/output per 1M) |
|
|
596
|
+
|---|---|---|
|
|
597
|
+
| OpenAI (14) | gpt-4o, gpt-4.5-preview, o1, o3, o4-mini, gpt-3.5-turbo | $5/$15 |
|
|
598
|
+
| Anthropic (8) | claude-3-5-sonnet, claude-opus, claude-haiku | $3/$15 |
|
|
599
|
+
| Google (12) | gemini-2.5-pro, gemini-2.0-flash, gemma | $1.25/$10 |
|
|
600
|
+
| DeepSeek (4) | deepseek-chat, deepseek-reasoner, deepseek-v3 | $0.14/$0.28 |
|
|
601
|
+
| xAI/Grok (5) | grok-3, grok-3-mini | $3/$15 |
|
|
602
|
+
| Meta/Llama (8) | llama-4-maverick, llama-3.3-70b | $0.2/$0.6 |
|
|
603
|
+
| Mistral (9) | mistral-large, mixtral-8x22b, codestral | $2/$6 |
|
|
604
|
+
| + 10 more | Cohere, AI21, Reka, Amazon, Alibaba, Zhipu, 01.AI, Writer, Perplexity, HuggingFace | varies |
|
|
443
605
|
|
|
444
|
-
Unknown models receive a conservative default estimate of $10/$30 per million tokens. Override via `PRICING_OVERRIDES` env var.
|
|
606
|
+
Unknown models receive a conservative default estimate of $10/$30 per million tokens. Override any model via the `PRICING_OVERRIDES` env var.
|
|
445
607
|
|
|
446
608
|
---
|
|
447
609
|
|
|
448
610
|
## Environment Variables
|
|
449
611
|
|
|
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}}` |
|
|
612
|
+
| Variable | Purpose | Default |
|
|
613
|
+
|---|---|---|
|
|
614
|
+
| `NVD_API_KEY` | NIST NVD API key for CVE lookups (20 req/min vs 5 without) | (none) |
|
|
615
|
+
| `MCP_GUARDIAN_DB_PATH` | Override SQLite database path | `~/.mcp-guardian/history.db` |
|
|
616
|
+
| `LOG_LEVEL` | Logging level: `DEBUG`, `INFO`, `WARN`, `ERROR` | `INFO` |
|
|
617
|
+
| `PRICING_OVERRIDES` | Custom pricing JSON: `{"my-model": {"input": 2.0, "output": 6.0}}` | (none) |
|
|
618
|
+
| `OPENAI_API_KEY` | Optionally used by tiktoken for token counting | (none) |
|
|
456
619
|
|
|
457
620
|
---
|
|
458
621
|
|
|
@@ -465,18 +628,69 @@ cd mcp-guardian
|
|
|
465
628
|
npm install
|
|
466
629
|
|
|
467
630
|
# Development
|
|
468
|
-
npm run dev
|
|
469
|
-
npm run build
|
|
470
|
-
npm run lint
|
|
471
|
-
npm test
|
|
472
|
-
npm run test:watch
|
|
631
|
+
npm run dev # Watch mode with tsx
|
|
632
|
+
npm run build # Compile TypeScript
|
|
633
|
+
npm run lint # Type check (tsc --noEmit)
|
|
634
|
+
npm test # 74 tests across 11 suites (Vitest)
|
|
635
|
+
npm run test:watch # Watch mode
|
|
473
636
|
|
|
474
637
|
# Contributing
|
|
475
|
-
See CONTRIBUTING.md for guidelines on adding scanners, pricing models, and tests.
|
|
638
|
+
# See CONTRIBUTING.md for guidelines on adding scanners, pricing models, and tests.
|
|
476
639
|
```
|
|
477
640
|
|
|
478
641
|
---
|
|
479
642
|
|
|
643
|
+
## FAQ
|
|
644
|
+
|
|
645
|
+
### Why does `mcp-guardian audit` show $0.0000?
|
|
646
|
+
|
|
647
|
+
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.
|
|
648
|
+
|
|
649
|
+
### Do I need an NVD API key?
|
|
650
|
+
|
|
651
|
+
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.
|
|
652
|
+
|
|
653
|
+
### How do I run the proxy alongside my AI assistant?
|
|
654
|
+
|
|
655
|
+
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.
|
|
656
|
+
|
|
657
|
+
### What does the proxy intercept?
|
|
658
|
+
|
|
659
|
+
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.
|
|
660
|
+
|
|
661
|
+
### Can I use MCP Guardian with SSE/HTTP transports?
|
|
662
|
+
|
|
663
|
+
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.
|
|
664
|
+
|
|
665
|
+
### How do I override pricing for my custom model?
|
|
666
|
+
|
|
667
|
+
Set the `PRICING_OVERRIDES` environment variable with JSON:
|
|
668
|
+
|
|
669
|
+
```bash
|
|
670
|
+
export PRICING_OVERRIDES='{"my-custom-model": {"input": 2.0, "output": 6.0}}'
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
Rates are in USD per 1 million tokens.
|
|
674
|
+
|
|
675
|
+
### Where is the database stored?
|
|
676
|
+
|
|
677
|
+
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`.
|
|
678
|
+
|
|
679
|
+
### What's the difference between `--config` and `--all`?
|
|
680
|
+
|
|
681
|
+
- `--config <path>` loads a single config file
|
|
682
|
+
- `--all` auto-discovers and aggregates all config files from known locations (Cline, Claude Desktop, Cursor, Windsurf), deduplicating servers by name
|
|
683
|
+
|
|
684
|
+
### Can I run MCP Guardian in CI/CD?
|
|
685
|
+
|
|
686
|
+
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.
|
|
687
|
+
|
|
688
|
+
### How accurate is the token counting?
|
|
689
|
+
|
|
690
|
+
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.
|
|
691
|
+
|
|
692
|
+
---
|
|
693
|
+
|
|
480
694
|
## Roadmap
|
|
481
695
|
|
|
482
696
|
- [x] Core security, cost, and health scanning
|
|
@@ -492,9 +706,21 @@ See CONTRIBUTING.md for guidelines on adding scanners, pricing models, and tests
|
|
|
492
706
|
- [x] Dependency injection container (IoC pattern)
|
|
493
707
|
- [x] Token-bucket rate limiter (OSV + NVD)
|
|
494
708
|
- [x] TLS certificate validation
|
|
495
|
-
- [x]
|
|
709
|
+
- [x] Command injection validation (10 suspicious patterns)
|
|
710
|
+
- [x] Active policy engine — YAML-based pass/block/flag with allowlists, regex, rate limiting, token budgets
|
|
711
|
+
- [x] Structured JSON logging (pino) for SIEM ingestion
|
|
712
|
+
- [x] STRIDE threat model (SECURITY.md)
|
|
713
|
+
- [x] 74 tests (11 suites)
|
|
496
714
|
- [x] GitHub Actions CI (Node 18/20/22 matrix)
|
|
497
|
-
- [
|
|
715
|
+
- [x] Performance benchmarks (p50: 5ms baseline, +25.78ms proxy overhead, +0.15ms policy)
|
|
716
|
+
- [x] Helm chart + production deployment guide (K8s, fail-open/closed, sidecar pattern, scaling)
|
|
717
|
+
- [x] Published to npm as [`@mcp-guardian/server`](https://www.npmjs.com/package/@mcp-guardian/server)
|
|
718
|
+
- [ ] OPA integration for Rego policies
|
|
719
|
+
- [ ] OAuth 2.1 / OIDC proxy authentication
|
|
720
|
+
- [ ] Web dashboard for historical trends
|
|
721
|
+
- [ ] Slack/Discord alerting
|
|
722
|
+
- [ ] Prometheus metrics endpoint
|
|
723
|
+
- [ ] Multi-user proxy
|
|
498
724
|
|
|
499
725
|
---
|
|
500
726
|
|
|
@@ -502,4 +728,4 @@ See CONTRIBUTING.md for guidelines on adding scanners, pricing models, and tests
|
|
|
502
728
|
|
|
503
729
|
MIT — see [LICENSE](LICENSE) for details.
|
|
504
730
|
|
|
505
|
-
**Built with TypeScript, @modelcontextprotocol/sdk, tiktoken, sql.js, and
|
|
731
|
+
**Built with TypeScript, @modelcontextprotocol/sdk, tiktoken, sql.js, commander, chalk, and zod.**
|