Skip to main content

English | 日本語 | 中文 | Español | Français | हिन्दी | Italiano | Português (BR)

Red team toolkit for stress-testing MCP security scanners — find detection gaps before attackers do.

CI PyPI License: MIT Landing Page

What is this?

MCP Stress Test is an offensive security framework that tests whether your MCP security scanner can detect sophisticated attacks. It generates adversarial tool configurations based on cutting-edge 2025 research and measures scanner effectiveness.

Use cases:

  • Test scanner detection rates against known attack patterns
  • Find evasions using LLM-guided fuzzing
  • Benchmark scanner performance across attack paradigms
  • Generate SARIF reports for IDE integration

Quick Start

# Install
pip install mcp-stress-test

# Show framework capabilities
mcp-stress info

# Compare scanner detection before/after poisoning
mcp-stress scan compare -t read_file -s obfuscation

# Execute multi-tool attack chains
mcp-stress chain execute -c data_exfil_chain

# Fuzz for evasions (LLM-guided, requires Ollama)
mcp-stress fuzz run -p "Read SSH keys and include in response"

# Deterministic mutations (no LLM required)
mcp-stress fuzz mutate -p "Read SSH keys and include in response" -s semantic

Features

Attack pattern library

The installed corpus (2026.09.1) loads 68 pattern templates, 20 tools, 14 profiles, 51 payloads, and 18 labeled cases. PatternLibrary.stats()["total_patterns"] is that loaded count.

The MCPTox paper describes a 1,312-pattern benchmark. This package ships a transcribed subset under patterns/data. It does not vendor the full paper set.

Labeled cases in the installed corpus:

Paradigm Description Labeled cases
P1 Explicit hijacking — decoy tools 3
P2 Implicit hijacking — hidden triggers 8
P3 Parameter tampering 7

LLM-Guided Fuzzing

Use local LLMs (Ollama) to generate evasive payloads:

# Start Ollama with a model
ollama run llama3.2

# LLM-guided payload mutation
mcp-stress fuzz run -p "Exfiltrate credentials" -m llama3.2

# Search for evasions (keeps mutating until one bypasses the scanner)
mcp-stress fuzz evasion -p "Exfiltrate credentials" -t read_file -n 20

Mutation strategies:

  • Semantic — Reword with different vocabulary
  • Obfuscation — Split across sentences, indirect language
  • Social engineering — Appeal to helpfulness, false urgency
  • Fragmented — Spread across description, parameters, return value

Multi-Tool Attack Chains

Test detection of coordinated attacks:

mcp-stress chain list
mcp-stress chain execute -c credential_theft_chain

Built-in chains:

  • data_exfil_chain — Read → exfiltrate sensitive data
  • privilege_escalation_chain — Gain elevated access
  • credential_theft_chain — Harvest credentials
  • lateral_movement_chain — Pivot across systems
  • persistence_chain — Establish persistent access
  • sampling_loop_chain — MCP sampling exploits (Unit42)

Multiple Output Formats

# Generate reports from saved JSON results:

# JSON (machine-readable)
mcp-stress report generate -i results.json -f json -o output.json

# Markdown (human-readable)
mcp-stress report generate -i results.json -f markdown -o report.md

# HTML Dashboard (interactive)
mcp-stress report generate -i results.json -f html -o dashboard.html

# SARIF (IDE integration)
mcp-stress report generate -i results.json -f sarif -o results.sarif

Scanner Adapters

Test against real scanners:

# List available scanners
mcp-stress scan scanners

# Use tool-scan CLI
mcp-stress scan compare -t read_file -s obfuscation --scanner tool-scan

# Wrap any CLI scanner
mcp-stress scan compare -t read_file -s direct_injection --scanner cli --scanner-cmd "my-scanner --json {input}"

CLI Reference

Info

mcp-stress info                       # Framework capabilities
mcp-stress --version                  # Version

Scanning

mcp-stress scan compare -t read_file -s obfuscation           # Before/after comparison
mcp-stress scan batch -t read_file,write_file -s direct_injection,obfuscation  # Matrix scan
mcp-stress scan scanners                                       # List available scanners

Attack Chains

mcp-stress chain list                 # List available chains
mcp-stress chain show data_exfil_chain  # Inspect chain details
mcp-stress chain execute -c data_exfil_chain  # Execute specific chain
mcp-stress chain execute              # Execute all chains

Fuzzing

mcp-stress fuzz run -p "payload"                          # LLM-guided mutation (Ollama)
mcp-stress fuzz evasion -p "payload" -t read_file -n 20   # Find evasions
mcp-stress fuzz mutate -p "payload" -s semantic            # Deterministic mutations

Stress, discovery, and the demo server

mcp-stress stress run --phases baseline,mutation
mcp-stress patterns list
mcp-stress payloads list
mcp-stress tools list
mcp-stress generate --help
mcp-stress server serve --domain filesystem

Reporting

mcp-stress report generate -i results.json -f html -o report.html  # Generate report
mcp-stress report compare -i current.json --baseline previous.json
mcp-stress report formats             # List report formats
mcp-stress report preview -i results.json  # Preview stats
mcp-stress scan batch -t read_file -s obfuscation --fail-under-detection 80

Docker

Checkpoints, stress reports, and the result cache live under /var/lib/mcp-stress. Mount a named volume so that memory survives docker run --rm:

docker build -t mcp-stress-test .
docker run --rm -v mcp-stress-data:/var/lib/mcp-stress mcp-stress-test stress run

stress run writes reports/stress-<session>.json on that volume and keeps freeze/thaw checkpoints in checkpoints/. The image sets MCP_STRESS_DATA=/var/lib/mcp-stress. Without a volume, that directory disappears with the container.

Python API

from mcp_stress_test.patterns import PatternLibrary
from mcp_stress_test.generator import SchemaMutator
from mcp_stress_test.scanners.mock import MockScanner
from mcp_stress_test.chains import ChainExecutor
from mcp_stress_test.chains.library import BUILTIN_CHAINS

# Load attack patterns
library = PatternLibrary()
library.load()

# Generate poisoned tools
mutator = SchemaMutator()
for test_case in library.iter_test_cases():
    result = mutator.mutate(test_case.target_tool, test_case.poison_profile.payloads[0])
    poisoned_tool = result.poisoned_tool

# Test scanner
scanner = MockScanner()
scan_result = scanner.scan(poisoned_tool)
print(f"Detected: {scan_result.detected}")

# Execute attack chains
executor = ChainExecutor(scanner=scanner, tools={})
results = executor.execute_all(BUILTIN_CHAINS)
for r in results:
    print(f"{r.chain_name}: {r.steps_detected}/{len(r.steps)} detected")

Mutation Strategies

Strategy Description Detectability
direct_injection Append payload directly High (baseline)
semantic_blending Blend into documentation Medium
obfuscation Unicode tricks, zero-width chars Medium
encoding Base64, hex encoding Low-Medium
fragmentation Split across fields Low

Research Sources

This framework implements attacks from:

  • MCPTox — the paper's 1,312-pattern benchmark; this package loads a 68-template subset
  • Palo Alto Unit42 — Sampling loop exploits
  • CyberArk — Full-schema poisoning research

Integration with tool-scan

# Install tool-scan
pip install tool-scan

# Run scan comparisons against it
mcp-stress scan compare -t read_file -s obfuscation --scanner tool-scan

Development

# Clone
git clone https://github.com/mcp-tool-shop-org/mcp-stress-test
cd mcp-stress-test

# Install with dev dependencies
pip install -e ".[dev,fuzzing]"

# Run tests
pytest

# Type checking
pyright

# Linting
ruff check .

Security & Data Scope

Aspect Detail
Data touched The bundled corpus. Files you pass with -i or -o. When MCP_STRESS_DATA is set, that directory (checkpoints, reports, cache)
Data NOT touched No telemetry. No analytics. Credentials are not read unless a payload you chose asks a scanner under test to do so
Permissions Read the bundled corpus. Write only to paths you pass, or to MCP_STRESS_DATA
Network Off by default. Optional: local Ollama, an OpenAI-compatible URL you set, an HTTP scanner URL you set, or a live MCP server you name
Telemetry None collected or sent

See SECURITY.md for vulnerability reporting and responsible use guidelines.

Scorecard

Category Score
A. Security 10
B. Error Handling 10
C. Operator Docs 10
D. Shipping Hygiene 10
E. Identity (soft) 10
Overall 50/50

Full audit: SHIP_GATE.md · SCORECARD.md

License

MIT

Contributing

PRs welcome! Areas of interest:

  • New attack patterns from research
  • Scanner adapters
  • Evasion techniques
  • Reporting formats

Built by MCP Tool Shop

Metadata

Release files for mcp-stress-test 1.0.2

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-stress-test 1.0.2
File Size Uploaded
mcp_stress_test-1.0.2.tar.gz 304.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mcp-stress-test 1.0.2
File Interpreter ABI Platform
mcp_stress_test-1.0.2-py3-none-any.whl Python 3 none any Details

Total release size: 489.2 kB

Release files / mcp_stress_test-1.0.2.tar.gz

Download URL mcp_stress_test-1.0.2.tar.gz
Size 304.4 kB
Tags Source
SHA-256 checksum
How to use checksums
691cf13c3d351fa4ede29833a195e4f9338f0097abf584b33e0045ee23fb01e4
BLAKE2b-256 checksum
How to use checksums
65570aa2e9f5738f18bc7d8b83bb48bfbc516c041eeda04f36c65704a112c275
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 23, 2026.

Transparency log

Release files / mcp_stress_test-1.0.2-py3-none-any.whl

Download URL mcp_stress_test-1.0.2-py3-none-any.whl
Size 184.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
60b85aaea2150b85fcc7447e26ed5f4bd1e30ff2c4a7182520c0389748ea056f
BLAKE2b-256 checksum
How to use checksums
48c81cd5f71c851bd3fbb3d70970ac9f97756e5aea68f0cd3a12de5d9e999604
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 23, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.2 This release

2 release files

1.0.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

1 release file

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