Security middleware for MCP. Blocks prompt injection, PII leakage, and resource exhaustion.
MCP-Bastion is security middleware for the Model Context Protocol (MCP). It is described as blocking prompt injection, PII leakage, and resource exhaustion, with a focus on security scanning/testing and observability for MCP.
🛠️ Key Features
Security middleware for MCP
Blocks prompt injection
Blocks PII leakage
Blocks resource exhaustion
Security and observability alignment (includes “mcp-observability” and OWASP-related topics)
🚀 Use Cases
MCP security testing and security scanning
Audit-oriented workflows for MCP interactions
Applying OWASP-style controls for LLM/MCP threats
⚡ Developer Benefits
Supports MCP security-focused development and evaluation
Provides observability-related context via “mcp-observability”
Multi-language relevance indicated by topics: Java, JavaScript/Node/Node.js, and Python (plus “koltin”)
⚠️ Limitations
Limited scope is indicated only for protection against prompt injection, PII leakage, and resource exhaustion (other capabilities are not described)
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.
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).
bash
# 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 CLI - flags injection, secrets, homoglyphs, and fingerprint drift with letter grade A–F
mcp-bastion scan - client-side static scanner; no cloud, no ML download
mcp-bastion audit CLI - local MCP risk audit of client configs, over-broad tools, and standing credentials
mcp-bastion audit - map the local MCP surface before you enforce; no network, no vault
MCP-Bastion: full MCP method coverage and Redis shared state for multi-replica deployments
MCP-Bastion hybrid stateful and stateless MCP transport with discovery, Redis-backed FinOps keys, and agent stability
MCP-Bastion 3.2 dual-path: legacy stateful sessions and SEP-2575-ready stateless state handles on one proxy
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, not delete_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)
yaml
# Stop the Confused Deputy Problem - Identity-Aware Routingagent_iam:enabled:truetoken_metadata_key:bastion_agent_tokenagents:-id:customer_support_bottoken_env:BASTION_TOKEN_SUPPORTallowed_tools: ["search_docs", "get_ticket_status"]
blocked_tools: ["execute_sql", "delete_user"]
rate_limit:max_iterations:5# Supply-chain checksums before any tool executesserver_verification:enabled:trueon_mismatch:blockbase_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
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).
MCP-Bastion Zero-Trust runtime governance: full MCP surface, Redis scale, Agent IAM, and beyond-OWASP coverage
Why developers adopt it
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)
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:
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.
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):
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.
MCP-Bastion benchmarks: RBAC tool-level matrix, output budget up to 99% on large tool responses, discovery filter catalog savings, lexical cache hit/miss
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 10OWASP 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.
MCP-Bastion: OWASP MCP Top 10, FinOps abuse attacks, token reduction and cost saving, 16 security pillars
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
Three ways to adopt
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"]
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
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).
Access control, integrity & abuse
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
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).
FinOps & performance
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).
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.
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).
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
Prebuilt images (after the first publish-docker run, usually on a v* release tag):
bash
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):
bash
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).
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:
python
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().
CLI for developers
bash
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
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.
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.
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.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.
Structure
Path
Description
src/mcp_bastion/
Python package: PromptGuard, Presidio, rate limiting, RBAC, etc.
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)
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]
(adds pyyaml; otherwise you may get ImportError when 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-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.
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.
Add MCP-Bastion to an existing MCP server in three steps:
python
from mcp_bastion import MCPBastionMiddleware, compose_middleware
# 1. Create the security middleware
bastion = MCPBastionMiddleware(
enable_prompt_guard=True,
enable_pii_redaction=True,
enable_rate_limit=True,
)
# 2. Compose with your middleware chain (Bastion runs first)
middleware = compose_middleware(bastion)
# 3. Pass the composed middleware to your MCP server# (integration depends on your server framework)
Examples:
Example
Description
examples/python_server_example.py
Basic middleware chain
examples/full_demo.py
Full middleware stack: add, PII, rate limit, prompt injection, etc.
from mcp.server.fastmcp import FastMCP
from mcp_bastion_fastmcp import secure_fastmcp
mcp = FastMCP("My Secure Server")
secure_fastmcp(mcp) # call right after FastMCP(), before mcp.run()@mcp.tool()defget_weather(city: str) -> str:
"""Get weather for a city."""returnf"Weather in {city}: 22C, sunny"if __name__ == "__main__":
mcp.run(transport="streamable-http")
Step 3: Run the server
bash
python server.py
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 fullbastion.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:
python
from mcp_bastion import build_middleware_from_config
middleware = build_middleware_from_config()
from mcp_bastion import MCPBastionMiddleware
from mcp_bastion.pillars.rate_limit import TokenBucketRateLimiter
from mcp_bastion.pillars.prompt_guard import PromptGuardEngine
# Stricter limits
rate_limiter = TokenBucketRateLimiter(
max_iterations=10,
timeout_seconds=30,
token_budget=25_000,
)
# Higher threshold = fewer blocks, more risk
prompt_guard = PromptGuardEngine(threshold=0.92)
bastion = MCPBastionMiddleware(
prompt_guard=prompt_guard,
rate_limiter=rate_limiter,
enable_prompt_guard=True,
enable_pii_redaction=True,
enable_rate_limit=True,
)
# Disable PII redaction if your data has no PII
bastion_no_pii = MCPBastionMiddleware(enable_pii_redaction=False)
Python: Custom Middleware
Extend Middleware to add logging, metrics, or custom logic:
python
from mcp_bastion import MCPBastionMiddleware
from mcp_bastion.base import Middleware, MiddlewareContext, compose_middleware
classLoggingMiddleware(Middleware):
asyncdefon_message(self, context, call_next):
result = await call_next(context)
# log method, elapsed, etc.return result
bastion = MCPBastionMiddleware() # or use the configured instance from above
middleware = compose_middleware(bastion, LoggingMiddleware())
import { Server } from"@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from"@modelcontextprotocol/sdk/server/stdio.js";
import {
wrapWithMcpBastion,
} from"@mcp-bastion/core";
const server = newServer({ name: "my-mcp-server", version: "1.0.0" });
// Wrap the server with MCP-Bastion (rate limiting only by default)// For prompt injection, PII, semantic egress, and result guard, run the Python sidecarwrapWithMcpBastion(server, {
enableRateLimit: true,
maxIterations: 15,
timeoutMs: 60_000,
// Optional: enable ML / semantic features via Python sidecarsidecarUrl: process.env.MCP_BASTION_SIDECAR || "",
enablePromptGuard: !!process.env.MCP_BASTION_SIDECAR,
enablePiiRedaction: !!process.env.MCP_BASTION_SIDECAR,
// Opt-in cyber extensions — see docs/CYBER_EXTENSIONS_CORE.mdenableSemanticEgress: true,
semanticEgressMode: "detect",
semanticEgressTools: ["create_pull_request", "send_email"],
tagResultProvenance: true,
enableAudit: true,
});
// Register tools (handlers are automatically wrapped)
server.setRequestHandler("tools/call"asany, async (request) => {
if (request.params?.name === "get_weather") {
return {
content: [{ type: "text", text: "Sunny, 22C" }],
isError: false,
};
}
thrownewError("Unknown tool");
});
asyncfunctionmain() {
const transport = newStdioServerTransport();
await server.connect(transport);
}
main();
Step 3: Run with rate limiting only
bash
npx tsx server.ts
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:
bash
# Start the Python sidecar, then the TypeScript server (sidecarUrl or MCP_BASTION_URL)
MCP_BASTION_SIDECAR=http://localhost:8000 npx tsx server.ts
Mediation precondition: wrappers only see MCP-mediated tool calls. Out-of-band shell/git is out of scope.
# Start your guarded server
python server.py # or: npx tsx server.ts# In another terminal, launch the Inspector
npx -y @modelcontextprotocol/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
bash
# Python (PYTHONPATH=src on Windows: $env:PYTHONPATH="src")
python -m pytest tests/ -v
# TypeScript
npm run test --workspace=@mcp-bastion/core
# Full validation checklist (build, pillars, latency)
PYTHONPATH=src python scripts/validate_checklist.py
# MCP Inspector (manual)
npx -y @modelcontextprotocol/inspector
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.