Skip to main content

Automated testing framework for MCP (Model Context Protocol) servers

Project description

MCPSentinel

MCPSentinel

Zero-config testing for MCP servers.
Install. Point at your server. Get a full test report.

PyPI Python License


Get Started

pip install mcp-sentinel
mcpsentinel "python my_server.py"

That's it. No config file. No test code to write. MCPSentinel connects to your server, discovers every tool, generates hundreds of test cases, and prints the results:

MCPSentinel v0.1.0

  Server:     python my_server.py
  Transport:  stdio (auto-detected)
  Modes:      schema, fuzz
  Output:     terminal

Discovering tools...  3 tools found

Running 47 tests ━━━━━━━━━━━━━━━━━━━━━━ 100%

Results: 44 passed, 3 failed, 0 errors

What It Tests

MCPSentinel runs two test modes by default:

Schema validation — sends valid inputs, omits required fields one at a time, tests enum boundaries, type mismatches.

Adversarial fuzzing — SQL injection, XSS, path traversal, command injection, null bytes, format strings, oversized payloads, unicode stress tests. Every fuzz test expects the server to not crash — returning an error is fine.


Common Usage

# Test your server (zero config)
mcpsentinel "python my_server.py"

# Schema tests only
mcpsentinel "python server.py" -m schema

# HTML report
mcpsentinel "python server.py" -f html

# SSE server (transport auto-detected from URL)
mcpsentinel "http://localhost:8001/sse"

# Streamable HTTP
mcpsentinel "http://localhost:8001/mcp"

# Test specific tools
mcpsentinel "python server.py" --tools "search_*"

# Exclude admin tools
mcpsentinel "python server.py" --exclude "admin_*"

# Reproducible fuzz run
mcpsentinel "python server.py" --fuzz-seed 42

# Docker container
mcpsentinel "docker exec -i my-container python -m my_mcp_server"

# Re-run only previously failed tests
mcpsentinel "python server.py" --retry-failed

# Watch mode — re-run on file changes
mcpsentinel "python server.py" --watch

# Multiple report formats
mcpsentinel "python server.py" -f terminal -f json -f html -f junit

# CI-friendly: quiet mode + JUnit output
mcpsentinel "python server.py" -q -f junit -o ./test-results

mcpsentinel run "..." still works — run is the default subcommand and can be omitted.


Other Commands

# Discover tools on a server
mcpsentinel discover "python my_server.py"

# Generate a config file (optional)
mcpsentinel init

Options

Option Short Default Description
--transport -t auto Transport: stdio, sse, or streamable-http
--mode -m schema,fuzz Test modes: schema, fuzz
--config -c Path to mcpsentinel.toml
--format -f terminal Output: terminal, json, html, junit
--output-dir -o ./reports Report output directory
--tools Glob pattern to include tools
--exclude Glob pattern to exclude tools
--fuzz-seed Seed for reproducible fuzz tests
--timeout 30 Timeout per tool call (seconds)
--concurrency 1 Parallel test executions
--rate-limit 0 Min delay between calls (ms)
--retry-failed Re-run only previously failed tests
--watch -w Watch for file changes and re-run
--watch-path . Directory to watch
--verbose -v Show all call logs in real-time
--quiet -q Suppress terminal output

Configuration (Optional)

MCPSentinel works without any config. If you want persistent settings:

mcpsentinel init

Creates mcpsentinel.toml — auto-discovered when present:

[server]
command = "python"
args = ["my_server.py"]
transport = "stdio"
startup_timeout = 30

[modes]
schema = true
fuzz = true

[fuzz]
seed = 42

[execution]
timeout_per_tool = 30
# tools = "search_*"
# exclude = "internal_*"

[reporting]
formats = ["terminal", "json"]
output_dir = "./reports"
verbose = false
quiet = false

CLI flags always override config file values.


Report Formats

Format Description
Terminal Rich colored output with summary tables and failure details
HTML Self-contained single-file report with dark/light theme, search, keyboard shortcuts
JSON Full machine-readable report with every test case, call log, and timing data
JUnit XML CI-compatible format for GitHub Actions, Jenkins, GitLab CI

CI/CD Integration

GitHub Actions

- name: Test MCP Server
  run: |
    pip install mcp-sentinel
    mcpsentinel "python my_server.py" -q -f junit -o ./test-results

- name: Publish Test Results
  uses: dorny/test-reporter@v1
  if: always()
  with:
    name: MCP Server Tests
    path: test-results/mcpsentinel-report-*.xml
    reporter: java-junit

Or use the MCPSentinel GitHub Action:

- uses: Dev07-Harsh/mcp-sentinel@main
  with:
    server-command: "python my_server.py"

Exit Codes

Code Meaning
0 All tests passed
1 One or more tests failed
2 Configuration error
3 No tools found on server

Test Modes

Schema Mode

Test Type What It Does
valid_minimal Sends only required parameters with valid types
valid_full Sends all parameters (required + optional)
defaults_only Sends only required params, omits optional
required_missing_* Omits each required parameter one at a time
enum_* Tests each declared enum value
boundary_* Tests min/max for numeric parameters

Fuzz Mode

Test Type What It Sends
type_mismatch Wrong types for every parameter
boundary_violation Values beyond declared min/max
null_injection null for every parameter
empty_value Empty strings, arrays, objects
invalid_enum Values outside declared enum sets
extra_fields Unexpected additional parameters
injection_* SQL, command, path traversal, XSS, format strings
encoding_* Unicode stress, newline/tab injection
overflow 100,000-character strings

Architecture

src/mcpsentinel/
├── cli/              # Typer CLI (run, discover, init)
├── client/           # MCP protocol client (stdio, SSE, streamable-http)
├── config/           # TOML + CLI config loading
├── discovery/        # Tool discovery and schema analysis
├── generation/       # Test case generators (schema + fuzz)
├── execution/        # Test runner and tool executor
├── evaluation/       # Result checkers (schema + fuzz)
├── reporting/        # Terminal, HTML, JSON, JUnit reporters
├── logging/          # Per-call trace recording
├── models/           # Pydantic data models
└── errors.py         # Error hierarchy

Extension Points

  • BaseGenerator — add new test generation strategies
  • BaseChecker — add new evaluation logic
  • BaseReporter — add new output formats

Installation

pip install mcp-sentinel

From source:

git clone https://github.com/Dev07-Harsh/mcp-sentinel.git
cd mcp-sentinel
pip install -e ".[dev]"

Requirements: Python 3.10+


Contributing

Contributions welcome. Open an issue or pull request on GitHub.

git clone https://github.com/Dev07-Harsh/mcp-sentinel.git
cd mcp-sentinel
pip install -e ".[dev]"
pytest tests/unit

Author

Harsh SinghGitHub

License

MIT License. See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcp_sentinel-0.1.0.tar.gz (66.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_sentinel-0.1.0-py3-none-any.whl (72.7 kB view details)

Uploaded Python 3

File details

Details for the file mcp_sentinel-0.1.0.tar.gz.

File metadata

  • Download URL: mcp_sentinel-0.1.0.tar.gz
  • Upload date:
  • Size: 66.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for mcp_sentinel-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a504e40f6e02e48003dd8fc78116300ef54da1e06807d44a8eb71fe75ca2b070
MD5 0d61aa95eaae4836892c7ba075647279
BLAKE2b-256 b68bb2684661e5d031ee0334f15e6fdf86c4ffe81c262abbf2118256f0b0168c

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_sentinel-0.1.0.tar.gz:

Publisher: publish.yml on Dev07-Harsh/mcp-sentinel

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mcp_sentinel-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: mcp_sentinel-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 72.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for mcp_sentinel-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 220b1e35075bacbef4dfe50719237e34b218df7db9c780e36667803324d80289
MD5 7faec564176932302c6594bc600cf79d
BLAKE2b-256 d19cdca116d82424c89977b870ea73e522a5efffdcb83849609c26a19d4d1786

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_sentinel-0.1.0-py3-none-any.whl:

Publisher: publish.yml on Dev07-Harsh/mcp-sentinel

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page