MCP-Aegis
The Zero-Trust Security Layer for AI Agentic Workflows.
MCP-Aegis is an open-source, high-performance security middleware library that acts as a firewall for AI agents. AI assistants like Claude and Cursor are no longer just answering questions. They now directly control your computer — reading files, running commands, querying databases — through something called MCP (Model Context Protocol).
THE PROBLEM
That remote control has no lock on it.
Right now, if you give an AI agent access to your database, it gets FULL access. It can read your data, delete your data, or drop entire tables. There is no way to say "you can read, but you cannot delete."
Worse, a bad actor can trick the AI (called prompt injection) into running dangerous commands like deleting files or sending your passwords to an external server. The AI doesn't know it's being tricked.
And nobody is keeping a record of what the AI did, when, or why.
THE SOLUTION
MCP-Aegis is a security guard that sits between the AI and your tools.
AI Agent → Guardian (checks everything) → Your Tools
Before any action reaches your tools, Guardian asks four questions:
- Who is asking? (identity check)
- Are they allowed? (permission check)
- Is the request safe? (scans for dangerous commands)
- Are they asking too much? (rate limiting)
If any answer is "no," the request is blocked. It never reaches your tools.
Features
- OAuth 2.1 / JWT Authentication — RS256 validation with scope-based access control and RFC 8707 Resource Indicators.
- RBAC Policy Engine — YAML-driven policies with wildcard permissions and principal-to-tool mapping.
- Argument Sanitization — Blocks shell injection, path traversal, and other malicious patterns before they reach tool servers.
- Stateful Rate Limiting — Token Bucket algorithm with pluggable backends (in-memory, Redis).
- Transport Agnostic — Supports both SSE and Stdio transports via a clean abstraction.
- CLI Security Shim — Drop-in
mcp-aegiscommand wraps any MCP server with zero code changes. - Structured Logging — Full traceability with JSON-RPC request ID correlation.
- Dependency Injection — Swap auth providers, policy engines, and rate limiters without touching proxy code.
- Production Hardened — Payload size limits, concurrency caps, nesting depth guards, bounded buffers, and Redis failure resilience prevent crashes under any load.
Installation
pip install mcp-aegis
# With Redis support for distributed rate limiting
pip install mcp-aegis[redis]
From source
git clone https://github.com/kalyanganala28/MCP-guardian.git
cd MCP-guardian
pip install -e ".[dev]"
Quick Start
Option 1: CLI (Stdio Shim) — Recommended
Wrap any MCP server with Guardian in one command. No code changes needed:
mcp-aegis \
--target "npx @modelcontextprotocol/server-filesystem /tmp" \
--policy policies.yaml \
--principal developer \
--roles dev \
--log-level INFO
Use it in your Claude Desktop / Cursor MCP config:
{
"mcpServers": {
"guarded-filesystem": {
"command": "mcp-aegis",
"args": [
"--target", "npx @modelcontextprotocol/server-filesystem /tmp",
"--policy", "/path/to/policies.yaml",
"--principal", "developer",
"--roles", "dev"
]
}
}
}
Option 2: Python Library (HTTP Proxy)
from mcp_guardian import GuardianProxy, JWTAuthenticator, YAMLPolicyEngine
authenticator = JWTAuthenticator(jwks_uri="https://auth.example.com/.well-known/jwks.json")
policy_engine = YAMLPolicyEngine.from_file("policies.yaml")
proxy = GuardianProxy(authenticator=authenticator, policy_engine=policy_engine)
proxy.serve(host="0.0.0.0", port=8443)
Option 3: Programmatic Stdio Bridge
import asyncio
from mcp_guardian import StdioBridge, YAMLPolicyEngine, LocalAuthenticator
from mcp_guardian.sanitizer import Sanitizer
auth = LocalAuthenticator(principal="my-agent", roles=frozenset({"dev"}))
policy = YAMLPolicyEngine.from_file("policies.yaml")
bridge = StdioBridge(
["npx", "@modelcontextprotocol/server-filesystem", "/tmp"],
claims=auth._claims,
policy_engine=policy,
sanitizer=Sanitizer(),
)
asyncio.run(bridge.run())
CLI Reference
usage: mcp-aegis [-h] --target TARGET --policy POLICY [--mode {stdio}]
[--log-level {DEBUG,INFO,WARNING,ERROR}]
[--principal PRINCIPAL] [--roles ROLES]
[--rate-limit N] [--max-line-size BYTES]
[--max-arg-size BYTES] [--max-depth N] [--version]
Required:
--target TARGET Command to launch the downstream MCP server
--policy POLICY Path to the YAML policy file
Optional:
--principal PRINCIPAL Local identity for policy evaluation (default: local-user)
--roles ROLES Comma-separated roles (e.g. 'admin,dev')
--rate-limit N Max tool calls per minute
--log-level LEVEL DEBUG, INFO, WARNING, ERROR (default: INFO)
--mode {stdio} Transport mode (default: stdio)
--max-line-size BYTES Max bytes per stdio JSON-RPC line (default: 10 MB)
--max-arg-size BYTES Max bytes per individual argument value (default: 1 MB)
--max-depth N Max nesting depth for argument structures (default: 32)
Policy Configuration
Define access control in policies.yaml:
version: "1"
defaults:
effect: deny # deny-by-default (zero trust)
principals:
admin:
roles: [admin]
tools:
- pattern: "*" # wildcard: access to everything
actions: [read, execute]
developer:
roles: [dev]
tools:
- pattern: "db:read" # exact match
actions: [execute]
- pattern: "fs:*" # namespace wildcard
actions: [read]
- pattern: "git:*"
actions: [read, execute]
readonly:
roles: [observer]
tools:
- pattern: "*"
actions: [read] # can read anything, execute nothing
Verification
Run the built-in verification script to confirm everything works:
python verify.py
Expected output:
1. Import Check
PASS All modules import successfully
2. Policy Engine
PASS Load policies.yaml
PASS Admin wildcard access allowed
PASS Junior denied db:write
3. Argument Sanitizer
PASS Clean SQL passes
PASS Shell injection blocked
PASS Path traversal blocked
PASS Command substitution blocked
...
============================================================
ALL 30 CHECKS PASSED
MCP-Aegis v0.1.1 is fully operational.
============================================================
Run the test suite:
pytest # quick run
pytest --cov=mcp_guardian --cov-branch # with coverage
pytest --cov=mcp_guardian --cov-report=html # HTML report
Production Hardening
MCP-Aegis is designed to never crash, regardless of input size or load. Every data path is bounded:
| Protection | Default | Industry Reference | Configurable via |
|---|---|---|---|
| HTTP body size | 100 MB | gRPC 4 MB, Django 2.5 MB | max_http_body_bytes / GUARDIAN_MAX_HTTP_BODY_BYTES |
| Stdio line size | 100 MB | asyncio 64 KB | max_stdio_line_bytes / GUARDIAN_MAX_STDIO_LINE_BYTES |
| Individual argument | 50 MB | — | max_argument_bytes / GUARDIAN_MAX_ARGUMENT_BYTES |
| Total arguments | 100 MB | — | max_arguments_total_bytes / GUARDIAN_MAX_ARGUMENTS_TOTAL_BYTES |
| Nesting depth | 128 levels | JSON parsers ~100 | max_nesting_depth / GUARDIAN_MAX_NESTING_DEPTH |
| Regex scan cap | 1 MB | — | sanitizer_max_scan_bytes / GUARDIAN_SANITIZER_MAX_SCAN_BYTES |
| SSE stream buffer | 100 MB | — | max_sse_buffer_bytes / GUARDIAN_MAX_SSE_BUFFER_BYTES |
| Policy file | 10 MB | — | max_policy_file_bytes / GUARDIAN_MAX_POLICY_FILE_BYTES |
| Concurrent requests | 10,000 | Uvicorn backlog 2048 | max_concurrent_requests / GUARDIAN_MAX_CONCURRENT_REQUESTS |
| Transport timeout | 30s | httpx 5s, K8s probe 30s | transport_timeout / GUARDIAN_TRANSPORT_TIMEOUT |
| Redis op timeout | 5s | redis-py None (unsafe) | redis_operation_timeout / GUARDIAN_REDIS_OPERATION_TIMEOUT |
| Redis failure mode | fail-closed | — | redis_fail_open / GUARDIAN_REDIS_FAIL_OPEN |
| Shutdown grace | 30s | K8s SIGTERM grace 30s | target_shutdown_timeout / GUARDIAN_TARGET_SHUTDOWN_TIMEOUT |
Programmatic configuration
from mcp_guardian import configure_limits
configure_limits(
max_http_body_bytes=50 * 1024 * 1024, # 50 MB
max_concurrent_requests=5000,
redis_fail_open=True,
)
Environment variable configuration
export GUARDIAN_MAX_HTTP_BODY_BYTES=52428800
export GUARDIAN_MAX_CONCURRENT_REQUESTS=5000
export GUARDIAN_REDIS_FAIL_OPEN=true
Project Structure
src/mcp_guardian/
├── __init__.py # Public API
├── __main__.py # python -m mcp_guardian
├── cli.py # argparse CLI entry point
├── bridge.py # Stdio message pump (security shim)
├── errors.py # MCPGuardianError hierarchy
├── limits.py # GuardianLimits (production safety thresholds)
├── sanitizer.py # Argument sanitization
├── logging.py # Structured logging setup
├── core/
│ ├── proxy.py # GuardianProxy (HTTP mode) + middleware
│ └── transport.py # Transport ABC + SSE/Stdio
├── auth/
│ ├── jwt.py # JWTAuthenticator (OAuth 2.1)
│ └── local.py # LocalAuthenticator (stdio mode)
├── policy/
│ └── engine.py # YAMLPolicyEngine (RBAC)
└── rate_limit/
├── limiter.py # Token Bucket rate limiter
└── backends.py # InMemory + Redis backends
Development
git clone https://github.com/kalyanganala28/MCP-guardian.git
cd MCP-guardian
pdm install -G dev # or: pip install -e ".[dev]"
pdm run pytest # tests
pdm run mypy src/ # type checking
pdm run ruff check src/ # linting
Contributing
See CONTRIBUTING.md for development setup, coding standards, and PR process.
License
Metadata
Release files for mcp-aegis 0.2.0
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 | |
|---|---|---|---|---|
| mcp_aegis-0.2.0.tar.gz | 42.9 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mcp_aegis-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 75.5 kB
Release files / mcp_aegis-0.2.0.tar.gz
| Download URL | mcp_aegis-0.2.0.tar.gz |
|---|---|
| Size | 42.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c4a26b152dd51544f4385cec82f63771de0eb0a5f338ad7d1a1a4a53dbc99d27
|
|
BLAKE2b-256 checksum How to use checksums |
8a54a9d3b8e8c12c76c94f74dca67c9ae58d2abbe49b9672acab566a83d2aa71
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 12, 2026.
Transparency logRelease files / mcp_aegis-0.2.0-py3-none-any.whl
| Download URL | mcp_aegis-0.2.0-py3-none-any.whl |
|---|---|
| Size | 32.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
158e37727622e09b89d14bf3e44707cd63d7f43bb1c8752a5e189ae0948e18c3
|
|
BLAKE2b-256 checksum How to use checksums |
de50fd5c495cb0a17cb3d1f4ef0112bdc91440e47ea865dcbf5210a7835a629d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 12, 2026.
Transparency logSecurity for mcp-aegis 0.2.0
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for mcp_aegis-0.2.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 12, 2026.
Transparency logA 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.