Skip to main content

Security toolkit for FastAPI-based MCP servers โ€” pre-flight audit + runtime prompt-injection guardrail.

Project description

๐Ÿ›ก๏ธ MCPRampart

Security for the FastAPI apps you expose to LLMs via MCP.
Pre-flight audit. Runtime prompt-injection guardrail. One package.

PyPI License Stars


from fastapi import FastAPI
from mcp_rampart import MCPRampart

app = FastAPI()
# ... your existing routes ...

rampart = MCPRampart(app)                    # 1. Speak MCP.
report = rampart.audit()                    # 2. Audit what you'd expose.
if report.has_blockers():
    report.print_text(); raise SystemExit(1)

rampart.enable_guardrails(policy="block")   # 3. Block prompt-injection at runtime.

Why this exists

MCP has gone from "interesting experiment" to 97M+ installs per month in 2026. Anthropic, OpenAI, Google, Cursor, Codex, Microsoft โ€” every major agent ships MCP support, and the Linux Foundation now stewards the protocol. The dev tooling around it has scaled fast.

The security tooling around it has not.

Every FastAPI app shipped as an MCP server is one careless include_paths=["/*"] away from handing a language model:

  • its admin endpoints,
  • its auth/OAuth flows,
  • the columns of its user table,
  • the verbs that mutate data.

And once it's live, every single tools/call request is untrusted input โ€” written by a model that may have been told to "ignore previous instructions" two turns ago.

MCPRampart is two things in one package, designed to make those two failure modes hard to ignore:

  1. A pre-flight audit() that walks every route you'd expose and refuses to start the server when something looks dangerous.
  2. A runtime Guardrail that scans the arguments of every tools/call against a curated prompt-injection pattern catalogue and blocks the call before your handler runs.

You don't have to integrate three libraries, write your own regex layer, or stand up a separate proxy. It's pip install mcp-rampart and three lines of code.


Quick start

pip install mcp-rampart
from fastapi import FastAPI
from mcp_rampart import MCPRampart

app = FastAPI(title="My App")

@app.get("/api/users/{user_id}")
async def get_user(user_id: int):
    """Get a user by their ID."""
    return {"id": user_id, "name": "Alice"}

rampart = MCPRampart(app)                    # auto-discovers routes, mounts /mcp
print(rampart.summary())

# Pre-flight audit โ€” refuses to start the server on CRITICAL findings
report = rampart.audit()
report.print_text()
if report.has_blockers():
    raise SystemExit(1)

# Runtime guardrail โ€” every incoming tools/call is scanned
rampart.enable_guardrails(policy="block")

Your app now exposes:

  • GET /mcp โ€” server info and tool listing
  • POST /mcp โ€” MCP JSON-RPC endpoint (Streamable HTTP transport)

Any MCP client (Claude Desktop, ChatGPT, Gemini, Cursor, Codex) can connect.


The pre-flight audit, in detail

rampart.audit() walks every exposed tool and runs 7 checks. Each finding gets a severity tag, a suggestion, and a category code you can match in CI.

Severity Check Triggers whenโ€ฆ
๐Ÿ”ด CRITICAL EXPOSED_AUTH route path matches /auth/, /login, /token, /oauth, โ€ฆ
๐Ÿ”ด CRITICAL EXPOSED_ADMIN route path matches /admin/, /internal/, /debug/, โ€ฆ
๐ŸŸ  HIGH MISSING_DOCSTRING no description โ†’ LLM will guess and call the wrong tool
๐ŸŸ  HIGH SENSITIVE_PARAM_NAME parameter name contains password, token, api_key, โ€ฆ
๐ŸŸ  HIGH PII_IN_RESPONSE response schema declares fields like email, phone, ssn, โ€ฆ
๐ŸŸก MEDIUM DESTRUCTIVE_METHOD DELETE / PUT / PATCH exposed without explicit consent flow
๐Ÿ”ต LOW UNTYPED_PARAMETER 3+ parameters falling back to str โ€” LLMs may send malformed inputs

Sample output on a deliberately bad app:

๐Ÿ›ก๏ธ  MCPRampart audit report
   13 tools from 13 routes
   ๐Ÿ”ด 2 critical ยท ๐ŸŸ  4 high ยท ๐ŸŸก 3 medium ยท ๐Ÿ”ต 1 low

   ๐Ÿ”ด [CRITICAL] POST   /api/auth/login           Authentication endpoint exposed to LLM clients
      โ†ณ Add '/api/auth/login' to exclude_paths
   ๐Ÿ”ด [CRITICAL] DELETE /api/admin/users/{user_id}  Admin / internal endpoint exposed to LLM clients
      โ†ณ Exclude this route from MCP exposure
   ๐ŸŸ  [HIGH]     GET    /api/users/me              Response may leak PII fields: email, phone, address
   โ€ฆ

Use it in CI:

- run: python -c "from myapp import rampart; r = rampart.audit(); r.print_text(); exit(1 if r.has_blockers() else 0)"

The runtime guardrail, in detail

The audit happens once, at startup. The guardrail runs forever โ€” on every tools/call request.

It scans the call's arguments (recursively, in dicts and lists) against a curated catalogue of prompt-injection patterns:

Confidence What gets caught
๐Ÿ”ด HIGH ignore previous instructions, you are now โ€ฆ, developer/admin/jailbreak mode, chat-template control tokens (<|im_start|>), [[system]] markers, SYSTEM: do โ€ฆ
๐ŸŸ  MEDIUM system prompt, act as โ€ฆ, pretend to be โ€ฆ, "reveal your instructions", "repeat everything above", "begin new session as"
๐Ÿ”ต LOW exfiltration verbs (send your tokens to โ€ฆ), <script> payloads, embedded curl/wget https://โ€ฆ, base64 obfuscation

Aggregate decision:

  • any HIGH match โ†’ BLOCK
  • 2+ MEDIUM matches โ†’ BLOCK
  • 1 MEDIUM or LOW โ†’ WARN (allowed, logged)
  • nothing โ†’ ALLOW

Enable in one line

rampart.enable_guardrails(policy="block")     # default
rampart.enable_guardrails(policy="alert")     # let through, log loudly, call on_alert
rampart.enable_guardrails(policy="log")       # observability / shadow mode

Plug your alerting in

def to_security_team(decision):
    slack.post(f"โš ๏ธ MCPRampart blocked {decision.tool_name}: {decision.reason}")

rampart.enable_guardrails(policy="block", on_block=to_security_team)

Inspect what happened

rampart.guardrail.stats()
# โ†’ {"total": 1284, "blocked": 7, "alerted": 23, "clean": 1254}

for entry in rampart.guardrail.recent(10):
    print(entry.tool_name, entry.decision.allowed, entry.decision.reason)

What an MCP client sees when blocked:

{
  "isError": true,
  "content": [{
    "type": "text",
    "text": "๐Ÿ›ก๏ธ Blocked by MCPRampart runtime guardrail.\nReason: Prompt-injection detected (HIGH:1)\nTop matches: high instruction_override @ arguments.query"
  }]
}

๐ŸŽฏ Real-world findings โ€” see case-studies/

We ran rampart.audit() against the official examples of tadata-org/fastapi_mcp (the most popular FastAPIโ†’MCP library, 11.9k โญ):

Example ๐Ÿ”ด Crit ๐ŸŸ  High ๐ŸŸก Med ๐Ÿ”ต Low Verdict
01_basic_usage_example 0 0 2 0 โœ…
02_full_schema_description 0 0 2 0 โœ…
04_separate_server 0 0 2 0 โœ…
08_auth_token_passthrough 0 1 2 0 โœ…
09_auth_example_auth0 3 6 0 1 โŒ BLOCK

Headline: the official Auth0 example exposes /oauth/authorize, /oauth/register, and /.well-known/oauth-authorization-server to LLM clients. MCPRampart catches all three and refuses to start the server. Full breakdown in case-studies/01-fastapi-mcp-examples.md.


Where MCPRampart sits in the MCP-security landscape

MCP security tools have started shipping. Here's an honest map:

Project โญ Shape What it does
mcp_rampart (this) new Embedded library (pip install into your FastAPI app) Pre-flight audit of your own routes + runtime injection guardrail on every tools/call
luckyPipewrench/pipelock 583 Client-side firewall Agent egress control, DLP, sits between agent and MCP server
apache/casbin-gateway 559 HTTP gateway Casbin policy enforcement in front of MCP traffic
apisec-inc/mcp-audit 149 Config scanner Scans mcp.json for exposed secrets / unsafe servers installed on your machine
hyprmcp/mcp-gateway 92 OAuth proxy DCR + analytics in front of MCP servers
ModelContextProtocol-Security/mcpserver-audit 16 CLI Audit MCP servers before you install them

Where MCPRampart is the only one โœ…

mcp_rampart pipelock casbin-gateway apisec mcp-audit hyprmcp
Runs inside your FastAPI app (no extra process) โœ… โŒ โŒ โŒ โŒ
Audits the routes you are about to expose (not someone else's) โœ… โŒ โŒ โŒ โŒ
Refuses to start the server on CRITICAL findings โœ… โŒ โŒ โŒ โŒ
Prompt-injection detection on every tools/call โœ… partial โŒ โŒ โŒ
Pluggable on_block / on_alert callbacks โœ… โŒ โŒ โŒ โŒ
Three-policy model (block / alert / log) โœ… โŒ โŒ โŒ โŒ

The gateway / firewall / config-scanner projects each solve a real problem for the agent operator or the MCP user. MCPRampart solves the dual problem for the MCP server author: did you accidentally expose something dangerous, and if so, are you willing to ship anyway?

If you're building an MCP server (not consuming someone else's), this is the layer you don't currently have.


How it works

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                  Your FastAPI app                    โ”‚
โ”‚                                                     โ”‚
โ”‚   @app.get("/api/recipes")     โ† Existing routes    โ”‚
โ”‚   @app.post("/api/recipes")                         โ”‚
โ”‚   @app.delete("/api/admin/...")  โ† BAD              โ”‚
โ”‚                                                     โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚   โ”‚            MCPRampart (embedded)              โ”‚   โ”‚
โ”‚   โ”‚                                             โ”‚   โ”‚
โ”‚   โ”‚  1. Introspect routes at startup            โ”‚   โ”‚
โ”‚   โ”‚  2. Extract Pydantic schemas + type hints   โ”‚   โ”‚
โ”‚   โ”‚  3. โšก Pre-flight security audit             โ”‚   โ”‚
โ”‚   โ”‚     โ†ณ refuse to start on CRITICAL findings  โ”‚   โ”‚
โ”‚   โ”‚  4. Generate MCP tool definitions           โ”‚   โ”‚
โ”‚   โ”‚  5. Mount JSON-RPC at /mcp                  โ”‚   โ”‚
โ”‚   โ”‚  6. ๐Ÿ›ก๏ธ  Scan every tools/call for injection โ”‚   โ”‚
โ”‚   โ”‚     โ†ณ block / alert / log per policy        โ”‚   โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
         โ”‚
         โ–ผ
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ”‚  Claude   โ”‚ โ”‚  ChatGPT  โ”‚ โ”‚  Gemini   โ”‚ โ”‚ Cursor  โ”‚
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Roadmap

  • v0.1 โ€” FastAPI introspection, MCP Streamable HTTP transport, examples
  • v0.2 โ€” rampart.audit() with 7 security checks, severity levels, JSON/text output
  • v0.3 โ€” Runtime guardrails: prompt-injection detection + block/alert/log policy + structured callbacks
  • v0.4 โ€” Multi-framework: Flask + Django adapters (the real white space)
  • v0.5 โ€” Custom audit & guardrail rules (decorators / config / plugins) + tunable confidence thresholds
  • v0.6 โ€” Auth passthrough (OAuth2 / API keys / JWT), stdio transport
  • v1.0 โ€” Smart tool grouping (collapse CRUD into fewer tools), policy-as-code, OpenAPI/Asyncapi spec ingestion

Contributing

git clone https://github.com/miloudbelarebia/mcp-rampart
cd mcp-rampart
pip install -e ".[dev]"
pytest

See CONTRIBUTING.md for guidelines.


License

MIT โ€” see LICENSE.


Built with โค๏ธ by Miloud Belarebia
97M MCP installs per month. Someone has to audit what they expose.

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_rampart-0.3.3.tar.gz (27.0 kB view details)

Uploaded Source

Built Distribution

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

mcp_rampart-0.3.3-py3-none-any.whl (24.4 kB view details)

Uploaded Python 3

File details

Details for the file mcp_rampart-0.3.3.tar.gz.

File metadata

  • Download URL: mcp_rampart-0.3.3.tar.gz
  • Upload date:
  • Size: 27.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for mcp_rampart-0.3.3.tar.gz
Algorithm Hash digest
SHA256 4c0d2980454025c936d4563bebfeddb2e55680c7150d71b4cfc9e89af0088438
MD5 5ee4056fe3fa8ee98f7b9d3d941c9b8f
BLAKE2b-256 7ef4afd3dd574b09947469bcbe508100594c21ab75862d215d8a7d48ac37e6b1

See more details on using hashes here.

File details

Details for the file mcp_rampart-0.3.3-py3-none-any.whl.

File metadata

  • Download URL: mcp_rampart-0.3.3-py3-none-any.whl
  • Upload date:
  • Size: 24.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for mcp_rampart-0.3.3-py3-none-any.whl
Algorithm Hash digest
SHA256 5a1ed3b9c51e9e8f6ab0d27e809eb589105fb01eecdf0e9a158f46f307ea410c
MD5 5746bb3cf6e1ee84bef7a6391921909f
BLAKE2b-256 e2d1ed947d55dbef0b7aae3d2540da1ac781f24c933aadae5378d3a42a2b4863

See more details on using hashes here.

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