Wazuh MCP Server
๐ก๏ธ Wazuh MCP Server
Talk to your SIEM in plain language.
Query alerts, hunt threats, triage vulnerabilities, and run active responses across your entire Wazuh deployment โ through natural conversation with any AI assistant.
55 security tools ยท dual-era MCP (2026-07-28 + legacy) ยท multi-cluster ยท fully air-gappable ยท production-hardened
Quick Start ยท Tools ยท Security ยท Docs ยท Changelog ยท Upgrading
What This Does
Your Wazuh SIEM generates thousands of alerts, vulnerability findings, and agent events daily. Investigating them means juggling dashboards, writing API queries, and manually correlating data across tools.
This MCP server turns that workflow into a conversation:
You: "Show me critical alerts from the last hour"
AI: [calls get_wazuh_alerts] Found 3 critical alerts:
1. SSH brute force from 10.0.1.45 โ agent-003 (Rule 5712, Level 10)
2. Rootkit detection on agent-007 (Rule 510, Level 12)
3. FIM change /etc/shadow on agent-001 (Rule 550, Level 10)
You: "Block that source IP on agent-003"
AI: [calls wazuh_block_ip] Blocked 10.0.1.45 via firewall-drop on agent-003.
You: "Which agents have unpatched critical CVEs?"
AI: [calls get_wazuh_critical_vulnerabilities] 3 agents with critical vulnerabilities...It works with Claude Desktop, Open WebUI + Ollama (fully local, air-gapped), mcphost, or any MCP-compliant client.
Works With Cloud AND Local LLMs
This is a standard MCP tool server. It doesn't care what LLM you use โ it just executes tools and returns results.
Mode | LLM | Client | Data leaves your network? |
Cloud | Claude, GPT, etc. | Claude Desktop, any MCP client | Yes (to LLM provider) |
Local | Llama, Qwen, Mistral via Ollama | Open WebUI, mcphost, IBM/mcp-cli | No. Fully air-gappable. |
For security teams that can't send SIEM data to cloud APIs (compliance, air-gapped networks, data sovereignty), the local mode with Ollama keeps everything on-premises. Both modes coexist โ same server, same tools, same API.
Quick Start: Local LLM with mcphost
# 1. Start the MCP server
docker compose up -d
# 2. Install mcphost (Go binary, no dependencies)
go install github.com/mark3labs/mcphost@latest
# 3. Configure
cat > ~/.mcphost.yml << 'EOF'
mcpServers:
wazuh:
type: remote
url: http://localhost:3000/mcp
headers: ["Authorization: Bearer ${env://MCP_API_KEY}"]
EOF
# 4. Chat with your SIEM using a local model
export MCP_API_KEY="your-key-from-server-logs"
mcphost --model ollama/qwen2.5:7bQuick Start: Multi-User SOC with Open WebUI
Open WebUI v0.6.31+ connects to our /mcp endpoint natively. Add it as an MCP tool server in Admin Settings, and your entire team gets AI-powered SIEM analysis with conversation history, RBAC, and a web UI.
55 Security Tools
Every tool is validated, rate-limited, scope-checked, and audit-logged.
Category | Tools | What They Do |
Alerts (5) |
| Query, filter, search, and aggregate alert data via the Indexer. Timestamps accept ISO 8601 or relative date math ( |
Agents (6) |
| Monitor agent status, running processes, open ports, and configs |
Vulnerabilities (3) |
| Query CVEs by severity, agent, and package |
Security Analysis (6) |
| Threat analysis, IOC lookup, optional web context, risk scoring, security reports |
Compliance (6) |
| Compliance scoring for PCI-DSS, HIPAA, SOX, GDPR, NIST, and ISO 27001:2022 (Annex A control mapping, gap analysis, SCA detail) |
System (10) |
| Cluster health, rules, manager logs, stats, connectivity |
Active Response (9) |
| Block IPs, isolate hosts, kill processes, quarantine files |
Verification (5) |
| Verify active response actions took effect |
Rollback (5) |
| Undo active response actions |
The 14 state-changing tools (Active Response + Rollback) require the wazuh:write scope; everything else needs only wazuh:read. ISO 27001 also adds an iso27001_assessment guided prompt (5 prompts total).
Quick Start
Prerequisites
Docker 20.10+ with Compose v2
Wazuh 4.8.0โ4.14.7 with API access enabled
Deploy
git clone https://github.com/gensecaihq/Wazuh-MCP-Server.git
cd Wazuh-MCP-Server
cp .env.example .envEdit .env:
WAZUH_HOST=your-wazuh-server
WAZUH_USER=your-api-user
WAZUH_PASS=your-api-passworddocker compose up -d
curl http://localhost:3000/healthPre-built image
A multi-arch image (amd64/arm64) is published to GitHub Container Registry on every release and on every push to main:
docker pull ghcr.io/gensecaihq/wazuh-mcp-server:latest # main branch
docker pull ghcr.io/gensecaihq/wazuh-mcp-server:4.3.0 # pinned releasedocker run -d --name wazuh-mcp-server --env-file .env -p 3000:3000 \
ghcr.io/gensecaihq/wazuh-mcp-server:latestConnect Claude Desktop
Settings โ Connectors โ Add custom connector
URL:
https://your-server/mcpAdd Bearer token in Advanced settings
Detailed setup: Claude Integration Guide
Security
This server sits between an LLM and your SIEM. Security is not optional.
Layer | What It Does |
RBAC | Per-tool scope enforcement, fail-closed: a token with no scope claim gets read-only, never write. The 14 state-changing tools (active response + rollback) require |
Audit Logging | Every destructive tool call (block IP, isolate host, kill process) is logged with client ID, session, timestamp, and full arguments. |
Output Sanitization | Credentials, tokens, and API keys in alert |
Input Validation | Every parameter validated: regex agent IDs, |
Rate Limiting | Per-principal sliding window (keyed on the authenticated client + trusted-proxy IP), with a short retry-after backoff โ seconds until the oldest request leaves the window, not a fixed multi-minute block. |
Circuit Breakers | Wazuh API failures trigger fail-fast for 60s, auto-recover. Single trial in HALF_OPEN state. |
Log Sanitization | Global filter redacts passwords, tokens, secrets from all server logs. |
Container Hardening | Non-root user, read-only filesystem, |
# Generate a secure API key
python -c "import secrets; print('wazuh_' + secrets.token_urlsafe(32))"Configuration
Required
Variable | Description |
| Wazuh Manager hostname or IP |
| API username |
| API password |
Optional
Variable | Default | Description |
|
|
|
|
| Manager API port |
|
| Verify the Manager's TLS certificate |
|
| Server bind address |
|
| Server port |
|
|
|
| auto (dev only) | JWT signing key. Required when |
| auto (dev only) | Pre-set API key ( |
|
| Scopes for |
|
| Allow active response in authless mode |
|
| CORS origins (comma-separated) |
| โ | Proxy IPs to trust for |
| โ | Redis URL for multi-instance session storage |
|
| Wire format for alert/event/vulnerability results: |
Response encoding (GCF)
Alert, security-event, and vulnerability tools return uniform record collections
under a data.affected_items array. Setting RESPONSE_FORMAT=gcf encodes those
responses as a Graph Compact Format generic wire instead
of JSON, factoring the repeated field names into a single header so the response
uses fewer tokens when it crosses the LLM boundary.
It is opt-in, lossless, and every response stays complete (a format change only,
no cross-turn deduplication, so no alert is ever omitted). If encoding fails โ
or the encoder isn't installed โ the tool falls back to JSON. It composes with
the existing compact field-projection parameter.
The encoder is one zero-dependency package (pinned exact). Install it directly, or via the
gcf extra from a source checkout:
pip install gcf-python==2.5.1 # direct
pip install ".[gcf]" # or, from a clone of this repoProduction note: the server listens over plain HTTP โ terminate TLS at a reverse proxy or load balancer. OAuth knobs (
OAUTH_ENABLE_DCRโ off by default,OAUTH_*_TTL) and rate-limit tuning (RATE_LIMIT_REQUESTS,RATE_LIMIT_WINDOW) are in the Configuration Guide.
Wazuh Indexer (for alert search + vulnerabilities)
Variable | Default | Description |
| โ | Indexer hostname (an |
|
| Indexer port |
| โ | Indexer username |
| โ | Indexer password |
|
| Use HTTPS for the Indexer (set |
|
| Verify the Indexer's TLS certificate |
| โ | Optional You.com API key. Enables the |
|
| Optional You.com Search API base URL |
|
| Verify You.com TLS certificates independently of Wazuh |
|
| Optional multi-cluster topology file (see below) |
| โ | Custom active-response command that removes a firewall-drop block. Required for |
| โ | Custom active-response command that removes a hosts.deny block. Required for |
Full reference: Configuration Guide
Multi-Cluster (optional)
Managing several Wazuh deployments? Drop a clusters.json next to your config (see
config/clusters.json.example) and every tool gains an
optional cluster_id argument plus a list_wazuh_clusters tool:
No
clusters.jsonโ single-cluster behavior from env vars, exactly as before.With
clusters.jsonโ named clusters, each with its own Manager (and optionally Indexer) credentials;"${ENV_VAR}"values are resolved from the environment so secrets stay out of the file. The env-configured cluster remains reachable asdefault.Cross-Cluster Search โ point clusters at a shared OpenSearch CCS coordinator and set
ccs_prefix(the remote-cluster name); alert/vulnerability queries becomeeu:wazuh-alerts-*. An entry with"ccs_prefix": "*"gives you anallpseudo-cluster that searches every remote cluster at once.
API Endpoints
Endpoint | Method | Description |
| POST/GET/DELETE | MCP Streamable HTTP (recommended) |
| GET | Legacy Server-Sent Events |
| GET | Liveness probe โ 200 while the process is up (no dependency checks; use for the container healthcheck) |
| GET | Readiness probe โ checks Wazuh Manager/Indexer reachability; 503 when a dependency is down |
| GET | Prometheus metrics |
| POST | Exchange API key for JWT (bearer mode) |
| GET | OAuth 2.0 discovery (oauth mode) |
| GET | OAuth protected-resource metadata, RFC 9728 (oauth mode) |
| GET | OpenAPI documentation |
Architecture
src/wazuh_mcp_server/
โโโ server.py # MCP protocol + 55 tool handlers
โโโ config.py # Environment-based configuration
โโโ auth.py # JWT + API key authentication
โโโ oauth.py # OAuth 2.0 with Dynamic Client Registration
โโโ security.py # Rate limiting, CORS, input validation
โโโ monitoring.py # Prometheus metrics, structured logging
โโโ resilience.py # Circuit breakers, retries, graceful shutdown
โโโ session_store.py # Pluggable sessions (in-memory + Redis)
โโโ api/
โโโ wazuh_client.py # Wazuh Manager REST API client
โโโ wazuh_indexer.py # Wazuh Indexer (Elasticsearch) clientTake It Further: Autonomous Agentic SOC
Combine this MCP server with Wazuh Autopilot to build an agentic Security Operations Center.
While this server gives you conversational access to Wazuh, Autopilot runs an eleven-agent AI SOC team on top of it around the clock โ a seven-stage reactive pipeline (triage โ correlation โ investigation โ response) plus four proactive specialists (vulnerability management, threat intel, threat hunting, detection engineering). Every containment action is gated behind two-tier human approval. Runs on OpenClaw, Hermes, or NVIDIA NemoClaw.
Manual SOC: Alert โ Analyst reviews โ Hours โ Response
Agentic SOC: Alert โ AI triages โ Seconds โ Response ready for approvalDocumentation
Guide | Description |
Claude Desktop setup and authentication | |
Full configuration reference | |
HA, serverless, compact mode | |
Per-tool documentation | |
Security hardening guide | |
Common issues and solutions | |
Deployment, monitoring, maintenance |
Contributing
We welcome contributions. See Issues for bugs and feature requests, Discussions for questions.
License
Acknowledgments
Wazuh โ Open source security platform
Model Context Protocol โ AI tool integration standard
Ollama โ Local LLM inference
Open WebUI โ Self-hosted AI chat interface
mcphost โ MCP CLI host with LLM support
Contributors
Avatar | Username | Contributions |
๐ป Code, ๐ Issues, ๐ PRs, ๐ฌ Discussions | ||
๐ป Code, ๐ Issues, ๐ PRs | ||
๐ป Code, ๐ PRs, ๐ฌ Discussions | ||
๐ป Code, ๐ PRs | ||
๐ป Code, ๐ PRs | ||
๐ป Code, ๐ PRs | ||
๐ป Code, ๐ PRs | ||
๐ป Code, ๐ PRs | ||
๐ป Code, ๐ PRs | ||
๐ป Code, ๐ PRs | ||
๐ PRs | ||
๐ PRs | ||
๐ PRs | ||
๐ PRs | ||
๐ Issues | ||
๐ Issues | ||
๐ Issues | ||
๐ Issues | ||
๐ Issues | ||
๐ Issues | ||
๐ Issues | ||
๐ Issues | ||
๐ Issues | ||
๐ฌ Discussions | ||
๐ฌ Discussions | ||
๐ฌ Discussions | ||
๐ฌ Discussions | ||
๐ฌ Discussions | ||
๐ฌ Discussions |
Legend: ๐ป Code ยท ๐ Issues ยท ๐ Pull Requests ยท ๐ฌ Discussions
Auto-updated by GitHub Actions