MCPDome sits between your AI agent and any MCP server, intercepting every JSON-RPC message on the wire. It enforces authentication, authorization, rate limiting, and injection detection — without modifying either side. Think of it as a firewall for AI tool calls.
┌──────────┐ ┌─────────┐ ┌────────────┐
│ AI Agent │ ──MCP──>│ MCPDome │──MCP──> │ MCP Server │
│ (Client) │<──MCP── │ Gateway │<──MCP── │ (Tools) │
└──────────┘ └─────────┘ └────────────┘
│
┌────┴────┐
│ Policy │
│ TOML │
└─────────┘
Why MCPDome?
AI agents are getting access to powerful tools — file systems, databases, APIs, code execution. MCP is the protocol connecting them. But there's no security layer in the middle. MCPDome fixes that:
- Default-deny policy engine — TOML rules with time-window conditions and day-of-week filtering, hot-reloadable via file watcher or SIGHUP
- Injection detection — Regex patterns with Unicode normalization (NFKC, homoglyph transliteration, zero-width stripping), recursive JSON scanning, and heuristic analysis (entropy, Base64, length)
- Schema pinning — Canonical SHA-256 hashes of tool definitions detect and block rug pulls and tool shadowing
- Hash-chained audit logs — Tamper-evident NDJSON logging with SHA-256 chain linking, full inbound + outbound coverage
- Token-bucket rate limiting — Global, per-identity, and per-tool limits with LRU eviction and TTL-based cleanup
- Multiple auth methods — Argon2id-hashed PSKs, API key authentication, OAuth2 scaffolding, with automatic credential stripping
- HTTP+SSE transport — Feature-gated HTTP transport with Server-Sent Events, session management, and CORS support (in addition to stdio)
- Full method coverage — All MCP methods are guarded (not just
tools/call), with proper JSON-RPC error responses on deny - Outbound scanning — Server responses are scanned for injection patterns before reaching the AI agent
- CLI toolbox —
validate,verify-log,hash-schema,keygensubcommands plus unified--configfile support - 0.2ms overhead — Rust performance, single binary, zero config to start
Install
# From crates.io
# From source
Quick Start
Wrap any stdio MCP server — zero config, transparent mode:
Enable security features progressively:
# Injection detection
# Schema pinning (detect tool definition changes)
# Rate limiting
# Everything with a config file
CLI Tools
# Validate a policy file
# Verify audit log integrity
# Pre-compute schema pin hashes
# Generate a pre-shared key
What It Catches
| Threat | How MCPDome Stops It |
|---|---|
| Prompt injection in tool args | Ward scans with Unicode normalization, recursive JSON extraction, and heuristic analysis |
| Unicode/encoding evasion | NFKC normalization, homoglyph transliteration, zero-width character stripping |
| Secret leakage (AWS keys, PATs) | Policy deny_regex with recursive argument inspection (catches nested payloads) |
| Tool rug pulls | Schema pinning with canonical JSON hashing blocks critical drift (not just warns) |
| Data exfiltration | Ward detects exfil patterns; outbound scanning catches malicious server responses |
| Unauthorized tool access | Default-deny policy on all MCP methods, not just tool calls |
| Pre-initialize attacks | Session enforcement blocks all requests before authenticated initialize |
| Abuse / runaway agents | Global + per-identity + per-tool rate limiting with LRU eviction |
| Credential leakage | Argon2id PSK hashing, automatic credential stripping before forwarding |
| Tampering with audit trail | SHA-256 hash chain with full inbound + outbound audit coverage |
Policy Example
# Block secret patterns everywhere (highest priority)
[[]]
= "block-secrets"
= 1
= "deny"
= "*"
= "*"
= [
{ = "*", = ["AKIA[A-Z0-9]{16}", "ghp_[a-zA-Z0-9]{36}"] },
]
# Developers can read, not delete
[[]]
= "dev-read-tools"
= 100
= "allow"
= { = ["role:developer"] }
= ["read_file", "grep", "git_status"]
# Write only to safe paths
[[]]
= "dev-write-safe"
= 110
= "allow"
= { = ["role:developer"] }
= ["write_file"]
= [
{ = "path", = ["/tmp/**"], = [".*\\.env$"] },
]
Time-window conditions:
[[]]
= "business-hours-only"
= 50
= "allow"
= "*"
= ["write_file", "delete_file"]
= [
{ = "time_window", = "09:00", = "17:00", = "UTC" },
{ = "day_of_week", = ["Mon", "Tue", "Wed", "Thu", "Fri"] },
]
See mcpdome.example.toml for a complete policy file.
Architecture
Rust workspace of focused crates, each with a single responsibility:
mcpdome (binary)
├── dome-core Shared types & error taxonomy
├── dome-transport MCP wire protocol (stdio, HTTP+SSE)
├── dome-gate Interceptor chain orchestration
├── dome-sentinel Authentication & identity resolution
├── dome-policy TOML policy engine (default-deny)
├── dome-ledger Hash-chained audit logging
├── dome-throttle Token-bucket rate limiting & budgets
└── dome-ward Injection detection & schema pinning
Interceptor chain order (inbound):
sentinel → throttle → ward → policy → ledger → upstream server
Ward runs before policy so injection detection cannot be bypassed by overly permissive authorization rules.
See ARCHITECTURE.md for the full deep dive.
Test Suite
204 tests covering every security component:
dome-core 5 tests (message parsing, error mapping)
dome-sentinel 30 tests (PSK auth, API keys, Argon2id, OAuth2 stub, chain resolution)
dome-policy 39 tests (rules, priority, recursive args, time-windows, hot-reload)
dome-throttle 22 tests (token bucket, rate limits, budgets, LRU eviction, global limits)
dome-ward 56 tests (injection patterns, Unicode normalization, recursive scanning, schema pins, heuristics)
dome-ledger 21 tests (hash chain, tamper detection, file rotation)
dome-transport 5 tests (HTTP+SSE connection, roundtrip, CORS, cleanup)
mcpdome binary 19 tests (CLI subcommands: validate, verify-log, hash-schema, keygen)
integration 7 tests (full binary proxy end-to-end)
Roadmap
| Phase | What Ships | Status |
|---|---|---|
| 1 | Transparent stdio proxy, audit logging | Done |
| 2 | TOML policy engine, PSK authentication, default-deny | Done |
| 3 | Injection detection, schema pinning, rate limiting | Done |
| 4 | HTTP+SSE transport, API key auth, time-window policies, config hot-reload, CLI tools | Done |
| 5 | OAuth 2.0 / mTLS, dashboard UI, remote policy fetching | Next |
License
Apache-2.0
Author
Orel Ohayon / Orellius.ai