BunkerWeb MCP
Máy chủ MCP chính thức để quản lý các triển khai BunkerWeb từ trợ lý AI, bao gồm instances, services, configuration, bans, plugins, jobs và cache.
Tài liệu
BunkerWeb MCP Server (Python)
A production-ready MCP server that exposes BunkerWeb's internal API to large language models via a constrained tool interface. The server provides both HTTP (for testing) and WebSocket (for MCP clients) JSON-RPC endpoints, strict input validation, and a resilient async client with retries.
BunkerWeb website · Documentation
Quick Start with Claude Code
# Install the package
git clone https://github.com/bunkerity/bunkerweb-mcp.git
cd bunkerweb-mcp
# For demo/testing you do not need to change anything
# Configure environment
cp .env.example .env
# Edit .env to set BUNKERWEB_BASE_URL
# Launch BunkerWeb Stack
docker compose up -d
# If you launch Claude in this repo, it will automatically read the .mcp.json file with mcp server url.
# You can then just launch Claude
claude
> List all BunkerWeb instances
> List my BunkerWeb services
> Review @config://global for security improvements
# To connect to a remote BunkerWeb MCP server,
# use BunkerWeb itself to protect the service with TLS:
claude mcp add --transport http bunkerweb http://remote-ip:8080/mcp/
claude mcp add --transport http bunkerweb https://your-domain.com/mcp/
Features
- 43 built-in API tools, plus optional semantic search
- 🔍 AI-powered semantic search in BunkerWeb Documentation via remote search service (optional, configurable)
- MCP resources for read-only data access (global config, job logs, active bans, instance status)
- Multiple transports: Stdio (for Claude Code), HTTP, WebSocket
- Official MCP SDK integration with FastMCP for compliant clients (Claude Code, VS Code, Claude Desktop)
- Robust async client with retry/backoff and typed Pydantic models
- Prompt catalog providing contextual guidance for each tool
- FastAPI app exposing
/rpcHTTP and/wsWebSocket JSON-RPC endpoints (legacy) - CLI entry point (
bunkerweb-mcp) for easy integration - Comprehensive documentation including CLAUDE.md with BunkerWeb expertise
- Optional authentication via shared-secret token or API bearer token
- Structured JSON logging with metrics for observability
- Unit tests with mocked HTTP transport
- Docker and Kubernetes deployment manifests
- ⚡ Performance optimizations (Sprint 2):
- Caching layer with configurable TTLs for read-only operations
- Optional rate limiting to protect against request floods
- Multi-worker support for high-traffic deployments
- Load testing suite with Locust for performance validation
Requirements
- Access to a BunkerWeb API (tested with BunkerWeb 1.6.13 and current 1.6.14~rc1 development code; default
http://localhost:8888)
Installation
From Source
# Clone the repository
git clone https://github.com/bunkerity/bunkerweb-mcp.git
cd bunkerweb-mcp
# Create virtual environment
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install in development mode
pip install -e ".[dev]"
# Or install from requirements
pip install -r requirements.txt
# Configure environment
cp .env.example .env
From PyPI (when published)
pip install bunkerweb-mcp
Update .env with your API base URL and either a token or basic credentials if required.
Development Context
The repository includes a CLAUDE.md file that provides Claude Code with comprehensive BunkerWeb expertise and best practices. This file is automatically loaded when working in this repository with Claude Code, giving the assistant context about:
- BunkerWeb architecture and components
- Security module configuration (ModSecurity, Antibot, etc.)
- Common operational workflows
- Troubleshooting guidelines
- Best practices for production deployments
Configuration
All settings are configurable via environment variables (see .env.example):
| Variable | Description | Default |
|---|---|---|
BUNKERWEB_BASE_URL | Base URL to the BunkerWeb API | http://localhost:8888 |
BUNKERWEB_API_TOKEN | Optional static bearer token | empty |
BUNKERWEB_BASIC_USERNAME | Optional username for HTTP Basic auth | empty |
BUNKERWEB_BASIC_PASSWORD | Optional password for HTTP Basic auth | empty |
BUNKERWEB_REQUEST_TIMEOUT_SECONDS | HTTP timeout in seconds | 30 |
BUNKERWEB_MAX_RETRIES | Retry attempts for transient failures | 3 |
BUNKERWEB_RETRY_BACKOFF_INITIAL | Initial backoff delay (seconds) | 0.5 |
BUNKERWEB_RETRY_BACKOFF_MAX | Maximum backoff delay (seconds) | 5.0 |
BUNKERWEB_WEBSOCKET_TOKEN | Shared-secret required by /ws and /rpc | empty |
BUNKERWEB_LOG_LEVEL | Logging level | INFO |
BUNKERWEB_PROMPT_CATALOG | Optional JSON file with per-tool prompts | built-in catalog |
RATE_LIMIT_ENABLED | Enable rate limiting (Sprint 2) | false |
RATE_LIMIT_TOOLS | Rate limit for /tools endpoint | 30/minute |
RATE_LIMIT_RPC | Rate limit for /rpc endpoint | 100/minute |
RATE_LIMIT_WS | Rate limit for WebSocket messages | 500/minute |
CACHE_ENABLED | Enable caching layer (Sprint 2) | true |
WORKERS | Number of Uvicorn workers (Docker only) | 1 |
Running the server
HTTP mode (recommended)
docker-compose
docker compose up --build
The compose file launches a BunkerWeb 1.6.13 demo stack and connects the MCP server to its API.
Local (uvicorn)
uvicorn bunkerweb_mcp.main:app --host 0.0.0.0 --port 8080
Docker
docker build -t bunkerweb-mcp .
docker run --rm -p 8080:8080 --env-file .env bunkerweb-mcp
Kubernetes
Deploy to Kubernetes with BunkerWeb ingress controller integration:
# Quick deployment
kubectl apply -f deploy/kubernetes/namespace.yaml
kubectl apply -f deploy/kubernetes/secret.yaml # Edit credentials first
kubectl apply -f deploy/kubernetes/configmap.yaml
kubectl apply -f deploy/kubernetes/deployment.yaml
kubectl apply -f deploy/kubernetes/service.yaml
# Optional: External access via BunkerWeb ingress
kubectl apply -f deploy/kubernetes/ingress.yaml
# Optional: Autoscaling and monitoring
kubectl apply -f deploy/kubernetes/hpa.yaml
kubectl apply -f deploy/kubernetes/servicemonitor.yaml
# Verify deployment
kubectl get pods -n bunkerweb
kubectl logs -n bunkerweb -l app=mcp-bunkerweb --tail=100 -f
Key features:
- BunkerWeb ingress controller with ModSecurity WAF and Antibot protection
- Horizontal Pod Autoscaler (2-10 replicas based on CPU/memory)
- Prometheus metrics and OpenTelemetry tracing
- Health checks with
/healthand/readyendpoints - Configurable via ConfigMap and Secrets
For detailed deployment instructions, troubleshooting, and configuration options, see deploy/kubernetes/README.md.
Stdio mode (recommended for local use)
If you installed the package locally (pip install -e .), Claude Code and VS Code can launch the server as a subprocess via stdio, without Docker.
Configuration examples for Claude Code, VS Code, and Claude Desktop are in the dedicated section: MCP integration > Stdio Transport.
Important: use the absolute path to the virtualenv binary in
command(get it withwhich bunkerweb-mcp). Relative commands can fail because MCP clients do not inherit your shell PATH.
MCP integration
The server supports multiple transport protocols for MCP clients:
Stdio Transport (Recommended for Claude Code and VS Code)
Claude Code — .mcp.json
{
"mcpServers": {
"bunkerweb": {
"type": "stdio",
"command": "/path/to/your/.venv/bin/bunkerweb-mcp",
"env": {
"BUNKERWEB_BASE_URL": "http://<bunkerweb-api-host>:8888",
"BUNKERWEB_API_TOKEN": "your-api-token-here"
}
}
}
}
VS Code — .mcp.json
VS Code uses servers (not mcpServers):
{
"servers": {
"bunkerweb": {
"type": "stdio",
"command": "/path/to/your/.venv/bin/bunkerweb-mcp",
"env": {
"BUNKERWEB_BASE_URL": "http://<bunkerweb-api-host>:8888",
"BUNKERWEB_API_TOKEN": "your-api-token-here"
}
}
}
}
Adapt command to your actual virtualenv path (which bunkerweb-mcp after activating it) and set BUNKERWEB_BASE_URL to your BunkerWeb API address.
For Claude Desktop, add the same block to your claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json, Linux: ~/.config/Claude/claude_desktop_config.json) — the type field can be omitted as Desktop defaults to stdio:
{
"mcpServers": {
"bunkerweb": {
"command": "/path/to/your/.venv/bin/bunkerweb-mcp",
"env": {
"BUNKERWEB_BASE_URL": "http://<bunkerweb-api-host>:8888",
"BUNKERWEB_API_TOKEN": "your-api-token-here"
}
}
}
}
Verify the server is detected by Claude Code:
claude mcp list
# bunkerweb: /path/to/your/.venv/bin/bunkerweb-mcp (stdio)
Note: The stdio transport runs the server as a subprocess communicating via stdin/stdout — no port, no Docker required.
HTTP Transport (For Remote Servers)
Point MCP-compatible clients at the streamable HTTP endpoint:
- Transport: Streamable HTTP
- URL:
http://localhost:8080/mcp
Configure in .mcp.json:
{
"mcpServers": {
"bunkerweb": {
"url": "http://localhost:8080/mcp",
"transport": "http"
}
}
}
Legacy Transports
Legacy JSON-RPC transports remain available for existing workflows:
- HTTP:
/rpcendpoint - WebSocket:
/wsendpoint
Use the BUNKERWEB_WEBSOCKET_TOKEN value when a client requires authentication; the same secret protects all transports.
MCP Resources
The server exposes read-only resources that can be referenced in Claude Code conversations using the @ syntax:
| URI | Description |
|---|---|
@config://global | Current global BunkerWeb configuration |
@logs://jobs | Scheduler job execution history |
@bans://active | Currently active IP bans |
@instances://status | Health status of all instances |
Example usage in Claude Code:
> Review @config://global and suggest security hardening improvements
> Check @bans://active for any suspicious patterns
Semantic Search
The MCP server uses an AI-powered semantic search tool for BunkerWeb documentation via a remote search service.
⚠️ IMPORTANT: The search functionality has been externalized to a separate service for better scalability and reduced image size. It is not yet available to the public
Configuration
Add to your .env file:
# Enable or disable search
SEARCH_MODE=disabled # 'remote' or 'disabled'
# Search service URL
SEARCH_API_URL=https://search.example.com
# Request timeout
SEARCH_TIMEOUT=10.0
Using with Docker Compose
The included docker-compose.yml disables search because no search container is bundled. To
use a deployed search service, set SEARCH_MODE=remote and provide its SEARCH_API_URL.
Disable Search
To run the MCP server without search:
# In .env
SEARCH_MODE=disabled
Tool catalogue
Query the /tools endpoint for JSON descriptors. Available tools include:
Documentation & Search:
search_bunkerweb_docs: Semantic search across BunkerWeb documentation (query,limit,category)
Instance Management:
ping: Check API reachabilityhealth: Read the API health probelist_instances: List registered BunkerWeb instancesreload_instances: Reload configuration across all instances (testflag supported)reload_instance: Reload a specific instance (hostname, optionaltest)
Security & Bans:
list_bans: Retrieve active bansban_ip: Ban one or multiple IPs (bansarray withip,exp,reason,service)unban_ip: Remove bans (bansarray withip, optionalservice)
Services:
list_services: List services (with_draftsflag)get_service: Fetch details for a specific service (service,full,methods,with_drafts)delete_service: Delete a service (service)
And 32 more built-in tools covering authentication, configs, plugins, jobs, and cache management.
Each descriptor now carries a prompt field sourced from the prompt catalog. MCP clients can surface these short instructions to keep assistant answers consistent across tools.
Prompt catalog
The package ships with bunkerweb_mcp/data/tool_prompts.json, a curated set of guidance strings keyed by tool name. At startup the catalog is loaded once and injected into tool descriptors as well as every RPC/WebSocket response. Override the location with BUNKERWEB_PROMPT_CATALOG if you need custom wording.
JSON-RPC usage
HTTP example
curl -X POST http://localhost:8080/rpc \
-H "Content-Type: application/json" \
-H "X-MCP-Token: $BUNKERWEB_WEBSOCKET_TOKEN" \
-d '{"id":"1","tool":"list_instances","params":{}}
WebSocket example (websocat)
echo '{"id":"ping-1","tool":"ping","params":{}}' \
| websocat -H "Sec-WebSocket-Protocol: json" ws://localhost:8080/ws?token=$BUNKERWEB_WEBSOCKET_TOKEN
Tests
pip install -r requirements-dev.txt
pytest
Project layout
src/bunkerweb_mcp/
├─ main.py # FastAPI app + JSON-RPC endpoints
├─ cli.py # CLI entry point for stdio mode
├─ mcp_adapter.py # MCP server integration
├─ client.py # Resilient async client for BunkerWeb
├─ tools/ # MCP tools with strict validation
├─ config.py # Environment-driven settings
├─ prompt_catalog.py # Prompt loading helpers
├─ exceptions.py # Domain-specific exceptions
├─ search_client.py # Lightweight HTTP client for search service
├─ schemas/ # Pydantic models for requests/responses
└─ utils/logging.py # Structured logging helpers
src/bunkerweb_mcp/data/
└─ tool_prompts.json # Default tool prompts exposed to MCP clients
Observability
The MCP server includes comprehensive observability features:
Prometheus Metrics
Metrics are exposed at GET /metrics in Prometheus format:
curl http://localhost:8080/metrics
Available metrics:
mcp_tool_calls_total{tool_name, status}- Total tool calls by statusmcp_tool_duration_seconds- Tool execution duration histogrammcp_active_websockets- Active WebSocket connectionsbunkerweb_api_requests_total{endpoint, method, status}- BunkerWeb API requestsbunkerweb_api_errors_total{endpoint, error_type}- API errorsmcp_cache_hits_total{cache_type}- Cache hitsmcp_cache_misses_total{cache_type}- Cache missesmcp_search_queries_total{mode, status}- Search queries
OpenTelemetry Tracing
Distributed tracing with automatic instrumentation:
# Configure tracing via environment variables
OTEL_TRACING_ENABLED=true
OTEL_EXPORTER_OTLP_ENDPOINT=http://jaeger:4317
Traces are automatically generated for:
- HTTP requests (FastAPI)
- Outgoing API calls (httpx)
- Tool executions
View traces in Jaeger UI at http://localhost:16686
Health Checks
Liveness probe - Checks if the server is running:
curl http://localhost:8080/health
# Response: {"status": "healthy", "timestamp": "..."}
Readiness probe - Checks if the server can handle requests:
curl http://localhost:8080/ready
# Response: {"status": "ready", "checks": {"bunkerweb_api": true, "search_service": true}, "timestamp": "..."}
Kubernetes configuration:
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
Monitoring Stack
Start the full observability stack (Prometheus, Grafana, Jaeger):
docker-compose -f docker-compose.monitoring.yml up -d
Access:
- Prometheus: http://localhost:9090
- Grafana: http://localhost:3000 (admin/admin)
- Jaeger UI: http://localhost:16686
Grafana Dashboard
Pre-built dashboard with 8 panels:
- Tool Calls Rate
- Tool Success Rate
- Active WebSockets
- Tool Latency (P50/P95/P99)
- BunkerWeb API Errors
- Cache Hit Rate
- BunkerWeb API Latency
- Search Results Count
Import from deploy/grafana/dashboards/mcp-bunkerweb.json
Alerting
Pre-configured Prometheus alerts in deploy/prometheus/alerts.yml:
- High tool error rate (>10%)
- High latency (P95 > 5s)
- BunkerWeb API errors
- Low cache hit rate (<30%)
- Service health issues
Structured Logging
Logs are emitted as single-line JSON for ingestion by log processors. Each tool_call log carries a metrics object with the tool name and duration_seconds for latency tracking. Adjust BUNKERWEB_LOG_LEVEL as needed.
See docs/OBSERVABILITY.md for the complete observability guide.
Performance Tuning
The MCP server includes several performance optimizations introduced in Sprint 2:
Caching Layer
Enabled by default - Caches read-only API operations to reduce latency and load on BunkerWeb API.
# Configure in .env
CACHE_ENABLED=true # Default: true
Cache TTLs (configured in src/bunkerweb_mcp/cache.py):
list_services: 300s (5 minutes)global_config: 600s (10 minutes)list_instances: 60s (1 minute)list_bans: 30s (30 seconds)
Cache is automatically invalidated on write operations (create, update, delete).
Rate Limiting
Disabled by default - Optional protection against request floods.
# Enable in .env for production
RATE_LIMIT_ENABLED=true # Default: false
RATE_LIMIT_TOOLS=30/minute
RATE_LIMIT_RPC=100/minute
RATE_LIMIT_WS=500/minute
When enabled, exceeding rate limits returns HTTP 429 or WebSocket error.
Multi-Worker Deployment
For high-traffic deployments, increase Uvicorn workers:
# Docker environment variable
WORKERS=4 # Default: 1
# Local development
uvicorn bunkerweb_mcp.main:app --workers 4
Kubernetes resource allocation:
resources:
requests:
cpu: "100m" # Baseline for single worker
memory: "256Mi"
limits:
cpu: "500m" # Increase for multiple workers
memory: "512Mi"
Recommendation: Set WORKERS to CPU count × 2 for production deployments.
Load Testing
Verify performance with the included Locust test suite:
# Install locust
pip install -r requirements-dev.txt
# Run load test
./scripts/load-test.sh
# Or customize parameters
HOST=http://localhost:8080 USERS=200 RUN_TIME=10m ./scripts/load-test.sh
Performance targets (Sprint 2):
- Throughput: > 1000 req/s sustained
- P95 latency: < 100ms
- Error rate: 0% at 100 concurrent users
Reports are generated in ./load-test-reports/.
Performance Tips
- Enable caching (
CACHE_ENABLED=true) for read-heavy workloads - Disable rate limiting by default (set
RATE_LIMIT_ENABLED=false) unless under attack - Use multiple workers (
WORKERS=4) only for high traffic (>100 req/s) - Monitor cache hit rate via logs to tune TTLs
- Increase resources in Kubernetes based on load test results
Security notes
DNS Rebinding Protection (Important!)
The MCP server includes built-in DNS rebinding protection. You must configure allowed hosts:
# In your .env file - REQUIRED for production
MCP_ENABLE_DNS_REBINDING_PROTECTION=true
MCP_ALLOWED_HOSTS=yourdomain.com,yourdomain.com:443,internal-host,internal-host:8085
Critical: Include both hostname alone and with port (e.g., apps,apps:8085).
See docs/security.md for detailed configuration guide.
Other Security Best Practices
- Populate
BUNKERWEB_API_TOKENwhen the target API requires authentication. - When using HTTP Basic auth, set
BUNKERWEB_BASIC_USERNAMEandBUNKERWEB_BASIC_PASSWORDvia secrets management. - Set
BUNKERWEB_WEBSOCKET_TOKENto require a shared secret for both/rpcand/ws. - Ensure the MCP server runs on a trusted network; the API can modify BunkerWeb state.
- Use HTTPS via reverse proxy (nginx, Traefik, or BunkerWeb) in production.
Documentation
Project Documentation
- Architecture Decision Records (ADR) - Major architectural decisions with context and rationale
- Observability Guide - Complete guide to metrics, tracing, and monitoring (Sprint 4)
- Security Guide - DNS rebinding protection and security best practices
- Claude Development Guide - BunkerWeb expertise for Claude Code
API Documentation
All tool handlers include comprehensive Google-style docstrings with:
- Detailed functionality description
- Parameter specifications with types and defaults
- Return value format documentation
- Exception handling guidance
- Usage examples
Example: src/bunkerweb_mcp/tools/registry.py registers all built-in handlers.
Architecture Decisions
Key architectural choices are documented in ADRs:
- ADR-0001: FastMCP SDK - MCP protocol implementation
- ADR-0002: Externalize Search - Search service architecture
- ADR-0003: Pydantic V2 - Data validation framework
- ADR-0004: Async HTTPX - HTTP client choice
Contributing
See individual ADRs for architectural guidance when proposing changes. All new tool handlers must include:
- Complete Google-style docstrings
- Unit tests with >80% coverage
- Updates to relevant ADRs if architectural changes are involved
License
MIT