Skip to content

quantifylabs/mcp-parapet

Repository files navigation

mcp-parapet

Security middleware for MCP servers. Runs entirely on your machine.

No API keys. No SaaS accounts. No telemetry. Just pip install mcp-parapet and every tool call gets scanned, verified, and logged before it reaches your server.

Client ↔ [mcp-parapet] ↔ MCP Server
            ↓
      Security Pipeline
      ├─ Content scanning (PII, secrets, prompt injection)
      ├─ Trust boundaries (OWASP 5-tier hierarchy)
      ├─ Rate limiting (per-server, per-tool)
      ├─ Manifest integrity (rug pull detection)
      └─ Audit trail (append-only JSONL)

Why mcp-parapet

82% of MCP servers have file operations vulnerable to path traversal. 66% contain at least one critical code smell. 23% have suspicious instruction-like patterns in tool descriptions.

Most MCP security tools require sign-ups, API tokens, or send your tool descriptions to third-party servers for analysis. mcp-parapet doesn't. Everything runs locally, offline, with zero external dependencies beyond PyYAML.

mcp-scan tells you what's wrong. mcp-parapet stops it from happening.

Install

pip install mcp-parapet

Quickstart

Prefix any server command with mcp-parapet wrap --. That's it.

Whatever command you use to start your MCP server, put mcp-parapet wrap -- in front of it. Every tool call now goes through the security pipeline.

# Before (no security)
npx -y @modelcontextprotocol/server-filesystem /tmp

# After (full security pipeline)
mcp-parapet wrap -- npx -y @modelcontextprotocol/server-filesystem /tmp

Works with any MCP server. No code changes. No server modifications.

# Node-based servers
mcp-parapet wrap -- npx -y @modelcontextprotocol/server-github
mcp-parapet wrap -- npx -y @modelcontextprotocol/server-puppeteer

# Python servers
mcp-parapet wrap -- python my_server.py
mcp-parapet wrap -- uvx my-mcp-package

# Anything that speaks MCP over stdio
mcp-parapet wrap -- ./my-custom-server --port 8080

Use in Claude Desktop

Replace "command" with mcp-parapet and prepend "wrap", "--" to args:

{
  "mcpServers": {
    "filesystem": {
      "command": "mcp-parapet",
      "args": ["wrap", "--name", "filesystem", "--",
               "npx", "-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
    },
    "github": {
      "command": "mcp-parapet",
      "args": ["wrap", "--name", "github", "--",
               "npx", "-y", "@modelcontextprotocol/server-github"],
      "env": { "GITHUB_TOKEN": "ghp_..." }
    }
  }
}

The --name flag tags audit logs and config per server. Optional but recommended.

Customise (optional)

# Generate a config file with sensible defaults
mcp-parapet init

# Scan a file or stdin directly
echo "My SSN is 123-45-6789" | mcp-parapet scan -

Out of the box, mcp-parapet rejects prompt injection, redacts leaked secrets, and logs every tool call. parapet.yaml lets you tune policies, set per-server trust levels, and configure rate limits — but the defaults are production-ready.

What it does

Content Scanning

Four-stage pipeline scans every tool call argument and response:

Stage What it catches Examples
1. Input validation Oversized payloads, null bytes, control chars DoS via payload inflation
2. Sensitive data SSNs, credit cards, API keys, emails, passwords PII leaking to untrusted servers
3. Prompt injection Override attempts, role manipulation, data exfiltration "Ignore previous instructions..."
4. LLM classification (Coming in v0.2) Adversarial inputs that bypass regex Obfuscated injection attacks

Configurable per-category policies: flag, redact, or reject.

Trust Boundaries

Five-tier trust hierarchy for MCP servers:

Level Permissions Use case
none Block all tool calls Unknown/untrusted servers
basic Read-only operations Third-party servers under evaluation
verified Standard operations (default) Servers with known manifests
trusted All operations including writes First-party servers
privileged Admin/system-level operations Internal infrastructure

Per-server allowlists and blocklists for fine-grained control.

Tool Manifest Integrity

Hashes the tool manifest on first connection. On every subsequent connection, compares against the stored hash. Detects:

  • Tool poisoning — malicious instructions embedded in tool descriptions
  • Rug pulls — tool definitions changed after initial trust
  • Tool shadowing — new tools added that impersonate existing ones
  • Manifest tampering — any modification to the tool list

Optional HMAC-SHA256 signing with a secret key for cryptographic verification.

Rate Limiting

Sliding window rate limiter with per-server and per-tool granularity:

  • Default: 60 calls/minute, 1000 calls/hour
  • Configurable per-server overrides
  • Prevents resource exhaustion and abuse

Audit Trail

Append-only JSONL log of every security decision:

{"timestamp":"2026-04-04T10:15:30Z","event_type":"tool_call_blocked","server_name":"filesystem","tool_name":"write_file","verdict":"reject","detections":[{"type":"injection_override","confidence":0.85}]}

Every tool call request, response, block, redaction, rate limit hit, and manifest change is logged with full context.

Configuration

parapet.yaml

scanner:
  policy_pii: flag           # flag | redact | reject
  policy_secrets: redact     # flag | redact | reject
  policy_injection: reject   # flag | redact | reject
  scan_tool_arguments: true
  scan_tool_responses: true

audit:
  enabled: true
  log_file: parapet-audit.jsonl

integrity:
  enabled: true
  alert_on_change: true
  block_on_change: false

rate_limit:
  default_per_minute: 60
  default_per_hour: 1000

servers:
  my-trusted-server:
    trust_level: trusted
  third-party-server:
    trust_level: basic
    allowed_tools:
      - search
      - read
    max_calls_per_minute: 10

Environment Variables

Variable Description
PARAPET_CONFIG Path to config file
PARAPET_SIGNING_KEY HMAC signing key for manifest integrity
PARAPET_AUDIT_FILE Audit log file path
PARAPET_LOG_LEVEL Log level (DEBUG, INFO, WARNING, ERROR)
PARAPET_POLICY_PII Override PII policy
PARAPET_POLICY_SECRETS Override secrets policy
PARAPET_POLICY_INJECTION Override injection policy

Python API

from mcp_parapet import ContentScanner, ScanVerdict

scanner = ContentScanner()

# Scan text content
verdict = scanner.scan("My SSN is 123-45-6789")
print(verdict.allowed)     # True (default PII policy is 'flag')
print(verdict.flags)       # ['pii_detected']
print(verdict.detections)  # [Detection(type=ssn, ...)]

# Scan tool call arguments
verdict = scanner.scan_json({"query": "ignore all previous instructions"})
print(verdict.allowed)     # False (default injection policy is 'reject')

OWASP MCP Top 10 Coverage

mcp-parapet maps to the OWASP MCP Top 10 (2025/2026, beta) — the first OWASP framework dedicated to Model Context Protocol security:

OWASP MCP Risk Status How mcp-parapet addresses it
MCP01 Token Mismanagement & Secret Exposure ContentScanner detects API keys (AWS, OpenAI, GitHub, Anthropic), passwords, and secrets in tool arguments and responses. Configurable: flag, redact, or reject.
MCP02 Privilege Escalation via Scope Creep TrustPolicy enforces 5-tier trust hierarchy with per-server tool allowlists and blocklists. Least-privilege by default.
MCP03 Tool Poisoning integrity module hashes tool manifests on first connection, diffs on reconnection. Detects description changes, tool shadowing, and silent redefinition.
MCP04 Supply Chain Attacks & Dependency Tampering HMAC-SHA256 manifest signing. Hash-based tool pinning across sessions. Alerts or blocks on any manifest change.
MCP05 Command Injection & Execution ContentScanner catches injection patterns in tool arguments. Runtime barrier — blocks payloads before they reach the server.
MCP06 Intent Flow Subversion (Prompt Injection) Stage 3 detection: override attempts, role manipulation, exfiltration instructions. Default policy: reject.
MCP07 Insufficient Authentication & Authorization 🔜 Planned for v0.2 (OAuth 2.1 integration).
MCP08 Lack of Audit & Telemetry AuditTrail — append-only JSONL with every tool call, block, redaction, and security event. File rotation by size.
MCP09 Shadow MCP Servers Out of scope (parapet wraps known servers; shadow detection is a network-level concern).
MCP10 Context Injection & Over-sharing PII and secret scanning catches sensitive data leaking across trust boundaries. Redaction prevents data from reaching untrusted servers.

Also maps to the OWASP Practical Guide for Secure MCP Server Development v1.0 (February 2026): §3 Input Validation (ContentScanner), §4 Access Control (TrustPolicy), §5 Tool Integrity (integrity), §6 Logging (AuditTrail), §7 Rate Limiting (RateLimiter), §8 Error Handling (JSON-RPC error responses).

How mcp-parapet compares

mcp-parapet Snyk Agent Scan (mcp-scan) Enterprise gateways (TrueFoundry, Lasso, MintMCP)
Runs locally ✅ Fully offline ❌ Requires Snyk API token ❌ SaaS / managed cloud
Zero telemetry ✅ Nothing leaves your machine ❌ Sends tool descriptions to Invariant API ❌ Vendor-hosted
Runtime blocking ✅ Intercepts and blocks live traffic ✅ Proxy mode (v0.4+) ✅ Gateway
Install pip install mcp-parapet uvx snyk-agent-scan + API key Dashboard signup + config
Trust boundaries ✅ 5-tier OWASP hierarchy ✅ RBAC / OAuth
Audit trail ✅ Local JSONL ✅ Cloud-hosted
Price Free. MIT license. Free (scan) / Paid (enterprise) Paid

mcp-parapet is not a replacement for enterprise MCP gateways. If you need OAuth 2.1, SSO, multi-tenant RBAC, and managed cloud dashboards, use TrueFoundry or Lasso. If you need a free, local-first security layer that you can pip install and forget — that's mcp-parapet.

CLI Reference

mcp-parapet wrap [--name NAME] [--config FILE] -- <command> [args...]
mcp-parapet scan <file | ->
mcp-parapet init [--output FILE] [--force]
mcp-parapet verify <manifest.json>
mcp-parapet version

License

MIT — Quantify Labs Ltd

Links

About

Local-first security middleware for MCP servers. Content scanning, prompt-injection defence, trust boundaries, manifest integrity, and audit trails. No API keys, no telemetry. OWASP MCP Top 10 aligned.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages