mcp-bastion-python 1.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,13 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ dist/
5
+ build/
6
+ .eggs/
7
+ node_modules/
8
+ *.log
9
+ .env
10
+ .venv/
11
+ venv/
12
+ .DS_Store
13
+ *.tsbuildinfo
@@ -0,0 +1,5 @@
1
+ MCP-Bastion uses the following third-party components:
2
+
3
+ Llama Prompt Guard 2 (meta-llama/Llama-Prompt-Guard-2-86M)
4
+ Llama 4 is licensed under the Llama 4 Community License, Copyright (c) Meta Platforms, Inc. All Rights Reserved.
5
+ See: https://www.llama.com/docs/overview
@@ -0,0 +1,506 @@
1
+ Metadata-Version: 2.4
2
+ Name: mcp-bastion-python
3
+ Version: 1.0.1
4
+ Summary: Security middleware for MCP servers protecting LLM agents from prompt injection, resource exhaustion, and PII leakage
5
+ Project-URL: Homepage, https://github.com/mcp-bastion/mcp-bastion
6
+ Project-URL: Repository, https://github.com/mcp-bastion/mcp-bastion
7
+ Project-URL: Documentation, https://github.com/mcp-bastion/mcp-bastion#readme
8
+ Author: Viquar Khan
9
+ License-Expression: MIT
10
+ License-File: NOTICE
11
+ Keywords: llm,mcp,middleware,pii,prompt-injection,security
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Security
20
+ Requires-Python: >=3.10
21
+ Requires-Dist: mcp>=1.0.0
22
+ Requires-Dist: presidio-analyzer>=2.2.0
23
+ Requires-Dist: presidio-anonymizer>=2.2.0
24
+ Requires-Dist: spacy>=3.5.0
25
+ Requires-Dist: torch>=2.0.0
26
+ Requires-Dist: transformers>=4.30.0
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
29
+ Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
30
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
31
+ Description-Content-Type: text/markdown
32
+
33
+ # MCP-Bastion
34
+
35
+ **Enterprise-Grade Security Middleware for the Model Context Protocol**
36
+
37
+ **Author:** Viquar Khan
38
+
39
+ > Releases are published automatically to npm and PyPI via GitHub Actions when tags are pushed.
40
+
41
+ The Model Context Protocol (MCP) has rapidly become the universally accepted standard for connecting AI agents to enterprise databases and APIs. However, this connectivity introduces a massive new attack surface: unpredictable, non-deterministic agentic behavior.
42
+
43
+ MCP-Bastion is a lightweight, drop-in security middleware designed to wrap around any existing Python or TypeScript MCP server. Instead of relying on passive logging, human-in-the-loop approvals, or third-party APIs, MCP-Bastion provides an active, 100% local defense layer. It intercepts standard JSON-RPC traffic to stop threats before they cross the enterprise boundary.
44
+
45
+ Under 5ms proxy overhead. MCP-Bastion provides:
46
+
47
+ - **Prompt Injection Defense:** Meta PromptGuard runs locally to block adversarial payloads and jailbreaks.
48
+ - **PII Redaction:** Uses Microsoft Presidio to detect and mask PII before it reaches the LLM context.
49
+ - **Infinite Loop Protection:** Token buckets and cycle detection stop runaway agents from burning API budget.
50
+
51
+ Secure your MCP server without changing business logic.
52
+
53
+ ---
54
+
55
+ ## Core Features
56
+
57
+ **Zero-Click Prompt Injection Prevention**
58
+
59
+ Integrates Meta's PromptGuard model locally to detect and block malicious payloads, jailbreaks, and adversarial tokenization before they reach your external tools.
60
+
61
+ **PII Redaction**
62
+
63
+ Microsoft Presidio scans outbound tool results and masks PII (redaction, substitution, generalization).
64
+
65
+ **Infinite Loop and Denial of Wallet Protection**
66
+
67
+ Implements stateful cycle detection and configurable FinOps token-bucket algorithms to automatically terminate runaway agents and prevent massive API bill overruns.
68
+
69
+ **100% Local Execution (Data Privacy)**
70
+
71
+ 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.
72
+
73
+ **Low Latency**
74
+
75
+ Drop-in middleware, under 5ms overhead.
76
+
77
+ **Framework Integration**
78
+
79
+ Hooks into MCP SDKs (TypeScript, Python) and FastMCP via standard middleware. No business logic changes.
80
+
81
+ ---
82
+
83
+ ## Why MCP-Bastion (Competitive Comparison)
84
+
85
+ Early security packages (mcp-guardian, mcp-shield) focus on logging or static scanning. MCP-Bastion adds an active defense layer.
86
+
87
+ ### 1. Active Defense vs. Passive Logging
88
+
89
+ | The Competition | MCP-Bastion |
90
+ |-----------------|-------------|
91
+ | Tools like mcp-guardian focus on tracing, logging, human-in-the-loop approvals. | Automated interception. MCP-Bastion scrubs PII before it leaves the server. |
92
+
93
+ ### 2. Local Inference vs. Third-Party APIs
94
+
95
+ | The Competition | MCP-Bastion |
96
+ |-----------------|-------------|
97
+ | Many guardrail proxies send prompts to external APIs (e.g. OpenAI moderation) to check for malice. | PromptGuard-86M and Presidio run locally. Data stays on your network. |
98
+
99
+ ### 3. Stateful Denial of Wallet Protection
100
+
101
+ | The Competition | MCP-Bastion |
102
+ |-----------------|-------------|
103
+ | Most tools focus on static vulns or basic rate limits. | Tracks tool call history per session. Stops runaway loops before they burn API budget. |
104
+
105
+ ### 4. Drop-in Middleware vs. Standalone Gateway
106
+
107
+ | The Competition | MCP-Bastion |
108
+ |-----------------|-------------|
109
+ | Some solutions need standalone proxy servers. | Library hooks into `server.setRequestHandler` (TS) or middleware (Python). No extra infra. |
110
+
111
+ ---
112
+
113
+ ## Structure
114
+
115
+ | Path | Description |
116
+ |------|-------------|
117
+ | `src/mcp_bastion/` | Python package: PromptGuard, Presidio, rate limiting |
118
+ | `packages/core/` | TypeScript package: rate limiting; ML via Python sidecar |
119
+ | `examples/` | Python examples: basic middleware, full demo ([examples/README.md](examples/README.md)) |
120
+ | `scripts/validate_checklist.py` | Enterprise validation runner |
121
+ | `VALIDATION_CHECKLIST.md` | Validation guide and MCP Inspector steps |
122
+ | `SETUP_GUIDE.md` | Setup, config, and validation |
123
+
124
+ ## Installation
125
+
126
+ **Python**
127
+
128
+ ```bash
129
+ uv add mcp-bastion-python
130
+ # or
131
+ pip install mcp-bastion-python
132
+ ```
133
+
134
+ **TypeScript**
135
+
136
+ ```bash
137
+ npm install @mcp-bastion/core
138
+ ```
139
+
140
+ ## Developer Guide
141
+
142
+ Integration examples for Python and TypeScript.
143
+
144
+ ---
145
+
146
+ ### Quick Start (Python)
147
+
148
+ Add MCP-Bastion to an existing MCP server in three steps:
149
+
150
+ ```python
151
+ from mcp_bastion import MCPBastionMiddleware, compose_middleware
152
+
153
+ # 1. Create the security middleware
154
+ bastion = MCPBastionMiddleware(
155
+ enable_prompt_guard=True,
156
+ enable_pii_redaction=True,
157
+ enable_rate_limit=True,
158
+ )
159
+
160
+ # 2. Compose with your middleware chain (Bastion runs first)
161
+ middleware = compose_middleware(bastion)
162
+
163
+ # 3. Pass the composed middleware to your MCP server
164
+ # (integration depends on your server framework)
165
+ ```
166
+
167
+ **Examples:**
168
+
169
+ | Example | Description |
170
+ |---------|-------------|
171
+ | `examples/python_server_example.py` | Basic middleware chain |
172
+ | `examples/full_demo.py` | All features: add, PII, rate limit, prompt injection |
173
+
174
+ ```bash
175
+ # Windows: $env:PYTHONPATH="src"; python examples/full_demo.py
176
+ # Linux/Mac: PYTHONPATH=src python examples/full_demo.py
177
+ ```
178
+
179
+ **Enterprise validation:**
180
+
181
+ ```bash
182
+ PYTHONPATH=src python scripts/validate_checklist.py
183
+ ```
184
+
185
+ See `VALIDATION_CHECKLIST.md` and `SETUP_GUIDE.md`.
186
+
187
+ ---
188
+
189
+ ### Python Tutorial: FastMCP Server
190
+
191
+ FastMCP server with MCP-Bastion.
192
+
193
+ **Step 1: Install dependencies**
194
+
195
+ ```bash
196
+ pip install mcp mcp-bastion-python
197
+ ```
198
+
199
+ **Step 2: Create your server file** (`server.py`)
200
+
201
+ ```python
202
+ from mcp.server.fastmcp import FastMCP
203
+ from mcp_bastion import MCPBastionMiddleware, compose_middleware
204
+
205
+ # Create the MCP server
206
+ mcp = FastMCP("My Secure Server")
207
+
208
+ # Create MCP-Bastion middleware
209
+ # It intercepts tool calls and resource reads before they execute
210
+ bastion = MCPBastionMiddleware(
211
+ enable_prompt_guard=True, # Block malicious prompts via PromptGuard
212
+ enable_pii_redaction=True, # Mask PII in outgoing content
213
+ enable_rate_limit=True, # Cap at 15 iterations, 60s timeout
214
+ )
215
+
216
+ # Compose middleware chain (pass to your server's middleware config if supported)
217
+ middleware = compose_middleware(bastion)
218
+
219
+ # Register a tool (protected when middleware is wired into your server)
220
+ @mcp.tool()
221
+ def get_weather(city: str) -> str:
222
+ """Get weather for a city."""
223
+ return f"Weather in {city}: 22C, sunny"
224
+
225
+ # Resource (PII redacted)
226
+ @mcp.resource("user://profile/{user_id}")
227
+ def get_profile(user_id: str) -> str:
228
+ """Get user profile. PII redacted."""
229
+ return f"User {user_id}: John Doe, SSN 123-45-6789, john@example.com"
230
+
231
+ if __name__ == "__main__":
232
+ mcp.run(transport="streamable-http")
233
+ ```
234
+
235
+ **Step 3: Run the server**
236
+
237
+ ```bash
238
+ python server.py
239
+ ```
240
+
241
+ MCP-Bastion:
242
+ - Scans tool args for prompt injection
243
+ - Redacts PII from resource responses
244
+ - Blocks sessions over 15 calls or 60s
245
+
246
+ ---
247
+
248
+ ### Python: Custom Rate Limits
249
+
250
+ Custom config example:
251
+
252
+ ```python
253
+ from mcp_bastion import MCPBastionMiddleware
254
+ from mcp_bastion.pillars.rate_limit import TokenBucketRateLimiter
255
+ from mcp_bastion.pillars.prompt_guard import PromptGuardEngine
256
+
257
+ # Stricter limits
258
+ rate_limiter = TokenBucketRateLimiter(
259
+ max_iterations=10,
260
+ timeout_seconds=30,
261
+ token_budget=25_000,
262
+ )
263
+
264
+ # Higher threshold = fewer blocks, more risk
265
+ prompt_guard = PromptGuardEngine(threshold=0.92)
266
+
267
+ bastion = MCPBastionMiddleware(
268
+ prompt_guard=prompt_guard,
269
+ rate_limiter=rate_limiter,
270
+ enable_prompt_guard=True,
271
+ enable_pii_redaction=True,
272
+ enable_rate_limit=True,
273
+ )
274
+
275
+ # Disable PII redaction if your data has no PII
276
+ bastion_no_pii = MCPBastionMiddleware(enable_pii_redaction=False)
277
+ ```
278
+
279
+ ---
280
+
281
+ ### Python: Custom Middleware
282
+
283
+ Extend `Middleware` to add logging, metrics, or custom logic:
284
+
285
+ ```python
286
+ from mcp_bastion.base import Middleware, MiddlewareContext, compose_middleware
287
+
288
+ class LoggingMiddleware(Middleware):
289
+ async def on_message(self, context, call_next):
290
+ result = await call_next(context)
291
+ # log method, elapsed, etc.
292
+ return result
293
+
294
+ middleware = compose_middleware(bastion, LoggingMiddleware())
295
+ ```
296
+
297
+ See `examples/full_demo.py` for a complete example.
298
+
299
+ ---
300
+
301
+ ### TypeScript: Wrap an MCP Server
302
+
303
+ **Step 1: Install dependencies**
304
+
305
+ ```bash
306
+ npm install @modelcontextprotocol/sdk @mcp-bastion/core
307
+ ```
308
+
309
+ **Step 2: Create your server** (`server.ts`)
310
+
311
+ ```typescript
312
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
313
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
314
+ import {
315
+ wrapWithMcpBastion,
316
+ wrapCallToolHandler,
317
+ } from "@mcp-bastion/core";
318
+
319
+ const server = new Server({ name: "my-mcp-server", version: "1.0.0" });
320
+
321
+ // Wrap the server with MCP-Bastion (rate limiting only by default)
322
+ // For prompt injection and PII, run the Python sidecar and set sidecarUrl
323
+ wrapWithMcpBastion(server, {
324
+ enableRateLimit: true,
325
+ maxIterations: 15,
326
+ timeoutMs: 60_000,
327
+ // Optional: enable ML features via Python sidecar
328
+ sidecarUrl: process.env.MCP_BASTION_SIDECAR || "",
329
+ enablePromptGuard: !!process.env.MCP_BASTION_SIDECAR,
330
+ enablePiiRedaction: !!process.env.MCP_BASTION_SIDECAR,
331
+ });
332
+
333
+ // Register tools (handlers are automatically wrapped)
334
+ server.setRequestHandler("tools/call" as any, async (request) => {
335
+ if (request.params?.name === "get_weather") {
336
+ return {
337
+ content: [{ type: "text", text: "Sunny, 22C" }],
338
+ isError: false,
339
+ };
340
+ }
341
+ throw new Error("Unknown tool");
342
+ });
343
+
344
+ async function main() {
345
+ const transport = new StdioServerTransport();
346
+ await server.connect(transport);
347
+ }
348
+
349
+ main();
350
+ ```
351
+
352
+ **Step 3: Run with rate limiting only**
353
+
354
+ ```bash
355
+ npx tsx server.ts
356
+ ```
357
+
358
+ **Step 4: Run with full ML features (Python sidecar)**
359
+
360
+ For prompt injection and PII redaction, run a Python HTTP service that exposes `/prompt-guard` and `/pii-redact` endpoints (see the Python package for sidecar implementation). Then:
361
+
362
+ ```bash
363
+ # Start the Python sidecar, then the TypeScript server
364
+ MCP_BASTION_SIDECAR=http://localhost:8000 npx tsx server.ts
365
+ ```
366
+
367
+ ---
368
+
369
+ ### TypeScript: Wrap Individual Handlers
370
+
371
+ Wrap specific handlers only:
372
+
373
+ ```typescript
374
+ import {
375
+ wrapCallToolHandler,
376
+ wrapReadResourceHandler,
377
+ } from "@mcp-bastion/core";
378
+ import {
379
+ CallToolRequestSchema,
380
+ ReadResourceRequestSchema,
381
+ } from "@modelcontextprotocol/sdk/types.js";
382
+
383
+ // Wrap only the tool handler
384
+ const safeToolHandler = wrapCallToolHandler(
385
+ async (request) => {
386
+ // Your tool logic
387
+ return { content: [{ type: "text", text: "OK" }], isError: false };
388
+ },
389
+ { enableRateLimit: true, maxIterations: 10 }
390
+ );
391
+
392
+ // Wrap only the resource handler (for PII redaction)
393
+ const safeResourceHandler = wrapReadResourceHandler(
394
+ async (request) => {
395
+ const contents = await fetchResource(request.params.uri);
396
+ return { contents };
397
+ },
398
+ { sidecarUrl: "http://localhost:8000", enablePiiRedaction: true }
399
+ );
400
+
401
+ server.setRequestHandler(CallToolRequestSchema, safeToolHandler);
402
+ server.setRequestHandler(ReadResourceRequestSchema, safeResourceHandler);
403
+ ```
404
+
405
+ ---
406
+
407
+ ### Configuration Reference
408
+
409
+ | Option | Python | TypeScript | Default | Description |
410
+ |--------|--------|------------|---------|-------------|
411
+ | `enable_prompt_guard` | Yes | Yes | `True` (Python) / `False` (TS) | Block malicious prompts via PromptGuard |
412
+ | `enable_pii_redaction` | Yes | Yes | `True` (Python) / `False` (TS) | Mask PII in outgoing content |
413
+ | `enable_rate_limit` | Yes | Yes | `True` | Enforce iteration and timeout caps |
414
+ | `max_iterations` | Via `TokenBucketRateLimiter` | Yes | 15 | Max tool calls per session |
415
+ | `timeout_seconds` / `timeoutMs` | Via `TokenBucketRateLimiter` | Yes | 60 | Session timeout |
416
+ | `token_budget` | Via `TokenBucketRateLimiter` | - | 50,000 | FinOps token cap per request |
417
+ | `sidecarUrl` | - | Yes | `""` | Python sidecar URL for ML features |
418
+ | `threshold` | Via `PromptGuardEngine` | - | 0.85 | Malicious probability cutoff |
419
+ | `setLogLevel` | - | Yes | `"info"` | TypeScript: `"debug"` \| `"info"` \| `"warn"` \| `"error"` |
420
+
421
+ ---
422
+
423
+ ### Error Handling
424
+
425
+ When MCP-Bastion blocks a request, it returns standard MCP/JSON-RPC errors:
426
+
427
+ | Code | Exception | When |
428
+ |------|-----------|------|
429
+ | -32001 | `PromptInjectionError` | Tool args contain jailbreak/injection |
430
+ | -32002 | `RateLimitExceededError` | Session exceeds iteration or timeout limit |
431
+ | -32003 | `TokenBudgetExceededError` | Session exceeds token budget |
432
+
433
+ ```python
434
+ # Python: exceptions
435
+ from mcp_bastion.errors import (
436
+ PromptInjectionError,
437
+ RateLimitExceededError,
438
+ TokenBudgetExceededError,
439
+ )
440
+ import logging
441
+ logger = logging.getLogger(__name__)
442
+
443
+ try:
444
+ result = await middleware(context, call_next)
445
+ except PromptInjectionError as e:
446
+ logger.warning("blocked: %s", e.to_mcp_error())
447
+ except RateLimitExceededError as e:
448
+ logger.warning("blocked: %s", e.to_mcp_error())
449
+ except TokenBudgetExceededError as e:
450
+ logger.warning("blocked: %s", e.to_mcp_error())
451
+ ```
452
+
453
+ ```typescript
454
+ // TypeScript: handlers return isError: true
455
+ import { logger, setLogLevel } from "@mcp-bastion/core";
456
+ setLogLevel("debug"); // optional: "debug" | "info" | "warn" | "error"
457
+ const result = await guardedHandler(request);
458
+ if (result.isError) {
459
+ logger.error("blocked", result.content);
460
+ }
461
+ ```
462
+
463
+ ---
464
+
465
+ ### Testing
466
+
467
+ MCP Inspector:
468
+
469
+ ```bash
470
+ # Start your guarded server
471
+ python server.py # or: npx tsx server.ts
472
+
473
+ # In another terminal, launch the Inspector
474
+ npx -y @modelcontextprotocol/inspector
475
+ ```
476
+
477
+ Connect via HTTP (`http://localhost:8000/mcp`) or stdio, then:
478
+ 1. List tools and call one with benign arguments (should succeed)
479
+ 2. Call a tool with "Ignore previous instructions" (should be blocked)
480
+ 3. Trigger 16+ tool calls in one session (should hit rate limit)
481
+
482
+ ---
483
+
484
+ ## Testing
485
+
486
+ ```bash
487
+ # Python (PYTHONPATH=src on Windows: $env:PYTHONPATH="src")
488
+ pytest tests/ -v
489
+
490
+ # TypeScript
491
+ npm run test --workspace=@mcp-bastion/core
492
+
493
+ # Full validation checklist (build, pillars, latency)
494
+ PYTHONPATH=src python scripts/validate_checklist.py
495
+
496
+ # MCP Inspector (manual)
497
+ npx -y @modelcontextprotocol/inspector
498
+ ```
499
+
500
+ ## Third-Party Components
501
+
502
+ See `NOTICE` for licenses. MCP-Bastion uses Meta Llama Prompt Guard 2 (Llama 4 Community License) and Microsoft Presidio.
503
+
504
+ ## License
505
+
506
+ MIT