mcp-shield
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-shieldrun the red-team suite against my MCP server"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-shield
Security primitives for the Model Context Protocol.
The Blackwell Systems 2026-06 audit scanned 54 production MCP servers and found 20 bugs in 9 of them. The 2026-03-05 MCP roadmap named audit trails, SSO, and machine-readable server discovery as the four blockers keeping MCP out of regulated enterprises. mcp-shield is the missing security layer — five drop-in primitives that address every bug class from the audit, MIT-licensed, stdlib-only, no SaaS dependency.
pip install mcp-shieldWhy this exists
If you're running an MCP server — yours or someone else's — you have four problems mcp-shield solves:
Tool errors return as success.
except E: return _format_error(e)leaves FastMCP'sisErrorflag unset, so the agent retries forever. MCPTox benchmark (arXiv:2508.14925) flags this across 26+ Python MCPs.No audit trail. SOC2 procurement requires per-call records. Building one yourself is a Friday you'll never get back.
Tool output can hijack the agent. OWASP #1 LLM vulnerability (Context Poisoning, >100K sites hit in 2025). Tool descriptions and outputs are the attack surface.
No input validation. Malformed calls from the agent crash your handler with
KeyError,TypeError, etc. — not a typed error the model can correct.
Related MCP server: MCP Security Framework
The five primitives
Primitive | Bug class | Drop-in usage |
| 1 — isError-compliance |
|
| 3 — JSONL audit |
|
| 4-adj — JSON-schema input |
|
| 2 — prompt-injection scrub |
|
| 4 — OAuth 2.1 scope |
|
Plus: a standalone MCP server exposing shield_audit_tail, shield_audit_summary, shield_red_team, shield_scan_input, shield_patterns_list, shield_sanitize_preview, shield_version — register it alongside any other MCP to inspect what's happening.
Quick start (decorator)
from mcp.server.fastmcp import FastMCP
from mcp_shield import shield_tool
mcp = FastMCP("my-server")
@mcp.tool()
@shield_tool(
name="search_things",
schema={
"type": "object",
"required": ["query"],
"properties": {"query": {"type": "string", "minLength": 1, "maxLength": 200}},
"additionalProperties": False,
},
sanitize_strict=False, # redact matched patterns; True raises
required_scopes="read",
)
async def search_things(query: str) -> str:
result = await upstream.search(query)
return json.dumps(result)That's it. You now have:
JSON-schema validation (rejects malformed calls with typed errors)
JSONL audit log per call (stderr default, override with
MCP_SHIELD_AUDIT_LOG)Output sanitization with 15 high-precision patterns from MCPTox + OWASP
isError-compliance (FastMCP sets
isError: trueautomatically)OAuth scope check
Quick start (operational MCP server)
# Audit logs go to stderr by default
mcp-shield
# Or to a file
MCP_SHIELD_AUDIT_LOG=/var/log/mcp/audit.jsonl mcp-shield
# Or disable audit entirely (for unit tests)
MCP_SHIELD_AUDIT=0 mcp-shieldThen ask your MCP client: "what was the error rate over the last hour?" or "run the red-team suite against my MCP."
What's in the box
src/mcp_shield/
├── __init__.py # public surface
├── audit.py # JSONL audit log (stdlib-only, fail-open, secret-redacting)
├── exceptions.py # typed exception hierarchy (ShieldError, ShieldAuthError, ...)
├── sanitize.py # prompt-injection scrubber (15 curated patterns)
├── server.py # standalone MCP server exposing ops tools
├── shield.py # @shield_tool decorator + ShieldedTool class + require_scope
└── validate.py # JSON-schema input validation (Draft 7 subset)Engineering standards
Every line of code in this repo follows patterns documented in the engineering playbook — the same playbook used by hawksoft-mcp, ezyvet-mcp, practicepanther-mcp, and the rest of the sanjibani MCP portfolio.
ruff: full rule set (E/F/W/I/N/UP/B/A/C4/DTZ/T20/PT/Q/RET/SIM/TID/ARG/PTH/ERA/PL/RUF)
mypy --strict: clean
pytest: 53 tests, all passing, covering every primitive + edge cases
py.typed: ships the marker for downstream
mypyto type-check usstdlib-only: audit + sanitize + validate need no extra deps; only
mcp[cli],httpx,pydantic,structlogfor the wrapperfail-open: a broken audit sink never breaks the tool (SOC2 baseline)
JSON-RPC safe: audit goes to stderr (or file), never stdout
Cross-promo footer
If you ship an MCP server, drop the shield on it in 5 minutes. If you don't ship one and just need to harden the ones you use, add the operational MCP server to your fleet.
If you'd rather have someone build a custom MCP server (vertical SaaS, internal tool, anything with a REST/GraphQL/SOAP API), see the engagement page — $25K / $60K / $120K+ tiers.
Other vertical MCPs in this portfolio:
hawksoft-mcp — independent insurance AMS
open-dental-mcp — dental practice
ezyvet-mcp — veterinary practice
jobber-mcp — home service trades
practicepanther-mcp — legal practice mgmt
Maintainer
Sanjibani Choudhury schoudhury1991@gmail.com · github.com/sanjibani
Available Tools
7 toolsaudit_summaryA
Aggregate counts over a JSONL audit log: total calls, error rate, top tools.
Use when: "how healthy is the MCP fleet?", "what's the error rate?". Example: path="/var/log/mcp-shield/audit.jsonl".
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
audit_tailA
Return the last n records from a JSONL audit log.
Use when: "what did the agent just do?", "did anything fail?". Example: path="/var/log/mcp-shield/audit.jsonl", n=50.
| Name | Required | Description | Default |
|---|---|---|---|
| n | No | ||
| path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
patterns_listA
List the prompt-injection patterns the sanitizer detects.
Use when: "what does this tool actually look for?".
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
red_teamA
Run a curated set of injection payloads through the sanitizer.
Use when: "is the sanitizer actually catching things?", "compliance evidence for security review". Example: strict=False (default; reports hits without raising).
Each result row shows {"input", "caught", "pattern"}. caught
is True iff the sanitizer matched any pattern.
| Name | Required | Description | Default |
|---|---|---|---|
| strict | No | ||
| extra_patterns | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
sanitize_previewA
Preview what the sanitizer would do to text without raising.
Use when: "what gets redacted from this output?". Example: text="ignore previous instructions", strict=False.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | ||
| strict | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
scan_inputA
Validate an args dict against a JSON schema; return OK or first error.
Use when: "is my agent's call valid before I send it?". Example: args={"q":"hi"}, schema={"type":"object","properties":{"q":{"type":"string"}}}.
Returns {"valid": true} or {"valid": false, "error": "..."}.
Never raises — the tool surfaces validation results as data.
| Name | Required | Description | Default |
|---|---|---|---|
| args | Yes | ||
| schema | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
versionA
Return mcp-shield version + runtime config.
Use when: "what version is deployed?".
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
7 tool updates
v0.1.0- First observed
audit_summary - First observed
audit_tail - First observed
patterns_list - First observed
red_team - First observed
sanitize_preview - First observed
scan_input - First observed
version
TDQS
Scored across 7 tools
Each tool has a clearly distinct purpose: auditing (summary and tail), pattern management (list and test), sanitization preview, input validation, and version info. No overlap.
All tool names use snake_case and follow a verb_noun pattern (audit_summary, audit_tail, patterns_list, red_team, sanitize_preview, scan_input). Even 'version' fits as a simple noun command.
With 7 tools, the surface is well-scoped for a security/audit server. It covers auditing, pattern introspection, testing, preview, input validation, and version info without bloat.
Covers core workflows: auditing (summary + tail), pattern listing, red team testing, sanitization preview, and input validation. Minor gaps like dynamic pattern updates or configuration are absent but not critical for the stated purpose.
Maintenance
Related MCP Connectors
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
One OAuth connector for your team's remote MCP servers, with Tool Packs, guardrails and logs.
Authenticated MCP server for ClearPolicy policy and compliance workflows.
Governed MCP gateway: one endpoint for your tools, with credential custody and audit log.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceSecurity middleware for MCP servers. Trust-based access control, rate limiting, and audit logging. Zero dependencies.17 npmMIT
- AlicenseAqualityBmaintenanceEnables creation of secure-by-default MCP servers with 5-layer validation to protect against injection, path traversal, and other attack vectors.71,498 npm2MIT
- AlicenseNot gradedqualityDmaintenanceDrop-in OAuth 2.1 + Dynamic Client Registration for MCP servers, providing authentication middleware and token verification.14 npm1MIT
- AlicenseNot gradedqualityDmaintenanceEnables developers to scaffold secure-by-default MCP servers with deny-all permissions, typed tool stubs, and pre-wired audit hooks, while enforcing security posture through CI.3 npmMIT