MCP server fuzzer client and utilities
Project description
MCP Fuzzer
A comprehensive CLI tool for fuzzing MCP servers using multiple transport protocols, with support for both tool argument fuzzing and protocol type fuzzing. Features pretty output using rich.
The most important thing I'm aiming to ensure here is: If your server conforms to the 2024-11-05 MCP schema, this tool will be able to fuzz it effectively.
Features
Tool Fuzzer (Original)
- Multi-Protocol Support: HTTP, SSE, Stdio, and WebSocket transports
- Tool Discovery: Automatically discovers available tools from MCP servers
- Intelligent Fuzzing: Uses Hypothesis to generate random/edge-case arguments
- Rich Reporting: Beautiful terminal tables with detailed statistics
- Protocol Flexibility: Easy to add new transport protocols
- Comprehensive Protocol Coverage: Fuzzes all MCP protocol types
- Edge Case Generation: Tests malformed requests, invalid parameters, and boundary conditions
- Protocol-Specific Strategies: Tailored fuzzing for each MCP message type
- State-Aware Testing: Tests protocol flow and state transitions
- Security Testing: Path traversal, injection attacks, and malformed data
Architecture
The MCP Fuzzer uses a modular architecture with clear separation of concerns:
Core Components
client.py: Unified client that orchestrates both tool and protocol fuzzingtransport.py: Abstract transport layer supporting HTTP, SSE, Stdio, WebSocket, and custom protocolsfuzzer/: Orchestration logic for different fuzzing typestool_fuzzer.py: Tool argument fuzzing orchestrationprotocol_fuzzer.py: Protocol type fuzzing orchestration
strategy/: Hypothesis-based data generation strategiestool_strategies.py: Strategies for generating tool argumentsprotocol_strategies.py: Strategies for generating protocol messages
Architecture Flow
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Client CLI │───▶│ Transport │───▶│ MCP Server │
│ (__main__.py) │ │ Layer │ │ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ Fuzzer │ │ Strategy │
│ Orchestration │ │ Data Gen │
│ (fuzzer/) │ │ (strategy/) │
└─────────────────┘ └─────────────────┘
Key Benefits
- Modular Design: Clear separation between orchestration and data generation
- Transport Agnostic: Fuzzer logic independent of communication protocol
- Extensible: Easy to add new transport protocols and fuzzing strategies
- Testable: Each component can be tested independently
Installation
pip install mcp-fuzzer
Usage
Tool Fuzzer (Original Functionality)
Fuzz tool arguments and parameters:
# Basic tool fuzzing
mcp-fuzzer --mode tools --protocol http --endpoint http://localhost:8000/mcp/ --runs 10
# With verbose output
mcp-fuzzer --mode tools --protocol http --endpoint http://localhost:8000/mcp/ --verbose
Protocol Fuzzer (New Functionality)
Fuzz MCP protocol types and messages:
# Fuzz all protocol types
mcp-fuzzer --mode protocol --protocol http --endpoint http://localhost:8000/mcp/ --runs-per-type 5
# Fuzz specific protocol type
mcp-fuzzer --mode protocol --protocol-type InitializeRequest --protocol http --endpoint http://localhost:8000/mcp/
# Fuzz with verbose output
mcp-fuzzer --mode protocol --protocol http --endpoint http://localhost:8000/mcp/ --verbose
Supported Protocol Types
The protocol fuzzer covers all major MCP protocol types:
Core Protocol
- InitializeRequest: Tests protocol version handling, client info, and capabilities
- ProgressNotification: Tests progress tokens, negative progress, and malformed notifications
- CancelNotification: Tests cancellation of unknown/completed requests
Resource Management
- ListResourcesRequest: Tests pagination cursors and edge cases
- ReadResourceRequest: Tests URI parsing, path traversal, and malformed URIs
- SubscribeRequest: Tests resource subscription with invalid URIs
- UnsubscribeRequest: Tests resource unsubscription edge cases
Logging & Configuration
- SetLevelRequest: Tests invalid logging levels and boundary conditions
LLM & Sampling
- CreateMessageRequest: Tests large prompts, invalid tokens, and malformed messages
- SamplingMessage: Tests message content and role validation
Prompt Management
- ListPromptsRequest: Tests prompt listing pagination
- GetPromptRequest: Tests prompt retrieval with invalid names
Root Management
- ListRootsRequest: Tests root listing functionality
Completion
- CompleteRequest: Tests completion with invalid references and arguments
Generic JSON-RPC
- GenericJSONRPCRequest: Tests malformed JSON-RPC messages, missing fields, and invalid versions
Custom Transport Protocols
The MCP Fuzzer uses a transport abstraction layer that makes it easy to implement custom transport protocols. You can create your own transport by inheriting from TransportProtocol:
Creating Custom Transports
from mcp_fuzzer.transport import TransportProtocol
class YourCustomTransport(TransportProtocol):
def __init__(self, your_config):
# Your initialization
pass
async def send_request(self, method: str, params=None) -> Any:
# Your custom implementation
return your_response
Example Custom Transports
The project includes examples of custom transport implementations:
- gRPC Transport: High-performance RPC communication
- Redis Transport: Pub/sub messaging via Redis
- Webhook Transport: HTTP webhook-based communication
See examples/custom_transport_example.py for complete implementation examples.
Integration Options
Option 1: Extend the factory function
def create_custom_transport(protocol, endpoint, **kwargs):
if protocol == "your-protocol":
return YourCustomTransport(endpoint, **kwargs)
else:
return create_transport(protocol, endpoint, **kwargs)
Option 2: Direct usage
from your_module import YourCustomTransport
transport = YourCustomTransport("your-endpoint")
client = UnifiedMCPFuzzerClient(transport)
Benefits of Custom Transports
- ✅ Plug-and-play: Just implement the interface
- ✅ Zero fuzzer changes: Fuzzer doesn't know about transport
- ✅ Protocol agnostic: Works with any transport
- ✅ Easy testing: Mock transports for testing
Supported Protocols
mcp-fuzzer --mode tools --protocol http --endpoint http://localhost:8080/rpc --runs 20
mcp-fuzzer --mode protocol --protocol http --endpoint http://localhost:8080/rpc --runs-per-type 10
SSE Transport
mcp-fuzzer --mode tools --protocol sse --endpoint http://localhost:8080/sse --runs 15
mcp-fuzzer --mode protocol --protocol sse --endpoint http://localhost:8080/sse --runs-per-type 8
Stdio Transport
# Binary executables
mcp-fuzzer --mode tools --protocol stdio --endpoint "./bin/mcp-shell" --runs 10
mcp-fuzzer --mode protocol --protocol stdio --endpoint "./bin/mcp-shell" --runs-per-type 5
# Python scripts
mcp-fuzzer --mode tools --protocol stdio --endpoint "python3 ./my-mcp-server.py" --runs 10
mcp-fuzzer --mode protocol --protocol stdio --endpoint "python3 ./my-mcp-server.py" --runs-per-type 5
WebSocket Transport
mcp-fuzzer --mode tools --protocol websocket --endpoint ws://localhost:8080/ws --runs 25
mcp-fuzzer --mode protocol --protocol websocket --endpoint ws://localhost:8080/ws --runs-per-type 12
Arguments
Common Arguments
--mode: Fuzzing mode (toolsorprotocol, default:tools)--protocol: Transport protocol to use (http, sse, stdio, websocket)--endpoint: Server endpoint (URL for http/sse/websocket, command for stdio)--timeout: Request timeout in seconds (default: 30.0)--verbose: Enable verbose logging
Tool Fuzzer Arguments
--runs: Number of fuzzing runs per tool (default: 10)
Protocol Fuzzer Arguments
--runs-per-type: Number of fuzzing runs per protocol type (default: 5)--protocol-type: Fuzz only a specific protocol type (optional)
Output
Results are shown in colorized tables with detailed statistics:
Tool Fuzzer Output
- Success Rate: Percentage of successful tool calls
- Exception Count: Number of exceptions during fuzzing
- Example Exceptions: Sample error messages for debugging
- Overall Statistics: Summary across all tools and protocols
Protocol Fuzzer Output
- Protocol Type: The specific MCP protocol type being tested
- Total Runs: Number of fuzz attempts for this protocol type
- Successful: Number of successful protocol interactions
- Exceptions: Number of exceptions or errors encountered
- Success Rate: Percentage of successful protocol interactions
- Example Exception: Sample error messages for debugging
Edge Cases Tested
The protocol fuzzer generates comprehensive edge cases including:
InitializeRequest
- Invalid protocol versions
- Malformed client info
- Invalid capabilities structures
- Empty or missing fields
ProgressNotification
- Negative progress values
- Invalid progress tokens
- Missing required fields
- Malformed progress structures
ReadResourceRequest
- Path traversal attempts (
../../../etc/passwd) - Invalid URI schemes
- Extremely long URIs
- Unicode and special characters in paths
- Data URIs with malformed content
SetLevelRequest
- Invalid logging levels
- Numeric and boolean values instead of strings
- Empty or malformed level strings
- Boundary testing of log systems
Generic JSON-RPC
- Missing
jsonrpcfield - Invalid JSON-RPC versions
- Missing request IDs
- Deeply nested parameters
- Malformed JSON-RPC structures
Examples
Testing a Simple MCP Server
# Start your MCP server
python my-mcp-server.py
# In another terminal, fuzz the tools
mcp-fuzzer --mode tools --protocol http --endpoint http://localhost:8000/mcp/ --runs 20
# Fuzz the protocol types
mcp-fuzzer --mode protocol --protocol http --endpoint http://localhost:8000/mcp/ --runs-per-type 10
Testing Specific Protocol Vulnerabilities
# Test initialization edge cases
mcp-fuzzer --mode protocol --protocol-type InitializeRequest --protocol http --endpoint http://localhost:8000/mcp/ --runs-per-type 20
# Test resource reading with path traversal
mcp-fuzzer --mode protocol --protocol-type ReadResourceRequest --protocol http --endpoint http://localhost:8000/mcp/ --runs-per-type 15
# Test logging level boundary conditions
mcp-fuzzer --mode protocol --protocol-type SetLevelRequest --protocol http --endpoint http://localhost:8000/mcp/ --runs-per-type 10
Development
Running Tests
# Test the protocol fuzzer
python examples/test_protocol_fuzzer.py
# Test custom transport examples
python examples/custom_transport_example.py
# Run the full test suite
python -m pytest tests/
Adding New Protocol Types
To add fuzzing for a new MCP protocol type:
- Add a new method to
ProtocolStrategiesinstrategy/protocol_strategies.py - Add the protocol type to the mapping in
ProtocolStrategies.get_protocol_fuzzer_method() - Add the send method in
client.py(in the_send_protocol_requestmethod) - Update the protocol types list in
ProtocolFuzzer.fuzz_all_protocol_types()
Adding New Transport Protocols
To add a new transport protocol:
- Create a new class inheriting from
TransportProtocolintransport.py - Implement the
send_request()method - Add the protocol to the
create_transport()factory function - Update the CLI argument parser in
__main__.pyif needed
Project dependencies are managed via pyproject.toml.
Example response from a server using examples/test_server.py -> It's easy to break man if schema validation is not there in the implementation, it might be easy to crash some servers.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcp_fuzzer-0.1.4.tar.gz.
File metadata
- Download URL: mcp_fuzzer-0.1.4.tar.gz
- Upload date:
- Size: 23.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.9.23
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
50b1754d95ef4c57e6c436f8ad2183b2ae0f1e58961e50be19d9b58b874ada95
|
|
| MD5 |
6fa0c129d195de19f68a2d3f3f81ccd6
|
|
| BLAKE2b-256 |
9f1a17c4e34892c035e9429696d6fe2da43c3f2f002c67690435d66af9bab4da
|
File details
Details for the file mcp_fuzzer-0.1.4-py3-none-any.whl.
File metadata
- Download URL: mcp_fuzzer-0.1.4-py3-none-any.whl
- Upload date:
- Size: 24.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.9.23
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f08da563ff91bc98c7bb65ca5e2fdc98715b430c61f19830ccbbb6e85ee3b79a
|
|
| MD5 |
7f7a3354e30422879dc6ccd8f554a972
|
|
| BLAKE2b-256 |
ad1ad305348147f167787b258eb311e4c79c20a40c582589cdd9905d92d33584
|