mcpField
G
Gauntlet

Gauntlet

Local
crates.ioDeveloper Tools0Updated 1w ago

About Gauntlet

Gauntlet is a Rust toolkit for developers testing MCP server security and reliability before deployment. Its two CLIs provide schema-driven fuzzing and concurrent load tests, with outputs suited to CI.

Key features

  1. 01Schema-aware input fuzzing
  2. 02SARIF findings output
  3. 03Concurrent MCP load testing
  4. 04Per-tool latency and throughput metrics
  5. 05CI thresholds for latency and errors
  6. 06stdio and Streamable HTTP transports

Use cases

  1. 01Find crashes and validation gaps before release
  2. 02Upload security findings to GitHub code scanning
  3. 03Check latency and error budgets in CI

MCP support

The shared async MCP client connects to servers over stdio or Streamable HTTP. mcp-fuzz discovers tools and schemas through MCP, while mcp-storm sends concurrent requests.

Configuration

Local server config is the same for every client. Copy it into your client’s MCP config file.

No install method listed yet

We haven’t collected a package or remote endpoint for this server. Follow the instructions in the project README.

Repository

Tools

No tool list yet

Local servers expose tools only once running on your machine, and the maintainer has not provided a tool list.

Details

From the project README

Part of the StudioMeyer MCP Stack — Built in Mallorca 🌴 · ⭐ if you use it

mcp-gauntlet

mcp-fuzz mcp-storm CI OpenSSF Scorecard License: MIT

A reliability + security toolkit for Model Context Protocol servers. Two single-binary CLIs that share one fast async MCP client core:

ToolWhat it does
🔬 mcp-fuzzSchema-aware fuzzer. Reads each tool's inputSchema and throws a battery of hostile/boundary/malformed payloads at it — finds crashes, hangs, internal errors and silent validation gaps. Emits SARIF for GitHub code scanning.
🌩️ mcp-stormLoad tester ("k6 for MCP"). Drives N concurrent workers against your server, reports p50/p95/p99 latency + throughput per tool, and gates CI on latency/error-rate thresholds.

Both are written in Rust: one static binary each, no runtime, drop into any CI. They talk MCP over stdio (subprocess) or Streamable HTTP.

Built by StudioMeyer. Companion to mcp-armor (runtime defense) — mcp-gauntlet is the pre-deploy attacker + load generator.


Why

MCP servers fail silently and ship fast. Most have no tests against malformed input and no latency budget. mcp-gauntlet gives you both in two commands you can wire into CI today — without writing a single test by hand, because the payloads are derived from the server's own schema.


Install

# from crates.io
cargo install mcp-fuzz mcp-storm

# or from source
git clone https://github.com/studiomeyer-io/mcp-gauntlet
cd mcp-gauntlet && cargo build --release
# binaries in target/release/{mcp-fuzz,mcp-storm}

MSRV: Rust 1.86.


mcp-fuzz — find crashes before your users do

# fuzz a stdio server (everything after -- is the launch command)
mcp-fuzz run --stdio -- node my-server.js

# fuzz a remote HTTP endpoint, write SARIF for GitHub code scanning
mcp-fuzz run --http https://example.com/mcp --sarif findings.sarif

# only one tool, more payloads, fail CI on any HIGH finding
mcp-fuzz run --stdio --tool search --iterations 300 --fail-on high -- ./server

It connects, calls tools/list, and for every tool generates payloads driven by the schema:

  • type confusion (string where a number is required, …)
  • boundary (empty / 100k-char strings, i64::MAX, negatives, zero, huge floats)
  • injection (path traversal, SQLi, command/template/format-string, prompt injection, CRLF, NUL bytes, RTL/zero-width Unicode) — sent purely as data, never executed
  • missing required fields, wrong-typed arguments, deep nesting

Outcomes are classified: a dropped connection ⇒ crash (HIGH), a timeout ⇒ hang (HIGH), -32603 ⇒ internal-error (MEDIUM), success on schema-invalid input ⇒ accepted-invalid (LOW). A clean -32602 invalid params is treated as the server correctly validating — not a finding.

Runs are reproducible (--seed). After a crash the fuzzer respawns the server and continues; if the server can't be brought back, it records that once and stops cleanly, rather than blaming every later payload for the original crash.

mcp-fuzz report
───────────────
server         my-server (protocol 2025-11-25)
tools          7
payloads sent  412
findings       2 total — 1 high, 0 medium, 1 low, 0 info

Findings (worst first):
  [HIGH  ] crash            search::server crashed on field 'query': null-byte
           stderr tail:
           thread 'main' panicked at 'invalid utf-8 ...'
  [LOW   ] accepted-invalid search::schema-invalid input accepted without error: missing required field 'query'
In CI (GitHub code scanning)
- run: mcp-fuzz run --stdio --sarif mcp.sarif --fail-on high -- node server.js
- uses: github/codeql-action/upload-sarif@v3
  if: always()
  with: { sarif_file: mcp.sarif }

mcp-storm — know your latency budget

# 16 workers for 30s against a stdio server
mcp-storm run --stdio --concurrency 16 --duration-secs 30 -- node my-server.js

# fixed request count against HTTP, gate CI on p95 + error rate
mcp-storm run --http https://example.com/mcp --requests 5000 \
  --threshold-p95-ms 250 --max-error-rate 1.0
mcp-storm report
────────────────
server       my-server (protocol 2025-11-25)
workers      16
duration     30.00s
requests     48213 (3 errors, 0.01% error rate)
throughput   1607 req/s

tool                    calls    err%     p50ms     p95ms     p99ms     maxms      req/s
──────────────────────────────────────────────────────────────────────────────────────
search                  31044   0.01%      6.20     14.80     31.10    102.40       1035
fetch                   17169   0.00%      9.10     22.30     58.70    210.00        572

Over stdio, concurrency is real: requests are multiplexed over the single pipe and demultiplexed by JSON-RPC id, so N workers genuinely overlap. --threshold-p95-ms / --max-error-rate make it exit non-zero when a budget is blown — drop it straight into a CI gate. Use --warmup-secs to exclude cold-start.


Workspace layout

mcp-gauntlet/
├── crates/mcp-gauntlet-core   # shared async MCP client (stdio + HTTP), schema gen, mock server
├── crates/mcp-fuzz         # the fuzzer CLI
└── crates/mcp-storm        # the load tester CLI

mcp-gauntlet-core is published too — it's a small, concurrency-capable MCP client you can use on its own, with a schema-driven value/mutation generator and an in-process mock server (mcp-fuzz mock / mcp-storm mock) you can point either tool at to try them with zero setup:

mcp-fuzz run --stdio -- mcp-fuzz mock     # fuzz the bundled demo server

Development

cargo fmt --all
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-features

Part of the StudioMeyer MCP toolkit

A small family of focused, production-grade tools for building and operating MCP servers — mix and match:

  • mcp-armor — runtime defense sidecar: scans tool calls, verifies signed manifests, blocks known-bad CVEs
  • mcp-gauntlet (this one) — pre-deploy mcp-fuzz (schema-aware fuzzer) + mcp-storm (load tester)
  • mcp-covenant — contract & breaking-change detector (semver for your MCP interface)
  • mcp-herald — static migration linter for the MCP 2026-07-28 spec
  • mcp-passport — publish-readiness validator for the MCP Registry
  • mcp-otel — W3C Trace Context → OpenTelemetry bridge
  • mcp-cache-kit — leak-safe SEP-2549 caching (ttlMs + cacheScope)
  • skilldoctor — linter + security scanner for agent skill files

License

MIT © StudioMeyer. See LICENSE.

Comments

Markdown supported

New to MCP?

From what the protocol is to installing your first server, these answers cover most first questions.

An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.