Skip to main content

Zero-Trust Security Layer for AI Agentic Workflows via the Model Context Protocol

Project description

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:

  1. Who is asking? (identity check)
  2. Are they allowed? (permission check)
  3. Is the request safe? (scans for dangerous commands)
  4. 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-aegis command 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

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcp_aegis-0.2.0.tar.gz (42.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_aegis-0.2.0-py3-none-any.whl (32.6 kB view details)

Uploaded Python 3

File details

Details for the file mcp_aegis-0.2.0.tar.gz.

File metadata

  • Download URL: mcp_aegis-0.2.0.tar.gz
  • Upload date:
  • Size: 42.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mcp_aegis-0.2.0.tar.gz
Algorithm Hash digest
SHA256 c4a26b152dd51544f4385cec82f63771de0eb0a5f338ad7d1a1a4a53dbc99d27
MD5 45567e5ef626245983991ad9ab29e607
BLAKE2b-256 8a54a9d3b8e8c12c76c94f74dca67c9ae58d2abbe49b9672acab566a83d2aa71

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_aegis-0.2.0.tar.gz:

Publisher: publish.yml on kalyanganala28/MCP-guardian

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mcp_aegis-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: mcp_aegis-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 32.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mcp_aegis-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 158e37727622e09b89d14bf3e44707cd63d7f43bb1c8752a5e189ae0948e18c3
MD5 ce3a14615ded3d6fbeb306cc116a67b5
BLAKE2b-256 de50fd5c495cb0a17cb3d1f4ef0112bdc91440e47ea865dcbf5210a7835a629d

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_aegis-0.2.0-py3-none-any.whl:

Publisher: publish.yml on kalyanganala28/MCP-guardian

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page