@mcp-guardian/cli 4.1.2

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,9 @@
1
+
2
+ 
3
+ > @mcp-guardian/cli@4.1.2 build /Users/rudraneeldas/Desktop/mcp-guardian/packages/cli
4
+ > pnpm --dir ../server run build && tsc
5
+
6
+
7
+ > @mcp-guardian/server@4.1.2 build /Users/rudraneeldas/Desktop/mcp-guardian/packages/server
8
+ > tsc
9
+
@@ -0,0 +1,49 @@
1
+
2
+ 
3
+ > @mcp-guardian/cli@4.1.2 test /Users/rudraneeldas/Desktop/mcp-guardian/packages/cli
4
+ > vitest run
5
+
6
+ [?25l
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+ 2:05:29 AM [vite] warning: `esbuild` option was specified by "vitest" plugin. This option is deprecated, please use `oxc` instead.
23
+
24
+  RUN  v3.2.4 /Users/rudraneeldas/Desktop/mcp-guardian/packages/cli
25
+
26
+ [?2026h
27
+  ❯ tests/index.test.ts [queued]
28
+
29
+  Test Files 0 passed (1)
30
+  Tests 0 passed (0)
31
+  Start at 02:05:29
32
+  Duration 202ms
33
+ [?2026l ✓ tests/index.test.ts (9 tests) 3ms
34
+ ✓ CLI — argument parsing > should support --fail-on-critical flag 1ms
35
+ ✓ CLI — argument parsing > should support --json flag 0ms
36
+ ✓ CLI — argument parsing > should support --skip-semantic flag 0ms
37
+ ✓ CLI — argument parsing > should support --verbose shorthand -v 0ms
38
+ ✓ CLI — argument parsing > should accept a positional config path 0ms
39
+ ✓ CLI — argument parsing > should default all flags to false 0ms
40
+ ✓ CLI — report formatting > should format a clean server result 0ms
41
+ ✓ CLI — report formatting > should identify critical status 0ms
42
+ ✓ CLI — report formatting > should identify warning status 0ms
43
+
44
+  Test Files  1 passed (1)
45
+  Tests  9 passed (9)
46
+  Start at  02:05:29
47
+  Duration  238ms (transform 18ms, setup 0ms, collect 14ms, tests 3ms, environment 0ms, prepare 38ms)
48
+
49
+ [?25h
package/README.md ADDED
@@ -0,0 +1,586 @@
1
+ # 🛡️ MCP Guardian
2
+
3
+ **Runtime security, cost governance, and health monitoring proxy for MCP infrastructure.**
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@mcp-guardian/server)](https://www.npmjs.com/package/@mcp-guardian/server)
6
+ [![npm downloads](https://img.shields.io/npm/dm/@mcp-guardian/server)](https://www.npmjs.com/package/@mcp-guardian/server)
7
+ [![mcp-guardian MCP server](https://glama.ai/mcp/servers/rudraneel93/mcp-guardian/badges/score.svg)](https://glama.ai/mcp/servers/rudraneel93/mcp-guardian)
8
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.4-blue)](https://www.typescriptlang.org/)
9
+ [![MCP SDK](https://img.shields.io/badge/MCP_SDK-1.0-green)](https://github.com/modelcontextprotocol/typescript-sdk)
10
+ [![License](https://img.shields.io/badge/License-MIT-yellow)](LICENSE)
11
+ [![CI](https://github.com/rudraneel93/mcp-guardian/actions/workflows/ci.yml/badge.svg)](https://github.com/rudraneel93/mcp-guardian/actions/workflows/ci.yml)
12
+
13
+ MCP Guardian sits between AI agents and MCP servers, enforcing **active security policies**, tracking **real token costs**, monitoring **server health**, and providing **enterprise observability** — all through a YAML-configurable engine with hot-reload.
14
+
15
+ It works as a **transparent proxy**, a **standalone CLI**, an **MCP server** (so agents can self-audit), and a **pnpm monorepo** — install only what you need.
16
+
17
+ ---
18
+
19
+ ## Quick Start
20
+
21
+ ```bash
22
+ # Install globally
23
+ npm install -g @mcp-guardian/server
24
+
25
+ # Scan your MCP servers for CVEs, secrets, and injection attacks
26
+ mcp-guardian scan --all
27
+
28
+ # Proxy with active policy enforcement
29
+ mcp-guardian proxy --policy ./default-policy.yaml --blocking-mode block
30
+
31
+ # Generate a full security-cost-health report
32
+ mcp-guardian report --all --format markdown --output guardian-report.md
33
+
34
+ # Run as an MCP server (AI agents can self-audit)
35
+ mcp-guardian # stdio transport, auto-starts MCP server
36
+ ```
37
+
38
+ ---
39
+
40
+ ## Features
41
+
42
+ ### Security
43
+ - **Three-layer detection engine** — Regex triage (38 patterns, 8 attack categories) → Schema analysis (parameters, defaults, enum injection) → LLM semantic verdict (Anthropic Claude), with semantic layer defaulting to run on **all** tools for comprehensive coverage
44
+ - **YAML policy engine** — Tool allowlists/denylists, regex patterns, rate limits, token budgets, RBAC, argument-level field patterns, destructive category detection, and **default-deny** (fail-closed) catch-all
45
+ - **Hot-reload policies** — File watcher atomically swaps policy engine on YAML changes — zero-downtime policy updates
46
+ - **50+ secret patterns** — OpenAI, Anthropic, GitHub, AWS, GCP, Azure, Stripe, Slack, Twilio, SendGrid, Datadog, CircleCI, Jenkins, Firebase, Cloudflare, HuggingFace, GitLab, NPM, Vercel, Heroku, database connection strings, RSA/PEM private keys, JWT secrets, and URI credentials
47
+ - **Shannon entropy analysis** — Detects base64/hex-encoded secrets that regex patterns miss, with configurable allowlist
48
+ - **AST command validation** — Shell-quote-based tokenizer with 33 dangerous commands, 6 structural operators, 5 suspicious path patterns, and Unicode homoglyph normalization (Cyrillic, fullwidth, zero-width attacks)
49
+ - **CVE scanning** — OSV.dev + NVD with transitive dependency tree scanning (200+ packages), direct/transitive triage, and LRU result caching
50
+ - **Response inspection** — Prompt injection and data exfiltration detection in tool responses
51
+ - **Hardcoded secret detection** — Scans adjacent `.env` files, `docker-compose.yml`, and environment variables
52
+ - **Typo-squatting detection** — Levenshtein distance analysis against known MCP server names
53
+ - **Auth weakness probing** — Missing authentication, unencrypted transport detection
54
+
55
+ ### Authentication & Zero Trust
56
+ - **OAuth 2.1 / OIDC** — JWT validation with OIDC Discovery, **algorithm pinning** (RS256/384/512, ES256/384, PS256 — rejects `alg: none` confusion attacks), audience/issuer validation, agent identity extraction
57
+ - **DPoP** — RFC 9449 sender-constrained tokens for replay-proof authentication
58
+ - **RBAC** — Scope-based and client-ID-based access control in policy engine
59
+ - **mTLS** — Mutual TLS with client certificates for proxy ↔ upstream communication
60
+ - **Dashboard authentication** — JWT session tokens, API key auth, CSRF protection, rate-limited login
61
+
62
+ ### Cost Governance
63
+ - **Real token counting** — Proxy intercepts `tools/call` traffic and counts tokens via `tiktoken` (o200k_base for OpenAI, char-ratio estimates for Anthropic/Google/DeepSeek/Meta/Mistral)
64
+ - **17 providers, 2,138 models** — Live pricing via litellm, with per-model cost comparison
65
+ - **Cost efficiency scoring** — Weighted 3-way composite score: security (40%), health (30%), cost efficiency (30%)
66
+ - **Per-tool breakdown** — Tokens, duration, and estimated cost for every intercepted call
67
+
68
+ ### Health & Observability
69
+ - **Live JSON-RPC probes** — Latency, success rate, tool count, and context pressure
70
+ - **Circuit breaker** — 3-state pattern (CLOSED, OPEN, HALF_OPEN) protects upstream servers from cascading failures
71
+ - **Prometheus metrics** — Counters (requests, blocked, auth failures), gauges (circuit breaker state, active sessions), histograms (proxy latency, auth latency)
72
+ - **`/healthz` and `/readyz` endpoints** — Liveness and readiness probes for K8s deployment
73
+ - **WebSocket dashboard** — Real-time push broadcaster replacing 5s polling, with graceful fallback
74
+ - **OpenTelemetry** — Distributed tracing across proxy and MCP servers via OTLP
75
+ - **Structured logging** — pino with request-ID tracing, policy decision audit trails
76
+ - **Webhook alerting** — Slack and Discord webhook support for critical policy events with severity filtering
77
+
78
+ ### Architecture
79
+ - **pnpm monorepo** — `packages/core` (detection engine), `packages/cli`, `packages/server` (MCP server), plus root `src/` (proxy, scanners, services, policy, auth)
80
+ - **better-sqlite3** — Native, WAL-mode, crash-safe database with **advisory file locking** (prevents multi-instance corruption), versioned migrations, automated purge, and prepared statements
81
+ - **Dependency injection interfaces** — `IHistoryDb`, `ISecurityScanner`, `ICostAuditor`, `IHealthMonitor`, `IPolicyEngine` for testability and swappable implementations
82
+ - **Secret provider interface** — Pluggable secret backends: EnvSecretProvider (default), HashiCorpVaultProvider, AwsSecretsManagerProvider
83
+ - **Redis cluster-state enforcement** — Warns on multi-replica/K8s without Redis; `GUARDIAN_STRICT_MODE=true` refuses startup
84
+ - **Graceful shutdown** — Async hook system flushes DB, closes connections, and WAL-checkpoints before exit
85
+
86
+ ### Deployment
87
+ - **Helm chart** — K8s Deployment with liveness/readiness probes, resource limits, security context (non-root, read-only filesystem, dropped capabilities), NetworkPolicy (ingress/egress rules, CIDR-based dashboard access), and ExternalSecrets support
88
+ - **Helm release workflow** — GitHub Actions auto-publishes chart to `gh-pages` on tagged releases
89
+ - **Docker** — Multi-stage build with production-ready image
90
+ - **Supply chain CI** — `npm audit`, CycloneDX SBOM generation, npm provenance attestation
91
+
92
+ ### Testing & Quality
93
+ - **207 tests** across 19 test files (core, server, cli, integration, e2e, fuzz)
94
+ - **Code coverage** — 80% lines, 80% functions, 75% branches enforced in CI
95
+ - **E2E proxy tests** — Real proxy spawns with policy YAML, sends JSON-RPC, verifies block/pass decisions
96
+ - **Fuzz testing** — Payload normalizer and policy engine fuzzing
97
+ - **Red-team corpus** — Labeled poisoned/benign test cases with precision/recall measurement
98
+
99
+ ### Cost Audit & Auto-Detection
100
+ - **CLI cost audit** — `mcp-guardian audit --all` queries proxy databases for real token counts and estimates costs per model
101
+ - **Auto-detection scripts** — `scripts/full-cost-report.cjs` reads Cline model config from `~/.cline/data/globalState.json`, auto-detects pricing, queries proxy DBs for precise MCP tool call costs, and computes LLM conversation cost estimates
102
+ - **Multi-proxy DB isolation** — `MCP_GUARDIAN_DB_PATH` env var allows running multiple proxy instances (e.g., github + filesystem) with separate databases, preventing lock conflicts
103
+ - **Per-call breakdown** — Every `tools/call` through the proxy is logged with request/response tokens, duration, and estimated cost
104
+
105
+ ### Recent Fixes (v2.3.24)
106
+ - **DB lock resolution** — `HistoryDatabase` constructor now checks `MCP_GUARDIAN_DB_PATH` env var as fallback, enabling multiple concurrent proxy instances without lock conflicts
107
+ - **container.ts** — `createContainer()` respects `MCP_GUARDIAN_DB_PATH` for all CLI commands (scan, audit, health, report, proxy)
108
+ - **index.ts** — MCP server startup sets a separate DB path to avoid conflicts with running proxy instances
109
+ - **macOS `/tmp` symlink** — Launch scripts use `/private/tmp` to avoid `proper-lockfile` stat errors on macOS
110
+
111
+ ---
112
+
113
+ ## Installation
114
+
115
+ ```bash
116
+ # Global CLI
117
+ npm install -g @mcp-guardian/server
118
+
119
+ # As an MCP server (for AI assistant integration)
120
+ npx @mcp-guardian/server
121
+
122
+ # From source (monorepo)
123
+ git clone https://github.com/rudraneel93/mcp-guardian.git
124
+ cd mcp-guardian
125
+ pnpm install
126
+ pnpm build
127
+ pnpm start
128
+ ```
129
+
130
+ ---
131
+
132
+ ## CLI Reference
133
+
134
+ ### `mcp-guardian scan`
135
+
136
+ ```bash
137
+ mcp-guardian scan --all # Scan all discoverable MCP configs
138
+ mcp-guardian scan --config ./mcp.json # Scan a specific config
139
+ mcp-guardian scan --fail-on-critical # Exit 1 if any CRITICAL CVE found
140
+ mcp-guardian scan --fail-on-secrets # Exit 1 if any hardcoded secret found
141
+ mcp-guardian scan --threshold-score 60 # Exit 2 if any server scores below 60
142
+ ```
143
+
144
+ Outputs per-server CVE list, auth status, typo-squat risk, secrets found, and composite security score (0–100).
145
+
146
+ ### `mcp-guardian audit`
147
+
148
+ ```bash
149
+ mcp-guardian audit --all # Audit costs for all servers
150
+ mcp-guardian audit --server github # Filter to a specific server
151
+ mcp-guardian audit --threshold-cost 0.01 # Exit 2 if total cost exceeds $0.01
152
+ ```
153
+
154
+ Outputs per-server token usage, estimated cost (USD), and tool-level breakdown.
155
+
156
+ ### `mcp-guardian health`
157
+
158
+ ```bash
159
+ mcp-guardian health --all # Health-check all servers
160
+ mcp-guardian health --fail-on-overload # Exit 1 if any server has tool overload
161
+ mcp-guardian health --threshold-latency 1000 # Exit 2 if latency exceeds 1000ms
162
+ ```
163
+
164
+ Outputs per-server latency, success rate, tool count, and overload warnings.
165
+
166
+ ### `mcp-guardian report`
167
+
168
+ ```bash
169
+ mcp-guardian report --all # Full security-cost-health report
170
+ mcp-guardian report --format markdown # Output as markdown
171
+ mcp-guardian report --format json # Output as JSON
172
+ mcp-guardian report --output guardian-report.md # Write to file
173
+ mcp-guardian report --threshold-score 75 # Exit 2 if overall score below 75
174
+ ```
175
+
176
+ Generates a comprehensive report with overall score (weighted: security 40%, health 30%, cost efficiency 30%).
177
+
178
+ ### `mcp-guardian proxy`
179
+
180
+ ```bash
181
+ mcp-guardian proxy --config ./mcp.json --policy ./default-policy.yaml --blocking-mode block
182
+ mcp-guardian proxy --policy ./policy.yaml --dry-run # Simulate without activating
183
+ mcp-guardian proxy --auth-issuer https://accounts.google.com --auth-audience my-app
184
+ mcp-guardian proxy --auth-required # Fail-closed auth
185
+ ```
186
+
187
+ Starts the transparent proxy. Policy modes: `audit` (passive), `warn` (flag only), `block` (active enforcement). With `--dry-run`, evaluates policy against historical call records without activating the proxy.
188
+
189
+ ---
190
+
191
+ ## Policy Engine
192
+
193
+ Policies are YAML files evaluated against every `tools/call` in real time. The pipeline normalizes payloads (decoding hex/unicode/URL/HTML entity obfuscation), performs semantic shell analysis, then evaluates rules in order.
194
+
195
+ ```yaml
196
+ # default-policy.yaml
197
+ version: '1.0'
198
+ policy:
199
+ mode: block
200
+ default_action: block # fail-closed — blocks anything not explicitly allowed
201
+
202
+ rules:
203
+ - name: block-shell-injection
204
+ action: block
205
+ patterns:
206
+ - curl\s|wget\s
207
+ - rm\s+-rf
208
+ - ;\s*\w
209
+ - '&&|\|\|'
210
+ - \$\{
211
+ - '`[^`]+`'
212
+ - /etc/passwd|/etc/shadow
213
+
214
+ - name: deny-dangerous-tools
215
+ action: block
216
+ tools:
217
+ deny:
218
+ - execute_command
219
+ - bash
220
+ - sh
221
+ - eval
222
+ - exec
223
+ - system
224
+ - spawn
225
+ - fork
226
+ - popen
227
+ - source
228
+
229
+ - name: rate-limit-tool-calls
230
+ action: flag
231
+ maxCallsPerMinute: 120
232
+
233
+ - name: token-budget
234
+ action: flag
235
+ maxTokens: 50000
236
+ ```
237
+
238
+ **Hot-reload:** Edit the YAML file — the policy engine swaps atomically without restarting the proxy.
239
+
240
+ **RBAC example:**
241
+ ```yaml
242
+ - name: admin-only-tool
243
+ action: block
244
+ tools:
245
+ deny: [dangerous_operation]
246
+ rbac:
247
+ scopes: [admin]
248
+ clientIds: [^trusted-agent-]
249
+ ```
250
+
251
+ ---
252
+
253
+ ## MCP Server Integration
254
+
255
+ MCP Guardian runs as a first-class MCP server, exposing security tools to AI assistants:
256
+
257
+ ```json
258
+ {
259
+ "mcpServers": {
260
+ "guardian": {
261
+ "command": "npx",
262
+ "args": ["@mcp-guardian/server"]
263
+ }
264
+ }
265
+ }
266
+ ```
267
+
268
+ **Available tools:**
269
+ - `scan_security` — CVE, auth, typo-squat, and secret scanning
270
+ - `audit_costs` — Token usage and cost estimation
271
+ - `check_health` — Latency, success rate, and tool count
272
+ - `full_report` — Complete security-cost-health report (JSON/markdown/text)
273
+
274
+ **Available resources:**
275
+ - `mcp-guardian://latest-scan` — Most recent security scan results
276
+
277
+ **Available prompts:**
278
+ - `audit-config` — Generates audit instructions for an MCP config
279
+
280
+ ---
281
+
282
+ ## Security Model
283
+
284
+ | Layer | What it catches |
285
+ |-------|----------------|
286
+ | **Payload normalization** | Hex escaping, Unicode escapes, URL encoding, HTML entities, shell obfuscation |
287
+ | **Regex triage** | Cross-tool chaining, privilege escalation, exfiltration URLs, stealth directives, Unicode obfuscation (38 patterns, 8 categories) |
288
+ | **Schema analysis** | Injection in parameter defaults, suspicious parameter names, enum injection |
289
+ | **Shell AST** | Command substitution, pipe chains, redirects, logical chains, 33 dangerous commands, Unicode homoglyphs |
290
+ | **LLM semantic** | Context-aware verdict on tool descriptions — catches adversarial intent regex can't see |
291
+ | **Secret patterns + entropy** | 50+ named patterns + Shannon entropy for base64/hex secrets |
292
+ | **Policy engine** | Tool denylists, regex patterns, rate limits, token budgets, RBAC, default-deny |
293
+ | **Response inspection** | Prompt injection in tool RESPONSES, data exfiltration URLs, base64-encoded payloads |
294
+
295
+ ---
296
+
297
+ ## Production Deployment
298
+
299
+ ### Kubernetes (Helm)
300
+
301
+ ```bash
302
+ helm repo add mcp-guardian https://rudraneel93.github.io/mcp-guardian
303
+ helm install guardian mcp-guardian/mcp-guardian \
304
+ --set persistence.enabled=true \
305
+ --set metrics.enabled=true \
306
+ --set secrets.mode=external \
307
+ --set secrets.existingSecret=mcp-guardian-secrets
308
+ ```
309
+
310
+ The Helm chart includes:
311
+ - **Liveness/readiness probes** (`/healthz`, `/readyz` on port 9090)
312
+ - **Resource limits** (CPU 100m–500m, memory 256Mi–512Mi)
313
+ - **Security context** (non-root, read-only root filesystem, all capabilities dropped)
314
+ - **NetworkPolicy** (intra-namespace proxy traffic, CIDR-restricted dashboard)
315
+ - **ExternalSecrets** support (Vault, SOPS)
316
+
317
+ ### Docker
318
+
319
+ ```bash
320
+ docker run -v $(pwd)/mcp.json:/etc/mcp-guardian/config.json \
321
+ -v $(pwd)/policy.yaml:/etc/mcp-guardian/policy.yaml \
322
+ ghcr.io/rudraneel93/mcp-guardian:latest \
323
+ proxy --config /etc/mcp-guardian/config.json --policy /etc/mcp-guardian/policy.yaml
324
+ ```
325
+
326
+ ---
327
+
328
+ ## Environment Variables
329
+
330
+ | Variable | Default | Description |
331
+ |----------|---------|-------------|
332
+ | `MCP_GUARDIAN_DB_PATH` | `~/.mcp-guardian/history.db` | SQLite database path |
333
+ | `MCP_GUARDIAN_SECRET_ALLOWLIST` | — | Comma-separated safe high-entropy strings |
334
+ | `MCP_GUARDIAN_MAX_PAYLOAD_BYTES` | `10485760` (10 MB) | Max JSON-RPC payload size |
335
+ | `GUARDIAN_SECRET_PROVIDER` | `env` | Secret backend: `env`, `hashicorp-vault`, `aws-secrets-manager` |
336
+ | `GUARDIAN_ALLOW_MODE_OVERRIDE` | `false` | Allow CLI `--blocking-mode` to override policy file mode |
337
+ | `GUARDIAN_STRICT_MODE` | `false` | Exit on Redis-not-configured in multi-replica/K8s |
338
+ | `METRICS_ENABLED` | `false` | Expose Prometheus metrics |
339
+ | `METRICS_PORT` | `9090` | Prometheus metrics port |
340
+ | `DASHBOARD_ENABLED` | `false` | Enable web dashboard |
341
+ | `DASHBOARD_PORT` | `4000` | Dashboard port |
342
+ | `DASHBOARD_METRICS_PUBLIC` | `false` | Allow unauthenticated metrics access |
343
+ | `REDIS_URL` | — | Redis connection for HA rate limiting and sessions |
344
+ | `ALERT_WEBHOOK_URL` | — | Slack or Discord webhook for critical alerts |
345
+ | `ALERT_MIN_SEVERITY` | `warning` | Minimum severity for webhook alerts |
346
+ | `ANTHROPIC_API_KEY` | — | API key for LLM semantic analysis layer |
347
+ | `NVD_API_KEY` | — | NIST NVD API key for CVE lookups |
348
+ | `MCP_PRICING_MODEL` | `gpt-4o` | Default model for cost estimation |
349
+
350
+ ---
351
+
352
+ ## Architecture
353
+
354
+ ```
355
+ ┌──────────────────────────┐
356
+ │ MCP Guardian Proxy │
357
+ │ ┌────────────────────┐ │
358
+ AI Client ──JSON-RPC→│ Policy Engine │──→ Upstream MCP Server
359
+ │ │ (audit/warn/block) │ │ │
360
+ │ └────────┬───────────┘ │ │
361
+ │ │ │ │
362
+ │ ┌────────▼───────────┐ │ │
363
+ │ │ HistoryDatabase │ │ │
364
+ │ │ (better-sqlite3 │ │ │
365
+ │ │ WAL + lockfile) │ │ │
366
+ │ └────────────────────┘ │ │
367
+ └──────────────────────────┘ │
368
+
369
+ ┌─────────────────────────────────────────┘
370
+
371
+ ┌─────────▼──────────┐ ┌──────────────┐ ┌──────────┐
372
+ │ Security Scanner │ │ Cost Auditor │ │ Health │
373
+ │ • CVE (OSV+NVD) │ │ • tiktoken │ │ Monitor │
374
+ │ • Auth probing │ │ • litellm │ │ • JSON- │
375
+ │ • Typo-squat │ │ • per-model │ │ RPC │
376
+ │ • Secret (50+ │ │ pricing │ │ probe │
377
+ │ + entropy) │ │ │ │ • latency│
378
+ │ • Command AST │ └──────────────┘ └──────────┘
379
+ │ • Response inspect │
380
+ └────────────────────┘
381
+ ```
382
+
383
+ ### Data Flow
384
+ 1. AI client sends `tools/call` JSON-RPC to proxy
385
+ 2. Proxy extracts JWT identity → validates (algorithm-pinned, audience/issuer-checked)
386
+ 3. Policy engine evaluates context (tool name, arguments, RBAC) → block/flag/pass
387
+ 4. If passed, forwards to upstream MCP server; if blocked, returns JSON-RPC error
388
+ 5. Records call metadata (tokens, duration, agent ID) to SQLite
389
+ 6. Circuit breaker monitors upstream health; health probes run periodically
390
+ 7. Dashboard receives real-time events via WebSocket; Prometheus scrapes `/metrics`
391
+
392
+ ---
393
+
394
+ ## Development
395
+
396
+ ```bash
397
+ # Clone and install
398
+ git clone https://github.com/rudraneel93/mcp-guardian.git
399
+ cd mcp-guardian
400
+ pnpm install
401
+
402
+ # Build all packages
403
+ pnpm build
404
+
405
+ # Run tests
406
+ pnpm test
407
+
408
+ # Run tests with coverage
409
+ pnpm test:coverage
410
+
411
+ # Type-check
412
+ pnpm typecheck
413
+
414
+ # Run specific test suites
415
+ cd packages/core && npx vitest run
416
+ cd packages/server && npx vitest run
417
+ cd packages/cli && npx vitest run
418
+
419
+ # Run corpus evaluation
420
+ pnpm eval
421
+
422
+ # Development mode (hot-reload)
423
+ pnpm dev
424
+ ```
425
+
426
+ ---
427
+
428
+ ## FAQ
429
+
430
+ ### How is MCP Guardian different from a WAF or API gateway?
431
+
432
+ A WAF inspects HTTP traffic patterns; MCP Guardian operates at the **MCP protocol layer** — it understands `tools/call` semantics, tool names, argument schemas, and agent identities. It can block `execute_command` calls while allowing `read_file`, enforce per-tool rate limits, and validate JWT claims with algorithm pinning. It also scans MCP servers for CVEs, secrets, and typo-squatting — things a WAF cannot do.
433
+
434
+ ### Does the proxy add latency?
435
+
436
+ Typically **5–25ms** for policy evaluation (regex + schema + semantic shell analysis). JWT validation adds another **5–15ms**. The total proxy overhead is under 50ms for most calls. If LLM semantic analysis is enabled, that adds 200–800ms per tool definition scan (not per call — it runs once during manifest verification, not on every intercepted request).
437
+
438
+ ### Can I run it without blocking anything?
439
+
440
+ Yes. Set the policy mode to `audit`:
441
+
442
+ ```yaml
443
+ policy:
444
+ mode: audit
445
+ ```
446
+
447
+ This logs every decision without blocking or flagging. Use it to understand what your agents are calling before enforcing rules. You can also run `mcp-guardian proxy --policy ./policy.yaml --dry-run` to simulate blocking against historical call records.
448
+
449
+ ### What happens if the policy engine crashes?
450
+
451
+ The proxy does **not** pass traffic through if the engine is unavailable — it returns a JSON-RPC error to the client. This is intentional fail-safe behavior. The policy engine is a synchronous, in-process evaluator (no network calls for regex/schema rules), so crashes are extremely unlikely. The LLM semantic layer gracefully degrades to an info-level "skipped" result if the API is unreachable.
452
+
453
+ ### Can I use it with multiple replicas?
454
+
455
+ Yes, with caveats. The proxy works single-instance or multi-replica, but **rate limiting and session state require Redis** (`REDIS_URL`) in multi-replica mode. Without Redis, rate limits are per-pod and session tokens from pod A are invalid on pod B. Set `GUARDIAN_STRICT_MODE=true` to refuse startup if Redis is missing in a multi-replica/K8s environment. For the audit database, use separate DB paths (`MCP_GUARDIAN_DB_PATH`) per instance, or migrate to PostgreSQL (planned for v2.4).
456
+
457
+ ### Does the LLM semantic layer send my data to Anthropic?
458
+
459
+ Only if you configure `ANTHROPIC_API_KEY`. The semantic scanner sends **tool definitions** (name + description + inputSchema) to Claude for security analysis — never the actual tool call arguments or response content. Tool definitions are metadata, not user data. You can disable the semantic layer entirely with `--skip-semantic` or by not setting the API key.
460
+
461
+ ### How do I add my own secret patterns?
462
+
463
+ Add them to the `MCP_GUARDIAN_SECRET_ALLOWLIST` environment variable (comma-separated) to suppress false positives. For custom detection patterns, you can extend `src/scanners/secret-scanner.ts` and rebuild. The entropy threshold (`4.5` bits per character) is also configurable in source.
464
+
465
+ ### Can I use it as a library in my own tool?
466
+
467
+ Yes. The `@mcp-guardian/core` package exports the detection engine directly:
468
+
469
+ ```typescript
470
+ import { scanServer, fetchToolsFromStdio } from '@mcp-guardian/core';
471
+
472
+ const tools = await fetchToolsFromStdio({ command: 'npx', args: ['@my-mcp-server'] });
473
+ const result = await scanServer('my-server', tools, 'stdio');
474
+ // result.status: 'clean' | 'warning' | 'critical'
475
+ // result.tools: per-tool scan results with issues
476
+ ```
477
+
478
+ The root package (`@mcp-guardian/server`) exports the full CLI, proxy, and MCP server.
479
+
480
+ ### What's the default policy if I don't provide one?
481
+
482
+ The `default-policy.yaml` shipped with the package blocks shell injection patterns (curl, wget, rm -rf, command chaining, /etc/passwd), explicitly denies dangerous tools (execute_command, bash, sh, eval, exec, etc.), rate-limits at 120 calls/min, flags tokens over 50K, and applies `default_action: block` — meaning anything not explicitly allowed is blocked. You can override this with your own policy file.
483
+
484
+ ### Does it work with Windows?
485
+
486
+ The TypeScript codebase is platform-agnostic, but the **stdio proxy** spawns child processes and uses Unix signal handling. Windows support via WSL2 is fully functional. Native Windows `cmd.exe` / PowerShell is experimentally supported but not the primary target. The HTTP/SSE proxy transport works on any platform.
487
+
488
+ ### How do I get alerted when something gets blocked?
489
+
490
+ Set `ALERT_WEBHOOK_URL` to a Slack or Discord webhook URL, and optionally `ALERT_MIN_SEVERITY` (default: `warning`). The alerter fires on policy blocks, circuit breaker state changes, and cost threshold breaches. Messages include server name, rule triggered, and timestamp.
491
+
492
+ ### Where is the database stored?
493
+
494
+ `~/.mcp-guardian/history.db` by default. Override with `MCP_GUARDIAN_DB_PATH`. The database uses SQLite with WAL mode, advisory file locking, and automatic purging of records older than 30 days. For tests, pass `':memory:'` to use an in-memory database.
495
+
496
+ ### How do I verify my policy before deploying?
497
+
498
+ Use dry-run mode:
499
+
500
+ ```bash
501
+ mcp-guardian proxy --policy ./new-policy.yaml --dry-run
502
+ ```
503
+
504
+ This evaluates the policy against every call record in your history database and prints a per-server block/pass breakdown without activating the proxy. If the block rate is unexpectedly high or low, adjust rules before deploying.
505
+
506
+ ### How do AI clients authenticate with OAuth?
507
+
508
+ The proxy validates JWT bearer tokens in the `Authorization` header of `tools/call` requests. However, AI clients like Cline and Claude Desktop don't natively generate OAuth tokens. You have three options:
509
+
510
+ 1. **Token injection via MCP config** — Set `env.AUTH_TOKEN` in your MCP server config. The proxy passes it as a Bearer token to upstream servers and validates it if `--auth-required` is set.
511
+ 2. **API gateway pattern** — Place an OAuth proxy (e.g., oauth2-proxy, Pomerium) in front of MCP Guardian. The gateway issues tokens; MCP Guardian validates them.
512
+ 3. **Service account tokens** — Generate a long-lived service account JWT and configure it as `AUTH_TOKEN`. Rotate it manually or via vault.
513
+
514
+ RBAC scopes are defined in your policy YAML under `rules[].rbac.scopes` and mapped to JWT claims (the `scope` or `scopes` claim in the token). DPoP (RFC 9449) requires the client to sign a proof-of-possession JWT per request — this is functional in code but not yet supported by any mainstream AI client.
515
+
516
+ ### How accurate is token counting?
517
+
518
+ For OpenAI models (GPT-4o, o1, o3), counting uses `tiktoken` with `o200k_base` encoding — these are exact (±1%). For other providers:
519
+
520
+ | Provider | Method | Typical accuracy |
521
+ |----------|--------|-----------------|
522
+ | Anthropic (Claude) | Char ratio (0.30) | ±5–15% |
523
+ | Google (Gemini) | Char ratio (0.22) | ±10–25% |
524
+ | DeepSeek | Char ratio (0.27) | ±8–20% |
525
+ | Mistral | Char ratio (0.25) | ±8–20% |
526
+ | Meta (Llama) | Char ratio (0.25) | ±8–20% |
527
+
528
+ Results are flagged with `isEstimate: true` when char-ratio counting is used. Treat non-OpenAI cost figures as estimates, not accounting-grade numbers.
529
+
530
+ ### How does CVE scoring work? Why aren't 100 CVEs penalized more?
531
+
532
+ MCP Guardian uses **logarithmic compound scoring**: each additional CVE in the same severity tier adds diminishing penalty. 1 critical CVE = −30, 2 = −60, 5 = −100, 10 = −130, 100 = −230. This prevents a single vulnerable package from zeroing the entire score while still scaling penalty with volume. CVE recency and EPSS (Exploit Prediction Scoring System) integration is planned for v2.4.
533
+
534
+ ### How do I set up mTLS?
535
+
536
+ mTLS requires:
537
+
538
+ 1. A Certificate Authority (CA) — you can use your existing PKI or create one with `openssl`
539
+ 2. A client certificate for each upstream MCP server signed by that CA
540
+ 3. The CA certificate configured in MCP Guardian via environment variables
541
+
542
+ Set `MCP_TLS_CA_PATH=/path/to/ca.pem` and `MCP_TLS_CLIENT_CERT_PATH=/path/to/client.crt`, `MCP_TLS_CLIENT_KEY_PATH=/path/to/client.key` per server in your MCP config's `env` section. A `mcp-guardian certs init` helper command is planned for v2.4 to automate this.
543
+
544
+ ### What happens if my policy YAML is malformed?
545
+
546
+ The proxy **fails closed** — malformed YAML causes a startup error and the proxy refuses to start. It does not silently fall back to the last good policy or default to audit mode. Use `--dry-run` to validate new policies before deploying:
547
+ ```bash
548
+ mcp-guardian proxy --policy ./new-policy.yaml --dry-run
549
+ ```
550
+
551
+ ### How do I contribute?
552
+
553
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines. The monorepo uses pnpm workspaces with turbo for build orchestration. Run `pnpm install && pnpm build && pnpm test` to verify your setup. All PRs must pass the 80% coverage threshold and the red-team corpus evaluation (F1 ≥ 85%).
554
+
555
+ ### Is it production-ready?
556
+
557
+ MCP Guardian is **production-grade for controlled environments** (single-instance or Redis-backed multi-replica with `GUARDIAN_STRICT_MODE`). The database layer uses better-sqlite3 with WAL mode and advisory file locking — crash-safe and non-blocking. It handles the core use case — active policy enforcement with audit trails — reliably. For high-trust enterprise deployments, a third-party security audit is planned for v2.5. See [SECURITY.md](SECURITY.md) for details on our security posture.
558
+
559
+ ---
560
+
561
+ ## Roadmap
562
+
563
+ ### v2.4
564
+ - PostgreSQL migration option for multi-replica deployments
565
+ - OPA/Rego policy integration
566
+ - Multi-user proxy (separate DB schemas per team)
567
+
568
+ ### v2.5
569
+ - Third-party security audit (OAuth/JWT/RBAC/DPoP)
570
+ - Adversarial fuzzing CI pipeline
571
+ - Hosted SaaS pilot
572
+
573
+ ### v3.0
574
+ - Plugin architecture for custom scanners
575
+ - gRPC transport support
576
+ - Real-time cost dashboards with budget alerts
577
+
578
+ ---
579
+
580
+ ## License
581
+
582
+ MIT — see [LICENSE](LICENSE).
583
+
584
+ ---
585
+
586
+ **Built with TypeScript, better-sqlite3, pino, prom-client, jose, shell-quote, tiktoken, commander, chalk, and lru-cache.**
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};