🚧 Experimental - Not Recommended for Production Use
This package is currently in experimental mode and may contain bugs, breaking changes, or incomplete features. Use at your own risk in development and testing environments only.
A collection of MCP middleware plugins based on FastMCP to add features like observability, error handling, guardrails, allowlists, and human-in-the-loop etc. for your MCP. Can be called from python code or through a cli proxy on top of MCP.
pip install mcp-plugins
from fastmcp import FastMCP
from mcp_plugins import ToolLoggingMiddleware
MCP_CONFIG = {
"hackernews": {
"command": "uvx",
"args": ["mcp-hn"],
"transport": "stdio"
},
"every": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-everything"],
"transport": "stdio"
}
}
server = FastMCP.as_proxy(MCP_CONFIG, name="MCP-HN with Tool Logging")
server.add_middleware(
ToolLoggingMiddleware(
log_tool_metadata=True,
log_arguments=True,
log_results=True,
include_timestamps=True,
max_log_length=1000,
)
)
server.run(transport="streamable-http", host="0.0.0.0", port=9000)
mcp-plugins run config.json --transport streamable-http --host 0.0.0.0 --port 9000
config.json
{
"mcpServers": {
"hackernews": {
"command": "uvx",
"args": ["mcp-hn"],
"transport": "stdio"
},
"every": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-everything"],
"transport": "stdio"
}
},
"plugins": [
{
"type": "tool_logging",
"config": {
"enabled": true,
"log_tool_metadata": true,
"log_arguments": true,
"log_results": true,
"include_timestamps": true,
"max_log_length": 1000,
"log_format": "human"
}
}
]
}
This package provides both custom middleware plugins and integrates with FastMCP's built-in middleware system. Each middleware has its own detailed documentation:
⚠️ Important Caveat: When multiple MCP servers are joined together, the tool names to be allowed or denied would be in the format"<server_name>_<tool_name>"
. For example, if you have a server named "weather" with a tool "get_forecast", you would reference it as "weather_get_forecast" in your allowlist or denylist configuration. You may use MCP inspector to check the exact tool names.
- SimpleLoggingMiddleware - Basic logging for all MCP operations
- ToolLoggingMiddleware - Advanced tool execution tracking with JSON/human formats
- HumanApprovalMiddleware - Human approval for tool execution with HTML dashboard
- DebugMiddleware - Raw JSON-RPC context inspection for protocol-level debugging
- Tool Access Control Overview - Overview of all tool access control middleware
- ToolAllowlistMiddleware - Simple allowlist-based access control
- ToolDenylistMiddleware - Simple denylist-based access control
- ToolRegexAllowlistMiddleware - Regex pattern-based allowlist
- ToolRegexDenylistMiddleware - Regex pattern-based denylist
- ToolArgumentRegexGuardrail - Regex-based validation of tool arguments before execution
- ToolResultSanitizationGuardrail - Sanitization of tool results to prevent sensitive data exposure
- TimeoutMiddleware - Timeout enforcement for tool calls with configurable limits
- TimingMiddleware - Basic request timing and performance monitoring
- DetailedTimingMiddleware - Comprehensive performance metrics and analysis
- RateLimitingMiddleware - Token bucket rate limiting for traffic control
- SlidingWindowRateLimitingMiddleware - Time-window-based rate limiting
- LoggingMiddleware - Basic request/response logging with configurable detail
- StructuredLoggingMiddleware - JSON-structured logs for log aggregation
- ErrorHandlingMiddleware - Error transformation and MCP compliance
The project is organized into several key directories:
mcp_plugins/
: Core middleware plugins and CLI implementationpython_examples/
: Python code examples demonstrating middleware usagejson_examples/
: JSON configuration examples for direct CLI usagedocs/
: Comprehensive documentation for each middleware typetests/
: Test suite for all middleware implementations
The easiest way to get started is using the built-in CLI:
# Create a sample configuration
mcp-plugins create-config config.json
# Run in stdio mode (default)
mcp-plugins run config.json
# Run with custom transport
mcp-plugins run config.json --transport streamable-http
# Run with custom host/port
mcp-plugins run config.json --transport streamable-http --host 127.0.0.1 --port 9001
# Run with custom log level
mcp-plugins run config.json --log-level DEBUG
# Run with all servers in configuration
mcp-plugins run config.json
Transport Types:
stdio
: For local command execution (requirescommand
andargs
)http
: For HTTP endpoints (requiresurl
)sse
: For Server-Sent Events (requiresurl
)streamable-http
: For streamable HTTP (requiresurl
)
Note: The CLI always runs as an output server. Use --transport stdio
for local development or specify network transports (http, sse, streamable-http) with --host
and --port
for remote access.
The project includes comprehensive examples demonstrating all available middleware plugins. You can run examples using the unified runner:
# Using uv (recommended)
uv run python run_examples.py --list
# Or directly from the python_examples directory
uv run python python_examples/run_examples.py --list
# Run a simple logging example
uv run python run_examples.py simple-logging
# Run a specific variant
uv run python run_examples.py tool-logging basic
# Run advanced examples
uv run python run_examples.py multiple-middleware custom
uv run python run_examples.py timing detailed
uv run python run_examples.py rate-limiting token-bucket
uv run python run_examples.py error-handling with-logging
uv run python run_examples.py structured-logging custom-methods
simple-logging
: Basic operation trackingtool-logging
: Detailed tool execution loggingtool-access-control
: Tool allowlist/denylist access controlmultiple-middleware
: Combining multiple pluginstiming
: Performance timing middlewarerate-limiting
: Request rate limitingerror-handling
: Error handling middlewarestructured-logging
: Structured logging
Each category includes multiple variants demonstrating different configurations and use cases.
python_examples/
: Python implementation of all examples with runnable codejson_examples/
: JSON configuration examples that follow the same schema assample-config.json
and can be used directly with the MCP Plugins CLI
The JSON examples provide ready-to-use configuration files that can be run directly with the CLI:
# List all available JSON examples
uv run python json_examples/run_json_examples.py list
# Show detailed information about a specific example
uv run python json_examples/run_json_examples.py show simple_logging_example.json
# Validate all JSON examples
uv run python json_examples/run_json_examples.py validate
# Run any JSON example directly with the CLI
mcp-plugins run json_examples/simple_logging_example.json
mcp-plugins run json_examples/tool_logging_example.json
mcp-plugins run json_examples/multiple_middleware_example.json
The project includes comprehensive tooling for development and code quality:
# Format all code
make format
# Check code formatting
make format-check
# Lint all code
make lint
# Auto-fix linting issues
make lint-fix
# Run all checks (format, lint, test)
make check
# Run all checks with auto-fix
make check-fix
All JSON examples are validated using the same validation logic as the CLI:
- Schema Validation: Ensures examples follow the correct configuration structure
- MCP Server Validation: Validates server configurations and transport types
- Plugin Validation: Validates plugin configurations against defined schemas
- Type Checking: Ensures proper data types for all configuration values
# Run tests
make test
# Run tests with coverage
make test-coverage
# Run tests in watch mode
make test-watch
Apache 2.0
Contributions are welcome! Please feel free to submit a Pull Request.