
A security middleware layer that sits between Claude and your MCP servers to block prompt injections, redact PII, and prevent runaway API costs. Uses Meta's PromptGuard locally to score tool arguments for adversarial patterns, Microsoft Presidio to mask sensitive data in responses, and token bucket limits to kill infinite loops before they drain your budget. Adds RBAC for tools, schema validation on arguments, and audit logs with structured deny reasons. Ships as Python middleware that hooks into standard MCP JSON-RPC traffic with claimed sub-5ms overhead. Designed for enterprises running MCP servers against production databases or APIs where a single malicious prompt or agent hallucination could leak customer data or rack up five-figure LLM bills.
README · Documentation · Demos · Dashboard / Observability · Multi-language · Benchmark · License · Security
Current release: 5.1.0 · Docker v5.1.0 · 26 PyPI packages · CHANGELOG
| Go to | Link |
|---|---|
| Docs / demos | https://vaquarkhan.github.io/MCP-Bastion/ · product tour video · integrations |
| Benchmark / security deck (PDF) | MCP-Security-Deck-v3.pdf · raw download |
| Documentation handbook | https://vaquarkhan.github.io/MCP-Bastion/guide/handbook.html |
| Demos (attacks, dashboard, payloads, all languages) | https://vaquarkhan.github.io/MCP-Bastion/guide/demos.html |
| Dashboard & observability (OTEL optional) | https://vaquarkhan.github.io/MCP-Bastion/guide/observability.html |
| Multi-language suite | https://vaquarkhan.github.io/MCP-Bastion/guide/multi-language.html · suite repo |
| MCP Test Harness (sister product — CI gate for MCP servers) | https://github.com/vaquarkhan/mcp-test-harness · use with Bastion E2E |
| Docs hub | https://vaquarkhan.github.io/MCP-Bastion/guide/ |
| Measured benchmarks (reproducible) | docs/BENCHMARKS.md |
The Zero-Trust control plane for MCP agents. Your agent can call databases, APIs, and shell tools. One bad prompt can leak PII; one runaway loop can burn your API budget in minutes; three agents on one server with no identity boundary is a confused-deputy incident waiting to happen. MCP-Bastion wraps your MCP server with local guardrails: agent IAM, supply-chain checksums, injection blocking, PII redaction, and denial-of-wallet caps, under 5ms overhead, with no third-party safety API.
Guiding rule: Stay a zero-infra, drop-in library - the guardrail brain that composes with any gateway, not a gateway itself. Strategy: docs/ZERO_INFRA_STRATEGY.md.
Slide deck (share with evaluators): MCP-Security-Deck-v3.pdf — security + FinOps proof pack (direct download).
| Gate | Result | How to reproduce |
|---|---|---|
| Injection heuristics | 100% attack block · 0% benign FP on the published corpus | pytest tests/test_injection_efficacy.py · docs/BENCHMARKS.md |
| Tool catalog scan | Injection / secrets / homoglyphs / shadow tools / nested weak schemas | mcp-bastion scan examples/fixtures/tools-poisoned.json |
| FinOps | Up to ~99.7% output-budget savings · ~85% fewer discovery tokens | docs/BENCHMARKS.md |
| Toxic-flow taint | Session PII/secret → egress tool with URL/email args blocked in-process | toxic_flow in bastion.yaml · docs/THREAT_MODEL.md |
| Phase | What | Command |
|---|---|---|
| Scan | Static tool-definition checks before deploy (injection, secrets, homoglyphs, fingerprint drift, schema preconditions) | mcp-bastion scan tools.json |
| Audit | Local MCP client-config risk report (over-broad tools, standing credentials, filesystem servers) | mcp-bastion audit |
| Test | Integrated red-team against bastion.yaml + pair with MCP Test Harness in CI | mcp-bastion redteam · docs/BASTION_AND_TEST_HARNESS.md |
| Enforce | Runtime middleware on every MCP method | secure_fastmcp(mcp) or bastion.yaml |
scan vs audit - different inputs, different questions
mcp-bastion scan | mcp-bastion audit | |
|---|---|---|
| Looks at | A tool catalog (tools.json / tools/list export) | MCP client configs on disk (mcp.json, Claude Desktop config, etc.) |
| Asks | “Is this tool metadata poisoned or drifted?” | “What can agents already reach on this machine?” |
| Finds | Injection in descriptions, secrets in schemas, homoglyphs, fingerprint drift, weak/unbounded inputSchema shapes | Over-broad tool grants (*), standing credentials in env, filesystem-server hints |
| When | Before you ship or attach a server’s tools (CI / pre-deploy) | Before you tighten policy on a laptop or workspace (local hygiene) |
They complement each other: audit the host surface, then scan the tools you attach. Neither replaces runtime enforce.
mcp-bastion scan also accepts --skills DIR for offline agent skill-file checks. Dependency CVEs: mcp-bastion osv-refresh then mcp-bastion osv-scan (local DB default; --online opt-in, fail-open).
# 1. Scan a tools/list export (or hand-authored catalog) - client-side, no cloud
mcp-bastion scan examples/fixtures/tools-poisoned.json
mcp-bastion fingerprint tools.json -o baseline.json
mcp-bastion scan tools.json --baseline baseline.json --format json -o report.json
mcp-bastion scan --skills ./skills/
# 1b. Audit local MCP client configs (what agents can already reach)
mcp-bastion audit --root .
mcp-bastion audit --format json -o risk-audit.json --fail-on none
# 2. Test policy effectiveness
mcp-bastion redteam --config bastion.yaml
# 3. Enforce at runtime (filesystem path guards when agents can read local files)
# merge examples/bastion-filesystem-guards.yaml into bastion.yaml
mcp-bastion validate --config bastion.yaml
mcp-bastion scan - client-side static scanner; no cloud, no ML download
mcp-bastion audit - map the local MCP surface before you enforce; no network, no vault
Schema · Skills · OSV - offline by default; no login server; no phone-home
Feature tour
Dashboard walkthrough
Live security posture + runtime dashboard - local-only, zero infra. mcp-bastion dashboard --demo · Dashboard docs · Older Vimeo walkthrough
Hybrid stateful / stateless MCP (3.2.0) - opt-in mcp_transport for SEP-2575 readiness without breaking legacy sessions. Architecture · Tutorial
As noted in the NSA's recent Cybersecurity Information Sheet on MCP security and the OWASP MCP Top 10, traditional AppSec tools cannot secure agentic workflows. The gap is runtime governance and the confused deputy problem: multiple AI agents sharing one MCP server with no native identity boundary. Public registry typosquatting and unverified servers have made supply-chain verification a board-level concern.
MCP-Bastion acts as the Zero-Trust Control Plane for your agents, addressing the hardest production problems:
search_docs, not delete_user.bastion.yaml)# Stop the Confused Deputy Problem - Identity-Aware Routing
agent_iam:
enabled: true
token_metadata_key: bastion_agent_token
agents:
- id: customer_support_bot
token_env: BASTION_TOKEN_SUPPORT
allowed_tools: ["search_docs", "get_ticket_status"]
blocked_tools: ["execute_sql", "delete_user"]
rate_limit:
max_iterations: 5
# Supply-chain checksums before any tool executes
server_verification:
enabled: true
on_mismatch: block
base_path: .
manifest_path: mcp-server.manifest.json
Generate a manifest after a trusted build: mcp-bastion manifest server.py pyproject.toml -o mcp-server.manifest.json
Deep dive: docs/RUNTIME_GOVERNANCE.md · docs/ENTERPRISE_RUNTIME_CONTROLS.md (3.0 pillars)
Opt-in enterprise controls for production MCP runtimes. All default off so 2.x behavior is unchanged until you enable them.
| Pillar | Config | What it does |
|---|---|---|
| Exfiltration canary | canary_goallock | Session token in context; blocks tool args that echo it (-32025) |
| ATR YAML rules | atr_rules | Community threat rules merged into content_filter (-32027) |
| Local LLM scanner | llm_scanner | Optional Ollama tier after heuristics; fail-open (-32026) |
| Threat intel feeds | threat_feeds | Background refresh of remote regex patterns |
| Auto-repave | auto_repave | Threshold-based containment (rotate canary, reset scope) |
| Secret redaction | secrets.redact_patterns | replace / hash / mask / remove on tool outputs |
| Observe mode | mode: observe | Log would_block without denying |
mode: enforce
canary_goallock:
enabled: true
atr_rules:
enabled: true
rules_dir: ./atr-rules
secrets:
redact_patterns:
- rule: "sk-[A-Za-z0-9]{20,}"
strategy: mask
CLI compliance evidence: mcp-bastion report --framework soc2 --audit ./audit.jsonl
Previously, most pillars ran only on tools/call. 2.0.0 extends the pipeline to resources/read, prompts/get, sampling/createMessage, and elicitation/create - closing exfil/injection gaps on the rest of the MCP surface.
For multi-replica deployments, enable state_backend.type: redis so rate limits, replay nonces, cost budgets, and session tool scope are shared across pods (default memory is single-process).
state_backend:
type: redis
redis_url: redis://127.0.0.1:6379/0
pip install mcp-bastion-python[redis] · Deep dive: docs/MCP_SURFACE_AND_SCALE.md
Battle-tested patterns from the broader MCP gateway ecosystem, wired into the middleware stack:
| Feature | What you get |
|---|---|
| JSONPath argument guards | Block or redact tool arguments by tool glob + JSONPath + regex before execution (argv-array evasion aware). pip install mcp-bastion-python[policy] |
| RBAC fnmatch globs | Role permissions like read_* / files_* with specificity-aware matching |
Audit JSONL + mcp-bastion tail | Append-only compliance log; audit.jsonl_path in config or mcp-bastion tail -p audit.jsonl |
| Cost checkpoint | Optional disk persistence for session totals across restarts (cost_tracker.checkpoint_path, memory backend only) |
Cost-aware policy (cost_policy) | Live spend rules: degrade model, force discovery filter, require approval; expensive-chain blocking |
| Governance attestation | mcp-bastion attest export --session … - signed session bundle with policy hash + controls fired |
| Boundary mode | Mandatory proxy auth on every request (boundary_mode + edge_auth / agent_iam) - GATEWAY_BOUNDARY.md |
| Ungated PromptGuard | prompt_guard.use_ungated_default: true → ProtectAI DeBERTa classifier (no HF gate) |
cost_policy:
enabled: true
rules:
- when: { session_spend_pct_gte: 80 }
action: degrade_model
target_model: gpt-4o-mini
- when: { session_spend_pct_gte: 95 }
action: require_approval
expensive_chain:
enabled: true
max_projected_cost_usd: 1.0
governance:
attestation_enabled: true
boundary_mode:
enabled: true # requires edge_auth or agent_iam
argument_guards:
enabled: true
rules:
- name: block_shell
match: "run_*"
arg: "$.command"
pattern: "(rm\\s+-rf|curl\\s+.*\\|.*sh)"
action: block
audit:
jsonl_path: .bastion/audit.jsonl
cost_tracker:
checkpoint_path: .bastion/cost-checkpoint.json
| You need… | MCP-Bastion gives you… |
|---|---|
| Guardrails without a rewrite | Drop-in middleware: secure_fastmcp(mcp) or one bastion.yaml |
| Privacy your legal team accepts | PromptGuard + Presidio run in your process; data stays on your network |
| Stop runaway agents & budget burn | On by default: 15 tool calls/session, 60s timeout, 50k token budget. Optional: per-tool caps, USD session/day limits, response offload |
| Shrink context & cut token spend | Opt-in: discovery filter (fewer tools in tools/list), output budget + session offload (up to ~99% on oversized tool outputs), lexical similarity cache - measured benchmarks |
| Something that ships today | PyPI, npm, Docker on GHCR, FastMCP, TypeScript wrapper, CI validate, live dashboard |
| Policy your team can review | bastion.yaml in Git, hot reload, OWASP-aligned controls (docs/PILLARS.md) |
Agents can loop on expensive tools (search, LLM calls, paid APIs) until your bill spikes. Bastion enforces session-level FinOps at the MCP boundary before each tools/call:
| Attack pattern | What Bastion does | Default |
|---|---|---|
| Infinite tool loop | Blocks after max iterations per session | On (15 calls) |
| Long-running session abuse | Session timeout | On (60s) |
| Token / context budget burn | Token budget per session; optional output offload | On (50k tokens); offload opt-in |
| Same tool hammered | Per-tool call cap (max_per_tool) | Opt-in |
| Paid API spend runaway | USD caps via cost tracker | Opt-in |
| Flaky or hostile tool cascade | Circuit breaker opens after failures | Opt-in in example config |
| Tool sprawl in one session | Cap distinct tools per session | Opt-in |
Blocked calls return standard errors (RateLimitExceededError -32002, TokenBudgetExceededError -32003, CostBudgetExceededError -32009) and show up in the dashboard and audit log. See docs/ATTACK_PREVENTION.md.
Bastion does not only block runaway spend - it reduces how much tool output and tool-catalog tokens reach the model on each turn (not the user’s LLM prompt text itself):
| Savings lever | What it does | Default |
|---|---|---|
| Discovery filter | Hides unused tools from tools/list so agents carry a smaller tool catalog in context (~85% fewer catalog tokens in benchmarks with 20→3 tools) | Opt-in |
| Output budget + offload | Truncates oversized tool responses; stores the rest in-session for bastion_get_offloaded (up to ~99.7% on 50k-token dumps; 0% when already under budget) | Opt-in |
| Lexical similarity cache | Skips redundant tool calls when queries are near-identical (Jaccard word overlap - not embedding “semantic” search) | Opt-in |
| Token budget caps | Hard stop before session token burn exceeds your limit | On (50k tokens) |
| USD session/day limits | Dollar ceilings via cost tracker | Opt-in |
There is no honest single “X% prompt reduction” figure - savings are input-dependent. See docs/BENCHMARKS.md for reproducible pytest benchmarks and live numbers.
Reproduce: PYTHONPATH=src python -m pytest tests/test_benchmarks_finops_rbac.py -v · Regenerate report: python scripts/generate_benchmark_report.py
Less tool output and catalog noise per turn means lower LLM input cost - without sending prompts to a third-party optimizer API.
Bottom line: MCP turned every server into an agent gateway overnight. Bastion is the firewall that makes that gateway safe to run in production - in three lines of code or one config file.
All 10 OWASP MCP Top 10 risks are mitigated at the MCP boundary (see controls below). Bastion also blocks FinOps and abuse patterns that OWASP does not list separately.
OWASP MCP Top 10 (all addressed)
| ID | Risk | Bastion controls |
|---|---|---|
| MCP01 | Token / secret exposure | PII redaction, audit trail, outbound response scan |
| MCP02 | Privilege escalation | RBAC, agent IAM, rate limits, cost caps, session tool scope |
| MCP03 | Tool poisoning | Prompt guard, content filter, response scan, metadata guard, grounding guard |
| MCP04 | Supply chain | Circuit breaker, server_verification checksums, doctor CLI, mcp-bastion manifest, audit |
| MCP05 | Command injection | Prompt guard, content filter, schema validation |
| MCP06 | Intent subversion | Rate limits, replay guard, per-tool caps, semantic firewall |
| MCP07 | Weak authentication | RBAC, edge auth, agent IAM (per-agent tokens) |
| MCP08 | Audit & telemetry | Audit log, dashboard, Prometheus, OTEL, alerts |
| MCP09 | Shadow MCP servers | Central bastion.yaml policy, metrics, discovery filter |
| MCP10 | Context injection | PII redaction, response scan, output budget, discovery filter |
FinOps & abuse attacks (beyond OWASP)
| Attack | Controls |
|---|---|
| Denial of wallet | Iteration cap, token budget, cost tracker, output budget |
| Runaway tool loops | Session timeout, rate limiter, circuit breaker |
| Per-tool hammering | max_per_tool session caps |
| API spend runaway | USD session/day caps |
| Session tool sprawl | Distinct-tool limit per session |
| Replay abuse | Replay guard + nonces |
Token reduction & cost saving
| Lever | Controls | Benchmark |
|---|---|---|
| Smaller tool catalog in context | Discovery filter on tools/list | ~85% catalog tokens (20→3 tools) - BENCHMARKS.md |
| Less tool output in every turn | Output budget, session offload, bastion_get_offloaded | Up to ~99.7% on oversized dumps; 0% when under budget |
| Fewer redundant calls | Lexical similarity cache (Jaccard overlap) | Exact repeat hits; paraphrase misses at 0.9 |
| Predictable spend | Token budget caps, USD session/day limits | Session defaults on |
Deep-dive mapping and integration hooks: docs/SECURITY_OBSERVABILITY.md · docs/ATTACK_PREVENTION.md
pip install mcp mcp-bastion-fastmcp
from mcp.server.fastmcp import FastMCP
from mcp_bastion_fastmcp import secure_fastmcp
mcp = FastMCP("My Server")
secure_fastmcp(mcp) # wires prompt guard, PII redaction, rate limits into tools/call
Policy-as-code instead? Copy bastion.yaml.example → bastion.yaml, then pip install mcp-bastion-python[policy]:
from mcp_bastion import build_middleware_from_config
middleware = build_middleware_from_config() # loads bastion.yaml
More paths (TypeScript, CI validate, Docker): docs/QUICK_START.md · docs/README.md · website
MCP-Bastion sits in-process on your MCP server and inspects every tools/call before it reaches databases, APIs, or shell tools - then redacts sensitive data on the way back.
flowchart LR
Agent["AI agent / LLM client"]
Server["Your MCP server"]
Bastion["MCP-Bastion<br/>middleware"]
Tools["Tools & upstream APIs"]
Agent -->|"JSON-RPC"| Server
Server --> Bastion
Bastion -->|"✓ allow / ✗ block"| Tools
Tools -->|"raw result"| Bastion
Bastion -->|"PII masked · audited"| Server
Server --> Agent
flowchart TB
Start(["Protect my MCP server"])
Start --> FastMCP["FastMCP · Python<br/><code>secure_fastmcp(mcp)</code>"]
Start --> Policy["Policy-as-code<br/><code>build_middleware_from_config()</code>"]
Start --> TS["TypeScript<br/><code>wrapWithMcpBastion(server)</code>"]
FastMCP --> Docs["docs/QUICK_START.md · path A"]
Policy --> Yaml["bastion.yaml + CI validate"]
TS --> Sidecar["Rate limit in-process · ML via sidecar"]
Releases: npm, PyPI, and prebuilt Docker on GHCR - see DOCKER.md. Community: SUPPORT.md · CONTRIBUTING.md · FUNDING.md · Security: SECURITY.md.
Zero-Click Prompt Injection Prevention
Integrates Meta's PromptGuard model locally to detect and block malicious payloads, jailbreaks, and adversarial tokenization before they reach your external tools.
PII Redaction
Microsoft Presidio scans outbound tool results and masks PII (redaction, substitution, generalization).
Infinite Loop and Denial of Wallet Protection
Implements stateful cycle detection and configurable FinOps token-bucket algorithms to automatically terminate runaway agents and prevent massive API bill overruns.
100% Local Execution (Data Privacy)
All security classification and data redaction happen entirely within the local memory space of your server. Sensitive data never leaves your enterprise network for third-party safety evaluations.
Low Latency
Drop-in middleware, under 5ms overhead.
Framework Integration
Hooks into MCP SDKs (TypeScript, Python) and FastMCP via standard middleware. No business logic changes.
Pillar definitions: Security controls, bastion.yaml sections, and how they relate to dashboard health rows are documented in docs/PILLARS.md (canonical reference; avoids ambiguous “total pillar” counts). The same page lists extended features restored in 1.0.16+ (semantic firewall, sensitive classifier, external policy, edge auth, tool allowlist, session scope, tool metadata guard, multi-tenant, audit hash chain, pricing hooks, telemetry sinks, red team and doctor CLIs, etc.), FinOps/context pillars in 1.0.17+ (output budget, discovery filter, response scan, grounding guard), and runtime governance (agent IAM, server verification - introduced in 1.0.18+, shipped in 2.0.0).
Deeper context: docs/SECURITY_OBSERVABILITY.md - OWASP MCP Top 10 alignment, attack scenarios, and SIEM/log integrations. Framework add-ons (LangChain, OpenAI, Bedrock, …) are listed under Framework Integrations below.
| Feature | What you get |
|---|---|
| Prompt injection defense | Meta PromptGuard scores tool arguments; malicious / jailbreak-style payloads can be blocked before execution (local inference, no third-party API). |
| Content filter | Block shell/code execution patterns, sensitive file paths, and URLs; optional allowlist / denylist regex or substring rules. |
| PII redaction | Microsoft Presidio detects many entity types in outbound tool/resource text (SSN, email, phone, cards, passport, IBAN, licenses, etc. - see Presidio docs). |
| Feature | What you get |
|---|---|
| Agent IAM (Confused Deputy) | Bind API tokens to agent identities; per-agent allowed_tools / blocked_tools, resource URI allow/block, optional rate limits - stops a support bot from calling admin tools or reading secret resources. See docs/RUNTIME_GOVERNANCE.md. |
| Full MCP surface guards (2.0.0) | resources/read, prompts/get, sampling/createMessage, elicitation/create - same inbound/outbound pillars as tool calls (not only tools/call). docs/MCP_SURFACE_AND_SCALE.md |
| Distributed state (2.0.0) | state_backend: redis - shared rate limits, replay nonces, cost caps, session scope across replicas. pip install mcp-bastion-python[redis] |
| Behavioral fingerprinting (3.3.0, opt-in) | behavior_fingerprint.enabled - per-agent tool baseline drift + rate spikes; default OFF. docs/BEHAVIOR_FINGERPRINT.md |
| Hybrid MCP transport (opt-in) | mcp_transport - stateful sessions and stateless explicit state handles; per-request protocol version; proxy discovery card; agent stability monitor. docs/HYBRID_MCP_TRANSPORT.md |
| Server verification (supply chain) | SHA-256 manifest checksums verified at startup and on every tools/call; mcp-bastion manifest generates trusted manifests after a signed-off build. |
| RBAC | Tool-level allow/deny by role (from request metadata); fnmatch globs (read_*) with specificity-aware matching in bastion.yaml. Pair with Agent IAM or edge auth - alone, roles are only as trustworthy as whatever sets metadata["role"]. Live matrix → |
| Argument guards (2.0.0) | JSONPath + regex block/redact on tools/call arguments before schema validation - stops shell injection and secret exfil in argv-style payloads. |
| Schema validation | Validate tools/call arguments against JSON Schema before the tool runs (block malformed or bypass attempts). |
| Replay guard | Nonce tracking to reject replayed requests (configurable require_nonce). |
| Rate limiting | Token-bucket style limits: max iterations per session, timeout, token budget - stops runaway loops and brute-force patterns. |
| Circuit breaker | Stop calling tools that fail repeatedly (limits blast radius of bad upstreams or poisoned tools). |
| Feature | What you get |
|---|---|
| Cost tracker | Per-session and optional per-day USD caps; blocks when budget is exceeded. Optional disk checkpoint for restart-safe totals (memory backend). |
| Semantic cache (lexical) | Optional Jaccard word-overlap cache for near-identical tool queries - not embedding-based; see benchmarks. |
| Low overhead | Middleware on the hot path targeting <5 ms typical overhead (see docs/METRICS.md). |
| Feature | What you get |
|---|---|
| Audit logging | Structured allow/deny decisions with reason, tool, tenant_id, trace_id, request_id - feed SOC / compliance. Optional JSONL file sink + mcp-bastion tail. |
| Alert sinks | Slack incoming webhook; generic HTTP webhooks (PagerDuty, Teams, custom APIs); multiple URLs; retry, backoff, timeout in bastion.yaml. |
| In-memory metrics | Global MetricsStore: requests, blocks, PII counts, cost, per-tool stats, latency samples, rolling time series buckets. |
| Real-time dashboard | Local web UI (additive panels): pre-deploy posture grades + Sonar-style prevalidation from .bastion/scan/, PMD-style issue guides (why / how to fix / OWASP), OWASP ASI + MCP + LLM heatmaps, live attack matrix, compliance evidence + dated reports, date filters, observe-mode banner, agents / trends / onboarding, forensics with why/pillar/trace, FinOps cost burn (actual vs would-have-been, tokens saved + avoided by blocks, charts), plus classic KPIs. APIs: /api/metrics, /api/posture, /api/prevalidate, /api/issue-guide, /api/taxonomy, /api/attack-matrix, /api/compliance. Dark/light theme. See dashboard/README.md. |
| OpenTelemetry | Optional OTLP span export - pip install mcp-bastion-python[otel] - docs/OTEL.md. |
| Feature | What you get |
|---|---|
| Policy-as-code | Single bastion.yaml: toggles for all request-path controls plus audit, alerts, and hot reload (docs/PILLARS.md); load via load_config / build_middleware_from_config. |
| Hot reload | Optional reload bastion.yaml on change without restarting the MCP server (docs/POLICY_AS_CODE.md). |
| Composable middleware | compose_middleware ordering; MCPBastionMiddleware flags for each pillar. |
| CLI | mcp-bastion scan, audit, validate, redteam, manifest, attest export, serve, dashboard, doctor, tail - docs/CLI.md. |
| Python + multi-language | mcp-bastion-python on PyPI (engine). For TypeScript / Java / Go / .NET / Kotlin / Rust adapters + shared bastion.yaml, use mcp-bastion-suite — see docs/MULTI_LANGUAGE_SUITE.md. Optional in-repo TypeScript: @mcp-bastion/core. |
| Containers | Dockerfile, docker-compose profiles (proxy + optional dashboard) - DOCKER.md. Prebuilt images (GHCR): mcp-bastion-proxy, mcp-bastion-dashboard - published on each v* tag (publish-docker.yml). |
The dashboard is optional and local - a read-only view over runtime metrics + local scan/audit artifacts. No login server, no cloud DB (see docs/ZERO_INFRA_STRATEGY.md).
Feature tour (GIF): posture + how-to-fix → OWASP → attack matrix → compliance → RBAC/governance → forensics → agents → posture drift → token & cost savings → traffic.
Feature tour
Dashboard walkthrough
Regenerate captures: mcp-bastion dashboard --demo then python scripts/capture_dashboard_demo.py · Seed: --demo
| Area | Panels / actions |
|---|---|
| Pre-deploy posture | Letter grades A–F for catalog scan, skill scan, OSV, risk audit + combined grade (reads .bastion/scan/*.json) |
| Static prevalidation | Sonar-style issue list from the same local JSON - not a SonarQube server (/api/prevalidate) |
| Issue guides | PMD-style why / how to fix / Bastion knobs / OWASP refs on every finding (/api/issue-guide) |
| OWASP coverage | Tabs for ASI Top 10, MCP Top 10, LLM Top 10 - green/amber/grey heatmap with finding + block pressure |
| Live attack matrix | Categories under pressure with intensity, share, top tool, OWASP tags, sample/trace drill-down |
| Compliance / reports | Attestation + policy hash; generate SOC2 / GDPR / ISO27001 / NIST AI RMF / ASI evidence or zip (date-filtered) |
| Runtime | KPIs, governance, alerts + SSE, insights, forensics (Why + Details), agents / trends / onboarding, traffic/latency/PII charts |
| FinOps | Actual vs would-have-been spend/tokens; FinOps tokens saved; tokens/$ avoided by blocks; charts + blocked-issues table |
| Filters | Date range + presets (forensics, trends, attack matrix, reports) |
mcp-bastion dashboard --port 7000 --demo
# or: PYTHONPATH=src python dashboard/app.py
| URL | What it returns |
|---|---|
| http://localhost:7000/ | Full UI (posture, prevalidate, OWASP, attack matrix, FinOps, forensics, …) |
| http://localhost:7000/api/metrics | Runtime JSON (cost_reduction: used/saved/avoided + would-have cost) |
| http://localhost:7000/api/posture | Scan / skill / OSV / risk-audit grades from local JSON |
| http://localhost:7000/api/prevalidate | Sonar-style issue list + grades (local scan suite) |
| http://localhost:7000/api/issue-guide?check=weak_schema | PMD-style rule card (or ?id=ASI02) |
| http://localhost:7000/api/taxonomy | ?framework=asi|mcp|llm heatmap |
| http://localhost:7000/api/attack-matrix | Live attack categories (+ date filter) |
| http://localhost:7000/api/compliance/report | Evidence markdown (framework, date_from, date_to) |
| http://localhost:7000/api/health | Build / ui_revision |
| http://localhost:7000/metrics | Prometheus text |
/api/metrics JSON for Grafana, Datadog, or custom pollers
Feed scan/audit artifacts into the posture panels:
mkdir -p .bastion/scan
mcp-bastion scan tools.json --format json -o .bastion/scan/catalog.json
mcp-bastion scan --skills ./skills --format json -o .bastion/scan/skills.json
mcp-bastion osv-scan --format json -o .bastion/scan/osv.json
mcp-bastion audit --format json -o .bastion/scan/risk-audit.json
Adoption paths (start-to-finish):
| Goal | Read in order |
|---|---|
| End-to-end handbook | docs/USER_GUIDE.md → published Docs |
| Documentation handbook (GIFs + dashboard) | docs/DOCUMENTATION_HANDBOOK.md → live handbook |
| Feature deep dive + attack demos | docs/FEATURE_DEEP_DIVE.md → docs/ATTACK_DEMOS.md |
| Java / TypeScript / Go / .NET / Kotlin / Rust | docs/MULTI_LANGUAGE_SUITE.md → mcp-bastion-suite |
Policy-as-code (bastion.yaml) | docs/PILLARS.md → docs/POLICY_AS_CODE.md → bastion.yaml.example → docs/CLI.md (validate) |
| LLM clients (OpenAI, Claude, Gemini, …) | docs/LLM_INTEGRATION.md → docs/INTEGRATION_MODELS.md → examples/ (llm_*.py) |
| FastMCP / TypeScript / third-party MCP | docs/TUTORIALS.md → docs/DETAILED_TUTORIAL.md |
Fleet rollout of bastion.yaml + SIEM / SOC audit | docs/SECURITY_OBSERVABILITY.md → docs/POLICY_AS_CODE.md |
| Minimal “hello world” + CI / registries | docs/QUICK_START.md → examples/ci/README.md → docs/DISCOVERY.md |
Full index: docs/README.md · handbook site: Docs guide · quick wrap: docs/QUICK_START.md · discovery: docs/DISCOVERY.md · contribute: CONTRIBUTING.md.
| Doc | Description |
|---|---|
| docs/USER_GUIDE.md | End-to-end user guide (concepts → install → proxy → vault → ops); published at /guide/ |
| docs/DOCUMENTATION_HANDBOOK.md | System handbook: attack GIFs, dashboard tour, feature map, multi-language |
| docs/FEATURE_DEEP_DIVE.md | Feature-by-feature deep dive: issue, how Bastion solves it, benefits (incl. dashboard) |
| docs/ATTACK_DEMOS.md | Runnable attack → defense demos (keep heavy walkthroughs out of this README) |
| docs/MULTI_LANGUAGE_SUITE.md | Multi-language connectors via mcp-bastion-suite |
| docs/index.md | Markdown docs home (source hub) |
| docs/POLICY_AS_CODE.md | bastion.yaml reference: keys, examples, hot reload, alerts |
| docs/LLM_INTEGRATION.md | LLM integration: OpenAI, Claude, Gemini, Mistral, Grok (stdio + HTTP configs) |
| docs/DETAILED_TUTORIAL.md | Step-by-step implementation tutorial for new teams |
| docs/USE_CASES.md | Real use cases: enterprise gateway, LLM products, internal tools, SaaS, compliance |
| docs/ATTACK_PREVENTION.md | Examples showing how MCP-Bastion prevents real attacks (injection, PII leak, rate exhaustion, path traversal, RBAC, replay) |
| docs/PILLARS.md | Canonical pillar counts: 18 request-path features (10 core + 8 extended), 14 dashboard pillar_health rows, 20+ bastion.yaml top-level areas - see the doc for scope |
| docs/SUPPLY_CHAIN.md | CI merge gates, releases, npm provenance, PyPI Trusted Publishing, CycloneDX SBOM |
| docs/CRA_COMPLIANCE.md | CRA / OpenSSF steward posture (Article 14 + SBOM; no runtime change) |
| docs/CRA_SBOM_TUTORIAL.md | Generate and download CycloneDX bom.json |
| docs/PII_VAULT.md | Opt-in reversible PII tokenization (abstract + hydrate) |
| docs/INTEGRATION_MODELS.md | Middleware + bastion.yaml vs “change base URL”; bridge for Python, TS, Desktop, HTTP, integrations |
| examples/ci/README.md | Copy-paste GitHub Actions snippet to run mcp-bastion validate on your policy file |
| docs/BENCHMARKS.md | Measured RBAC matrix, output-budget reduction (up to ~99% on large tool outputs), discovery filter, lexical cache - pytest + report generator |
| docs/REDTEAM.md | Interpreting harness / red-team scores; which bastion.yaml pillars to enable; Node vs Python scope (packages/core/README.md) |
| docs/SECURITY_OBSERVABILITY.md | OWASP MCP Top 10, integration hooks, fleet-scale bastion.yaml rollout, SIEM / SOC audit patterns |
| docs/METRICS.md | Performance overhead (<5ms) and effectiveness metrics (dashboard, Prometheus, OTEL) |
| docs/TUTORIALS.md | Tutorials: integrating with FastMCP, TypeScript, GitHub MCP, and open-source MCP servers |
| docs/CYBER_EXTENSIONS_CORE.md | TypeScript Extensions A/E/F (semantic egress, result provenance, audit) |
| docs/GITHUB_PAGES.md | Publish docs as a GitHub Pages website from this same repo |
| docs/QUICK_START.md | Minimal FastMCP / bastion.yaml / CI snippets (time-to-value) |
| docs/DISCOVERY.md | Registry and ecosystem discovery checklist |
| docs/ENTERPRISE_RUNTIME_CONTROLS.md | 3.0 runtime governance: canary, ATR rules, LLM scanner, threat feeds, auto-repave, secret redaction, observe mode |
| docs/ROADMAP.md | Product roadmap: cost-aware governance, security depth, discoverability |
| docs/COMPARISON.md | vs unguarded MCP, thin proxy, full AI/MCP gateway |
| docs/ENGINEERING_10_10.md | Strategic path to 10/10 on injection depth, tool poisoning, gateway maturity, FinOps metrics, project maturity |
| CONTRIBUTING.md | Contributor guide and good first issue ideas |
Prebuilt images (after the first publish-docker run, usually on a v* release tag):
docker pull ghcr.io/vaquarkhan/mcp-bastion-proxy:latest
docker run -p 8080:8080 ghcr.io/vaquarkhan/mcp-bastion-proxy:latest
# Dashboard (optional, port 7000):
# docker pull ghcr.io/vaquarkhan/mcp-bastion-dashboard:latest
# docker run -p 7000:7000 ghcr.io/vaquarkhan/mcp-bastion-dashboard:latest
# Pin a release: ghcr.io/vaquarkhan/mcp-bastion-proxy:vX.Y.Z (published on each v* tag)
Build locally (any revision):
docker build -t mcp-bastion/proxy .
docker run -p 8080:8080 mcp-bastion/proxy
MCP endpoint: http://localhost:8080/mcp. Use docker-compose up -d for proxy; add --profile with-dashboard for the dashboard. See DOCKER.md (includes GHCR pull commands and package links for forks: replace vaquarkhan with your org or user in image paths).
Single config file controls policy (see docs/PILLARS.md for pillar definitions). Copy bastion.yaml.example to bastion.yaml, then:
from mcp_bastion import build_middleware_from_config
middleware = build_middleware_from_config()
Tip: set hot_reload.enabled: true in bastion.yaml to apply policy changes without restarting your MCP server when using build_middleware_from_config().
mcp-bastion audit # local MCP client-config risk report
mcp-bastion scan tools.json # static tool-definition scan
mcp-bastion validate # validate bastion.yaml
mcp-bastion serve --http 8080 # run MCP server with config
mcp-bastion dashboard --port 7000 # run metrics dashboard
See docs/CLI.md.
On every pull request and push to main, .github/workflows/ci.yml runs:
pip install -e ".[dev,policy,dashboard]" - install the Python package with tests, YAML policy loading, and FastAPI for dashboard tests.mcp-bastion validate --config bastion.yaml.example - ensure the example policy file loads.python -m pytest --cov=mcp_bastion --cov-fail-under=92 - full Python test suite with ≥92% line coverage on src/mcp_bastion (see [tool.coverage.*] in pyproject.toml for measured paths and gates).npm ci and npm test - TypeScript workspace tests.To validate your repo’s bastion.yaml in CI without cloning MCP-Bastion, see examples/ci/README.md.
Set OTEL_EXPORTER_OTLP_ENDPOINT to export tool-call spans to OTLP. Install optional deps: pip install mcp-bastion-python[otel]. See docs/OTEL.md.
Use Slack (slack_webhook / SLACK_WEBHOOK_URL), a generic HTTP webhook (webhook_url / BASTION_WEBHOOK_URL), or multiple URLs (alerts.webhooks in bastion.yaml). POSTs can drive PagerDuty, Microsoft Teams, Datadog Events, or any HTTP collector your SIEM exposes. Configure retry/backoff in bastion.yaml (retry_attempts, retry_backoff_seconds, retry_backoff_max_seconds, timeout_seconds).
Metrics & traces: scrape the dashboard /metrics (Prometheus) or poll /api/metrics (JSON) for Grafana, Datadog, or custom pollers. Set OTEL_EXPORTER_OTLP_ENDPOINT for traces to Jaeger, Honeycomb, AWS ADOT, etc. (pip install mcp-bastion-python[otel]). Route Python logs (including LoggingAlertSink) through Fluent Bit, Vector, or the CloudWatch agent into Splunk / Elastic / CloudWatch Logs.
See docs/SECURITY_OBSERVABILITY.md for the full integration table and OWASP MCP Top 10 alignment.
bastion.yaml with build_middleware_from_config() or wire MCPBastionMiddleware / wrapWithMcpBastion in Python or TypeScript. For a separate process in front of an upstream MCP server, use a wrapper or proxy you control; see docs/INTEGRATION_MODELS.md.| Path | Description |
|---|---|
src/mcp_bastion/ | Python package: PromptGuard, Presidio, rate limiting, RBAC, etc. |
packages/core/ | TypeScript package: rate limit + provenance + audit in-process; prompt/PII/semantic/result via sidecar (MCP_BASTION_URL) |
examples/ | Python examples (examples/README.md) |
dashboard/ | Real-time dashboard UI and metrics API (dashboard/README.md) |
bastion.yaml.example | Policy-as-code sample; copy to bastion.yaml (docs/POLICY_AS_CODE.md) |
scripts/validate_checklist.py | Enterprise validation runner |
VALIDATION_CHECKLIST.md | Validation guide and MCP Inspector steps |
SETUP_GUIDE.md | Setup, config, and validation |
DOCKER.md | Docker one-line run and compose |
| File | Purpose |
|---|---|
examples/python_server_example.py | Minimal middleware chain |
examples/full_demo.py | Multi-pillar stack (core toggles: rate limit, PII, RBAC, … - see docs/PILLARS.md) |
examples/llm_server.py | Shared MCP server for LLM clients |
examples/llm_openai_example.py | OpenAI |
examples/llm_claude_example.py | Claude |
examples/llm_gemini_example.py | Gemini |
examples/llm_mistral_example.py | Mistral |
examples/llm_grok_example.py | Grok (xAI) |
examples/server_with_config.py | Policy-as-code (bastion.yaml) |
Python
uv add mcp-bastion-python
# or
pip install mcp-bastion-python
# pin a specific release (optional)
pip install mcp-bastion-python==5.1.0
Prerequisites (recommended)
python -m spacy download en_core_web_smbastion.yaml): install YAML support:pip install mcp-bastion-python[policy]pyyaml; otherwise you may get ImportError when loading policy files).ProtectAI/deberta-v3-base-prompt-injection-v2 via use_ungated_default: true (no Hugging Face login). Optional gated upgrade: set use_ungated_default: false and use meta-llama/Llama-Prompt-Guard-2-86M after huggingface-cli login. Unverified payloads are blocked when fail_open: false (default). Run mcp-bastion doctor to verify ML availability.The PyPI wheel ships the full mcp_bastion tree (including config, cli, otel, dashboard metrics, and alert sinks). If you use an older wheel that omits modules, upgrade to the current release.
TypeScript
npm install @mcp-bastion/core
Drop-in security for your favorite LLM framework. Each package auto-installs mcp-bastion-python. Version and download columns use live badges from ecosystem-downloads.json (all-time total via PePy). Trends: pypistats.org.
One-place totals: Integrations download dashboard · ecosystem-downloads.json (sum of all 26 packages, refreshed daily).