MCPGuard 🛡️
Runtime security proxy for the Model Context Protocol (MCP) and Agent-to-Agent (A2A) protocols.
MCPGuard sits between MCP clients and servers, inspecting every JSON-RPC message in real time to detect and block security threats. Supports HTTP SSE, stdio, and WebSocket transport modes.
What makes MCPGuard unique
| Capability | MCPGuard | Raw proxy | Custom middleware |
|---|---|---|---|
| Prompt injection detection | ✅ 14 regex patterns | ❌ | Manual |
| Tool poisoning detection | ✅ flags suspicious tools/list |
❌ | ❌ |
| SSRF protection | ✅ redirect blocking + scheme validation | ❌ | Manual |
| Rate limiting | ✅ per-method + per-IP | ❌ | ❌ |
| Live dashboard | ✅ HTMX at /_mcpguard/ |
❌ | ❌ |
| Prometheus metrics | ✅ /metrics |
❌ | ❌ |
| All 3 transports | ✅ HTTP SSE + stdio + WebSocket | Partial | Manual |
| Hot-reload config | ✅ | ❌ | ❌ |
| Circuit breaker | ✅ auto-recovers | ❌ | ❌ |
Features
| Category | Feature | Description |
|---|---|---|
| Detection | Prompt Injection | Scans tools/call arguments for instruction override patterns (14 regexes) |
| Tool Poisoning | Flags suspicious tool definitions in tools/list responses |
|
| Resource Scanning | Detects sensitive URI access (/etc/passwd, file:///, metadata endpoints) |
|
| Suspicious Prompts | Flags prompt names like debug, admin, shell |
|
| Anomaly Detection | Burst, volume, and dominance-based anomaly alerts | |
| Control | Rate Limiting | Per-method + per-IP rate limits with configurable windows |
| Allow/Deny Lists | Control which tools and methods are permitted | |
| Auth Middleware | API key auth with timing-attack resistant comparison (hmac.compare_digest) |
|
| Circuit Breaker | Auto-opens after 5 upstream failures, recovers after 30s | |
| Body Size Limit | Rejects requests >10MB (413) to prevent DoS | |
| Transport | HTTP SSE | Proxies MCP Streamable HTTP (rewrites endpoint URLs) |
| Stdio | Wraps local MCP server subprocesses with command validation | |
| WebSocket | WebSocket transport support for MCP servers | |
| Observability | Live Dashboard | HTMX-powered dashboard at /_mcpguard/ with JS event filtering |
| Prometheus Metrics | /metrics with counters, gauges (uptime, active SSE) |
|
| Audit Logging | All events logged to daily JSONL files | |
| Security | SSRF Protection | follow_redirects=False, target URL scheme validation |
| Subprocess Validation | Command existence + executable check before spawn | |
| Rate Limit Headers | Retry-After, X-RateLimit-* on 429 responses |
|
| Platform | TLS | HTTPS support via --tls-cert / --tls-key |
| Config Validation | 10 validation rules on startup (port range, TLS paths, conflicts) | |
| Config File | YAML/JSON configuration via --config with auto-split for string commands |
|
| Hot-Reload | Async config watcher (no blocking threads) | |
| Tool Cache | tools/list caching with configurable TTL |
|
| Graceful Shutdown | 10s timeout for clean connection drain |
Installation
pip install mcpguard-proxy
From source:
git clone https://github.com/Carlos-Projects/mcpguard.git
cd mcpguard
pip install -e ".[dev]"
Quick Start
# HTTP mode (intercept an upstream MCP server)
mcpguard proxy --target http://localhost:8000 --port 8080
# Stdio mode (wrap a local MCP server process)
mcpguard proxy --mode stdio --cmd python3 --cmd /path/to/server.py --port 8080
# With auth, TLS, and circuit breaker
mcpguard proxy --target http://localhost:8000 --port 8443 \
--api-key my-secret --tls-cert cert.pem --tls-key key.pem
# With config file (YAML/JSON)
mcpguard proxy --config mcpguard.yaml --hot-reload
Clients connect to http://localhost:8080 instead of the server directly. Dashboard at /_mcpguard/.
CLI Reference
mcpguard proxy [OPTIONS]
| Option | Default | Description |
|---|---|---|
--target, -t |
http://localhost:8000 |
Upstream MCP server URL |
--host, -h |
127.0.0.1 |
Proxy listen address |
--port, -p |
8080 |
Proxy listen port |
--mode, -m |
http |
Transport: http or stdio |
--cmd, -c |
[] |
Stdio command (repeatable) |
--sse-path |
/sse |
SSE endpoint path |
--messages-path |
/messages/ |
Messages endpoint path |
--log-dir, -l |
./mcpguard_logs |
Log directory |
--config, -C |
— | Config file (YAML/JSON) |
--allow, -a |
[] |
Allowlisted tools (repeatable) |
--deny, -d |
[] |
Denylisted tools (repeatable) |
--rate-limit, -r |
100 |
Max requests per time window |
--rate-window, -w |
60 |
Rate limit window in seconds |
--api-key, -k |
— | API key for proxy auth |
--tls-cert |
— | TLS certificate file |
--tls-key |
— | TLS key file |
--hot-reload |
— | Watch config file for changes |
--request-timeout |
30.0 |
Upstream request timeout in seconds |
mcpguard analyze [LOG_DIR]
Analyze logged events with optional --severity, --type, --limit filters.
Architecture
┌──────────────────┐
┌───▶│ MCPGuard Proxy │───▶ MCP Server (HTTP/SSE)
│ │ (port 8080) │
MCP Client (Host)──┤ └──────────────────┘ ┌──────────────────┐
│ │ │ MCP Server │
│ ├──────────────────▶│ (stdio process) │
│ │ └──────────────────┘
│ ┌──────────────────┐
└───▶│ /_mcpguard/ │
│ Dashboard │
└──────────────────┘
│
┌──────────┴──────────┐
│ /metrics │
│ /health │
│ /health/ready │
└─────────────────────┘
Detection Plugins
| Plugin | Trigger | Action |
|---|---|---|
| Prompt Injection | tools/call with instruction override keywords |
Block (403) |
| Tool Poisoning | tools/list with suspicious tool names |
Block if block_on_poisoning: true |
| Resource Scanner | resources/read with sensitive URIs |
Log |
| Suspicious Prompts | prompts/get with admin-like names |
Log |
| Rate Limiter | Per-method + per-IP threshold exceeded | Block (429) with Retry-After |
| Anomaly Detector | Burst, dominant-method, high-volume patterns | Log |
| Circuit Breaker | 5 consecutive upstream failures | Block (503) for 30s recovery |
Config File Example
mode: http
target_url: http://localhost:8000
listen_host: 127.0.0.1
listen_port: 8080
rate_limit: 100
rate_window: 60
block_on_injection: true
block_on_poisoning: true
max_sse_connections: 50
request_timeout: 30.0
api_key: your-secret-key
allowlisted_tools:
- get_weather
- search
denylisted_tools:
- execute_bash
- delete_files
tls_cert_path: /path/to/cert.pem
tls_key_path: /path/to/key.pem
Testing
pip install -e ".[dev]"
python -m pytest tests/ -v --cov=mcpguard --cov-report=term-missing
Ecosystem
MCPGuard is a runtime guard — it complements:
- Cisco MCP Scanner — static analysis of MCP servers
- MCPwn — active red teaming framework for MCP
Changelog
v0.4.0 (2025-05-25)
- Security: Timing-attack resistant auth, body size limit (10MB), subprocess command validation, SSRF protection
- Reliability: Circuit breaker (5 failures/30s recovery), async config watcher, graceful shutdown (10s)
- Features:
/health/readyendpoint, rate limit headers, configurable timeout, WebSocket transport - Dashboard: JS event filtering, CDN fallback, uptime/active connections metrics
- Config: Validation on startup, auto-split string commands,
request_timeoutoption - Tests: 52 → 104 tests, coverage ~85%, 7 new test files, CI coverage reporting
- Infra:
.dockerignore, stdio integration tests in CI, codecov integration
v0.3.0 (2025-05-24)
- HTTP SSE + stdio transport modes
- Prompt injection, tool poisoning, resource scanning, anomaly detection
- Live HTMX dashboard, Prometheus metrics, JSONL audit logging
- Auth middleware, TLS support, rate limiting, allow/deny lists
- Docker support, CI/CD, PyPI publishing
License
MIT
Metadata
Release files for mcpguard-proxy 0.4.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| mcpguard_proxy-0.4.1.tar.gz | 50.5 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mcpguard_proxy-0.4.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 97.1 kB
Release files / mcpguard_proxy-0.4.1.tar.gz
| Download URL | mcpguard_proxy-0.4.1.tar.gz |
|---|---|
| Size | 50.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
003abda57ade76809e930f7cbfa01006060d3ff4da1dd21166da48f928b469c7
|
|
BLAKE2b-256 checksum How to use checksums |
acbd8e8b8f8ef2b9a4d8e020215703d6c918d30b0ca05344244e5c1ae384bd66
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Release files / mcpguard_proxy-0.4.1-py3-none-any.whl
| Download URL | mcpguard_proxy-0.4.1-py3-none-any.whl |
|---|---|
| Size | 46.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c43a94b253b2c548ee56edf5703be345e126e6efa30b468af8a71303923b541a
|
|
BLAKE2b-256 checksum How to use checksums |
3db2c84d39757fd988d89f0d386106a29fe585a644dd06f5dcae4ad2e2d4f4ee
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Security for mcpguard-proxy 0.4.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.