Skip to main content

mcp-server-shield

mcp-server-shield is a Python-first hardening library for MCP server authors. It is not a scanner, gateway, proxy, or hosted security service. It protects the MCP tool function boundary directly: validate arguments before execution, use safe wrappers for dangerous operations, filter outputs before they reach the MCP client, lint tool descriptions, lock tool manifests, and emit structured audit logs.

The project is built for the way FastMCP and the official Python MCP SDK expose tools: ordinary Python functions decorated as tools.

Install

pip install mcp-server-shield

For local development:

pip install -e ".[dev]"

Quickstart

from mcp_server_shield import ShieldPolicy, shield
from mcp_server_shield.output_filters import PromptInjectionFilter, SecretRedactor
from mcp_server_shield.validators import PathGuard, StringGuard, URLGuard

policy = ShieldPolicy.strict(
    paths={"file_path": PathGuard(root="./workspace", read=True, write=False)},
    urls={"url": URLGuard(allowed_schemes=["https"], allowed_hosts=["api.github.com"])},
    strings={
        "query": StringGuard(
            max_len=5000,
            deny_substrings=["ignore previous instructions"],
        )
    },
    output_filters=[SecretRedactor(), PromptInjectionFilter()],
)

@shield(policy)
def read_file(file_path: str) -> str:
    with open(file_path, encoding="utf-8") as handle:
        return handle.read()

FastMCP Example

Use @shield(policy) closest to the function so FastMCP sees the preserved signature and metadata after the wrapper is applied:

from fastmcp import FastMCP
from mcp_server_shield import ShieldPolicy, shield
from mcp_server_shield.validators import PathGuard

mcp = FastMCP("secure-files")

policy = ShieldPolicy.strict(
    paths={"file_path": PathGuard(root="./workspace", read=True, write=False)},
)

@mcp.tool()
@shield(policy)
def read_file(file_path: str) -> str:
    with open(file_path, encoding="utf-8") as handle:
        return handle.read()

Policy File Example

policy_id: secure-fetch-v1
fail_closed: true
audit_log: logs/mcp-shield-audit.jsonl
paths:
  file_path:
    root: ./workspace
    read: true
    write: false
    allowed_extensions: [".txt", ".md"]
urls:
  url:
    allowed_schemes: ["https"]
    allowed_hosts: ["api.github.com"]
    allow_localhost: false
    allow_private_ips: false
strings:
  query:
    max_len: 5000
    deny_substrings: ["ignore previous instructions"]
output_filters:
  - type: secret_redactor
    redact_pii: true
  - type: prompt_injection
    action: redact
waivers:
  - id: WAIVER-001
    reason: Temporary partner endpoint migration.
    expires_on: 2026-06-30
    applies_to: ["URLGuard:url"]
    evidence:
      ticket: SEC-1234

Load it with:

policy = ShieldPolicy.from_file("mcp-shield-policy.yaml")

CLI

Lint tool descriptions:

mcp-shield lint-descriptions tools.json --json

Generate and verify a descriptor lockfile:

mcp-shield manifest generate tools.json --output mcp-shield.lock.json
mcp-shield manifest verify tools.json --lockfile mcp-shield.lock.json

Validate a policy file:

mcp-shield policy check mcp-shield-policy.yaml

Check the local installation:

mcp-shield doctor

Threat Model

mcp-server-shield assumes MCP tool arguments, external URLs, filesystem paths, command arguments, tool descriptions, and tool outputs may be attacker influenced. It focuses on deterministic local controls for:

  • Secret exposure and context over-sharing through output redaction.
  • Command and argument injection through safe_run.
  • Path traversal and symlink escape through PathGuard.
  • SSRF, localhost access, and DNS rebinding risk through URLGuard.
  • Tool poisoning through description linting and manifest locking.
  • Audit gaps through JSONL audit events for allowed, denied, redacted, and errored calls.

What This Library Does Not Solve

This library does not replace authentication, authorization, sandboxing, container policy, dependency scanning, supply-chain review, network egress policy, or a full MCP gateway. It does not claim to detect every prompt-injection phrase or every possible secret format. It does not make unsafe business logic safe by itself. It gives MCP server authors reusable secure-by-default primitives at the point where tool code handles untrusted data.

Release files for mcp-server-shield 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mcp-server-shield 0.1.0
File Size Uploaded
mcp_server_shield-0.1.0.tar.gz 31.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mcp-server-shield 0.1.0
File Interpreter ABI Platform
mcp_server_shield-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 60.6 kB

Release files / mcp_server_shield-0.1.0.tar.gz

Download URL mcp_server_shield-0.1.0.tar.gz
Size 31.5 kB
Tags Source
SHA-256 checksum
How to use checksums
8e7c738e572c36abf1b73360972bd96bda2becd117b17a9c42c690661427651e
BLAKE2b-256 checksum
How to use checksums
7102f783008b227f47afcea39216b95534423d8d5c14a4cc17d32a7b72557c30
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 25, 2026.

Transparency log

Release files / mcp_server_shield-0.1.0-py3-none-any.whl

Download URL mcp_server_shield-0.1.0-py3-none-any.whl
Size 29.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
90f2705cf52282eb6dc4fb8a8ab204d4c0cbc079e3a3a5927dfc27a626e7a902
BLAKE2b-256 checksum
How to use checksums
b039a6fa86d7c1736caa3e2d096b085e90621acc04f5fc897568f9ac7d43c63f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page