
MCP-Bastion
io.github.vaquarkhanPublished by GitHub account vaquarkhanv5.1.0Updated Oct 24, 2026
Security middleware for MCP. Blocks prompt injection, PII leakage, and resource exhaustion.
Overview
Security middleware for MCP servers that scans tool catalogs, audits local client configs, red-teams policies and enforces runtime guards against injection, PII
- What you can do
- Scan and fingerprint tool catalogs and skill files for injection, secrets, homoglyphs and drift, and audit local MCP client configs for over-broad grants and standing credentials (CLI). Red-team a bastion.yaml policy and validate it before deployment. Enforce runtime controls on every MCP method: prompt-injection and content filtering, PII redaction, RBAC and per-agent tool allow/deny, argument and schema guards, replay and rate limits. Cap cost and abuse with token budgets, iteration limits, USD spend caps and circuit breakers. Log allow/deny decisions to audit JSONL, metrics, alert webhooks and a local dashboard, and export compliance reports.
- When to use it
- Use it when you run or ship MCP servers and want a local, policy-as-code layer that blocks prompt injection, PII leakage, runaway tool loops and spend, and when you need pre-deploy scanning of tool metadata or an audit of what agents can already reach on a machine.
- Requirements
- Runs locally as a Python package (mcp-bastion-python, with extras such as policy, redis and otel) plus optional FastMCP or TypeScript adapters. Configuration is a bastion.yaml file; agent IAM uses per-agent tokens referenced by environment variable names. Optional features need Redis for shared state, Hugging Face access for the PromptGuard model, and Ollama for the local LLM scanner.
Installation
In SourceWeft
- Open MCP-Bastion in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Other MCP clients
Follow the launch instructions in the repository.
README
MCP-Bastion
README · Documentation · Demos · Dashboard / Observability · Multi-language · Benchmark · License · Security
[MCP-Bastion - Fortifying the Model Context Protocol]
[PyPI version] [PyPI downloads (mcp-bastion-python)] [Ecosystem PyPI downloads] [Python] [CI] [Docker proxy (GHCR)] [Docker dashboard (GHCR)] [Docs] [Demos] [Benchmark deck] [Multi-language] [License: Source Available] [Website]
Current release: 5.1.0 · Docker v5.1.0 · 26 PyPI packages · CHANGELOG
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.
Measured proof (offline, reproducible)
Slide deck (share with evaluators): MCP-Security-Deck-v3.pdf — security + FinOps proof pack (direct download).
[MCP-Bastion: SCAN → TEST → ENFORCE - No other tool has all three]
Scan → Test → Enforce (no other tool has all three)
scan vs audit - different inputs, different questions
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).
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
[MCP-Bastion client-side scan suite - schema preconditions, skill files, OSV dependency CVE lookup]
Schema · Skills · OSV - offline by default; no login server; no phone-home
Feature tour
[MCP-Bastion dashboard walkthrough GIF]
Dashboard walkthrough
[MCP-Bastion dashboard collage - security posture, OWASP coverage, attack matrix, and runtime KPIs]
Live security posture + runtime dashboard - local-only, zero infra. mcp-bastion dashboard --demo · Dashboard docs · Older Vimeo walkthrough
[MCP-Bastion: full MCP method coverage and Redis shared state for multi-replica deployments]
Hybrid stateful / stateless MCP (3.2.0) - opt-in mcp_transport for SEP-2575 readiness without breaking legacy sessions. Architecture · Tutorial
Why MCP-Bastion? (Solving the 2026 MCP Security Crisis)
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:
- The Confused Deputy (Agent IAM): Identity-aware routing binds API tokens to Agent Identities and enforces strict per-tool RBAC. Your customer-support bot can call
search_docs, notdelete_user. - Supply chain & typosquatting defense: Cryptographic SHA-256 manifest verification blocks traffic when MCP server artifacts drift from your signed-off checksums.
- Data exfiltration & injection prevention: PromptGuard heuristics + ML block jailbreaks locally; Presidio scrubs outbound PII before it hits a model context window.
Define your agent policies (bastion.yaml)
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)
Runtime governance pillars (3.0.0+, current 5.1.0)
Opt-in enterprise controls for production MCP runtimes. All default off so 2.x behavior is unchanged until you enable them.
CLI compliance evidence: mcp-bastion report --framework soc2 --audit ./audit.jsonl
[MCP-Bastion 3.0 runtime governance pillars]
[Exfiltration canary blocks context leakage in tool arguments]
Full MCP surface + horizontal scale (2.0.0)
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).
pip install mcp-bastion-python[redis] · Deep dive: docs/MCP_SURFACE_AND_SCALE.md
Production hardening adopted in 2.0.0
Battle-tested patterns from the broader MCP gateway ecosystem, wired into the middleware stack:
Why developers adopt it
FinOps & abuse protection (denial-of-wallet)
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:
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.
Token reduction & cost saving
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):
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.
OWASP MCP Top 10 + production attacks
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)
FinOps & abuse attacks (beyond OWASP)
Token reduction & cost saving
Deep-dive mapping and integration hooks: docs/SECURITY_OBSERVABILITY.md · docs/ATTACK_PREVENTION.md
Secure your MCP server in 3 lines (FastMCP)
Policy-as-code instead? Copy bastion.yaml.example → bastion.yaml, then pip install mcp-bastion-python[policy]:
More paths (TypeScript, CI validate, Docker): docs/QUICK_START.md · docs/README.md · website
- Prompt injection defense: Heuristic jailbreak blocking out of the box; Meta PromptGuard ML when Hugging Face access is configured.
- PII redaction: Presidio masks SSN, email, phone in outbound content.
- Denial-of-wallet protection: Token buckets, iteration caps, token budget, cost tracking.
- Response scan: Blocks jailbreak patterns in outbound tool/resource text.
- Output budget & grounding guard: Optional response truncation and path verification (opt-in).
How it works
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.
Three ways to adopt
Releases: npm, PyPI, and prebuilt Docker on GHCR - see DOCKER.md. Community: SUPPORT.md · CONTRIBUTING.md · FUNDING.md · Security: SECURITY.md.
Core Features
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.
Complete feature catalog
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.
Threat prevention & content safety
Access control, integrity & abuse
FinOps & performance
Audit, metrics & alerting
Policy, packaging & developer experience
Real-Time Dashboard and Alerts
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.
[MCP-Bastion dashboard feature tour GIF]
Feature tour
[MCP-Bastion dashboard walkthrough GIF]
Dashboard walkthrough
[MCP-Bastion dashboard collage - posture, OWASP, attack matrix, KPIs]
Regenerate captures: mcp-bastion dashboard --demo then python scripts/capture_dashboard_demo.py · Seed: --demo
What you get on the board
/api/metrics JSON for Grafana, Datadog, or custom pollers
Feed scan/audit artifacts into the posture panels:
- Alerts: Slack webhook and cost-threshold alerts. Full UI reference: dashboard/README.md.
Documentation: Use Cases, Attacks, Metrics, Tutorials
Adoption paths (start-to-finish):
Full index: docs/README.md · handbook site: Docs guide · quick wrap: docs/QUICK_START.md · discovery: docs/DISCOVERY.md · contribute: CONTRIBUTING.md.
One-Line Docker
Prebuilt images (after the first publish-docker run, usually on a v* release tag):
Build locally (any revision):
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).
Policy-as-Code (bastion.yaml)
Single config file controls policy (see docs/PILLARS.md for pillar definitions). Copy bastion.yaml.example to bastion.yaml, then:
Tip: set hot_reload.enabled: true in bastion.yaml to apply policy changes without restarting your MCP server when using build_middleware_from_config().
CLI for developers
See docs/CLI.md.
Continuous integration (this repository)
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 onsrc/mcp_bastion(see[tool.coverage.*]inpyproject.tomlfor measured paths and gates).npm ciandnpm test- TypeScript workspace tests.
To validate your repo’s bastion.yaml in CI without cloning MCP-Bastion, see examples/ci/README.md.
OpenTelemetry
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.
Webhook alerts and external logging
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.
[MCP-Bastion features at a glance]
Why MCP-Bastion
- Active enforcement - Intercepts MCP tool traffic so policies (prompt injection checks, PII handling, content rules, RBAC, and more) run before tools execute and before sensitive results propagate.
- Local-first classification - PromptGuard and Presidio run in your environment; you are not required to send prompts to a third-party API for guardrail scoring.
- Stateful guardrails - Per-session rate limits, iteration caps, token budgets, and cost tracking to reduce runaway loops and unexpected spend.
- Composable integration - Use
bastion.yamlwithbuild_middleware_from_config()or wireMCPBastionMiddleware/wrapWithMcpBastionin 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.
Structure
Example Files
Installation
Python
Prerequisites (recommended)
- PII redaction: Presidio expects the spaCy English model. After install, run:
python -m spacy download en_core_web_sm
Without it, PII analysis can fail at runtime. - Policy-as-Code (
bastion.yaml): install YAML support:
pip install mcp-bastion-python[policy]
(addspyyaml; otherwise you may getImportErrorwhen loading policy files). - Prompt injection (PromptGuard): two layers:
- Regex heuristics (always on) block obvious jailbreak strings such as “ignore previous instructions” - no model download required.
- ML classifier (default ungated):
ProtectAI/deberta-v3-base-prompt-injection-v2viause_ungated_default: true(no Hugging Face login). Optional gated upgrade: setuse_ungated_default: falseand usemeta-llama/Llama-Prompt-Guard-2-86Mafterhuggingface-cli login. Unverified payloads are blocked whenfail_open: false(default). Runmcp-bastion doctorto 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
Framework Integrations
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).
Publish one-by-one: see integrations/PUBLISH.md.
Publish (PyPI / npm)
- PyPI:
python -m build && twine upload dist/*(or use GitHub Actions on tag). - npm: From repo root,
cd packages/core && npm publish --access public(or use Trusted Publishers). - Version is set in
pyproject.toml(Python),packages/core/package.json(npm), andserver.json(MCP registry). Bump before releasing.
Developer Guide
Integration examples for Python and TypeScript. Full contributor and feature docs:
Quick Start (Python)
Add MCP-Bastion to an existing MCP server in three steps:
Examples:
LLM integration: See docs/LLM_INTEGRATION.md for copy-paste config for OpenAI, Claude, Gemini, Mistral, and Grok.
Enterprise validation:
See VALIDATION_CHECKLIST.md and SETUP_GUIDE.md.
Python Tutorial: FastMCP Server
FastMCP server with MCP-Bastion via secure_fastmcp (patches tool dispatch - see integrations/mcp-bastion-fastmcp/README.md).
Step 1: Install dependencies
Step 2: Create your server file (server.py)
Step 3: Run the server
MCP-Bastion (via secure_fastmcp):
- Scans tool arguments for prompt injection before execution
- Redacts PII in tool results on the way out
- Enforces default rate limits (15 calls per session, 60s timeout - see
TokenBucketRateLimiter)
For full bastion.yaml policy or resource (resources/read) PII redaction, use the low-level MCP Server with build_middleware_from_config() - see docs/QUICK_START.md path B.
Alternative: Policy-as-Code
Use bastion.yaml instead of code. Copy bastion.yaml.example to bastion.yaml, then:
See docs/POLICY_AS_CODE.md and examples/server_with_config.py.
Python: Custom Rate Limits
Custom config example:
Python: Custom Middleware
Extend Middleware to add logging, metrics, or custom logic:
See examples/full_demo.py for a complete example.
TypeScript: Wrap an MCP Server
Step 1: Install dependencies
Step 2: Create your server (server.ts)
Step 3: Run with rate limiting only
Step 4: Run with full ML features (Python sidecar)
For prompt injection, PII redaction, semantic egress, and result guard, run a Python HTTP service that exposes /prompt-guard, /pii-redact, /semantic-egress, and /result-guard (see docs/CYBER_EXTENSIONS_CORE.md). Then:
Mediation precondition: wrappers only see MCP-mediated tool calls. Out-of-band shell/git is out of scope.
TypeScript: Wrap Individual Handlers
Wrap specific handlers only:
Configuration Reference
Error Handling
When MCP-Bastion blocks a request, it returns standard MCP/JSON-RPC errors:
Testing
MCP Inspector:
Connect via HTTP (http://localhost:8000/mcp) or stdio, then:
- List tools and call one with benign arguments (should succeed)
- Call a tool with "Ignore previous instructions" (should be blocked)
- Trigger 16+ tool calls in one session (should hit rate limit)
Testing
Third-Party Components
See NOTICE for licenses. MCP-Bastion uses Meta Llama Prompt Guard 2 (Llama 4 Community License) and Microsoft Presidio. For OWASP-relevant mitigations and dependency audit, see docs/SECURITY.md. To report vulnerabilities privately, see SECURITY.md.
License
MCP-Bastion is distributed under the MCP-Bastion Community and Commercial License (LICENSE).
- Free for non‑commercial use when you cite MCP-Bastion and the copyright notice (see CITATION.cff; you can list your name, team, or org as authors or as who used the software, while still including the project and repository in the credit).
- Copyright is retained. Do not remove license or copyright text, and do not republish a duplicate of the work as if it were unrelated software without meeting the License terms.
- Commercial use (as defined in the License) may still require a separate written agreement - see COMMERCIAL_LICENSE.md.
See also:
- LICENSE
- COMMERCIAL_LICENSE.md
- FUNDING.md - sponsorship and sustainability
- SUPPORT.md - docs, issues, response expectations
- CITATION.cff
Product overview & security decks
Reproducible numbers behind the decks: docs/BENCHMARKS.md · threat model: docs/THREAT_MODEL.md.
Source: README.md at commit b6bd8c4
Tools
0Version history
1- v5.1.0LatestSep 16, 2026
Score
40% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
- Reached in the last 30 days25 pts
Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.
- Auth declared10 pts
Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.
- Tools listed15 pts
Answer tools/list without a credential, or ship a package that starts in a sandbox without one.
- DescriptionRequired15 pts
- Logo10 pts
- Documentation15 pts
- License10 pts
Declare a license in the repository or the registry entry.