Wazuh MCP Server
Blue Team MCP Server (Wazuh SIEM)
Оборонительный MCP-сервер для Claude Desktop / любого MCP-клиента — аналог для синей команды по отношению к атакующему инструментарию. 123 инструмента + 4 ресурса в области Wazuh SIEM, многопровайдерной аналитики угроз, корреляции 3-Sum APT на основе MITRE, построения графов атак, исследовательских рабочих процессов LangGraph и форензики хостов. По умолчанию — только чтение.
Программист: NAuliajati (csirt[at]tangerangkota[.]go[.]id)
Архитектура
main.py -> mcp_server/ (package)
├─ core/ HTTP client, redaction, audit, config, attack graph, IOC store
├─ wazuh/ Indexer (OpenSearch) + Manager API (JWT auth)
├─ correlation/ 3-Sum engine (pure computation, MITRE-driven)
├─ threat_intel/ CrowdSec, ThreatFox, OTX, URLhaus, GreyNoise + shared cache
├─ agents/ LangGraph investigation + playbook workflows
└─ tools/ 49 tool modulesКаждый вызов инструмента проходит через единый конвейер в декораторе @blueteam_tool — три наиболее связанных узла в графе кода:
audit (_audit_log) -> call -> redact (_redact_alert_data) -> truncate (_truncate_if_needed)Весь исходящий HTTP проходит через автоматический выключатель на пул (http_client.CircuitBreaker: 5 последовательных сбоев -> разомкнут, 60-секундная пауза, одно пробное полуоткрытое соединение). 429 и 4xx никогда не считаются сбоями, поэтому сбой на одном вышестоящем сервисе приводит к быстрому отказу, а не к накоплению повторных попыток между инструментами.
Транспорт | Сценарий использования |
| Локальный подпроцесс / SSH-канал (по умолчанию) |
| Удалённый HTTP-сервис ( |
Related MCP server: wrg-mcp-server
Быстрый старт
git clone <repo> && cd Wazuh-MCP-Server
sudo bash setup.sh # deps, venv, wrapper at /opt/blue-team-mcp
# configure (edit /opt/blue-team-mcp/config.env)
export WAZUH_INDEXER_URL="https://<host>:9200"
export WAZUH_INDEXER_USER="admin"
export WAZUH_INDEXER_PASSWORD="<indexer-password>"
export WAZUH_API_URL="https://<host>:55000" # optional — Manager API tools
export WAZUH_API_USER="wazuh-wui"
export WAZUH_API_PASSWORD="<api-password>"
export CROWDSEC_API_KEY="<key>" # optional — threat intel (free)
# inbound auth for the HTTP transport (REQUIRED when binding beyond 127.0.0.1)
export MCP_API_KEY="btm_<43-char-base64>" # generate: python3 -c "import secrets; print('btm_' + secrets.token_urlsafe(32))"
export MCP_API_KEY_SCOPES="wazuh:read wazuh:write" # optional — default wazuh:read (read-only)
# run (stdio)
mcp-server-blueteam
# or remote HTTP (MCP_API_KEY is mandatory here — the server refuses to bind otherwise)
MCP_TRANSPORT=streamable_http MCP_HOST=0.0.0.0 MCP_PORT=8001 \
MCP_API_KEY="btm_<43-char-base64>" mcp-server-blueteamКонфигурация Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"blue-team-mcp": {
"command": "ssh",
"args": ["-i", "~/.ssh/id_ed25519", "user@DEFENDER_HOST", "mcp-server-blueteam"],
"transport": "stdio"
}
}
}Конфигурация
Учётные данные берутся из переменных окружения и проверяются при запуске. Каждый ключ threat-intel необязателен — инструменты корректно деградируют без них.
Область | Переменные | Примечания |
Wazuh Indexer |
| OpenSearch (9200) — данные оповещений/событий |
Wazuh Manager |
| Manager API (55000) — правила/агенты/конфигурация |
TLS |
| по умолчанию |
Threat intel |
| 9 провайдеров + RapidAPI + HudsonRock; все необязательны |
Маскирование |
| см. «Безопасность и конфиденциальность» |
Форензик-шлюз |
| по умолчанию |
Входящая аутентификация |
| предварительно согласованный API-ключ + области для |
Усиление входящих соединений |
| скользящее окно ограничения скорости на IP (запросов/мин, |
Аудит и хранение |
| JSONL-журнал аудита + хранилища (необязательно) |
Ограничение доступа |
| пропуск разрушительных инструментов / категорий инструментов |
Возможности
Wazuh SIEM
Поиск оповещений (blueteam_wazuh_indexer_search, wazuh_alert_dsl_query), статистические агрегации без документов, обнаружение схемы (blueteam_index_schema), поиск по доменам/email/гео/syscheck/комплаенсу, а также инструменты Manager API (правила, декодеры, группы, агенты, события безопасности).
Корреляция 3-Sum APT
three_sum_correlation запускает два движка плюс единую оценку риска:
Движок A — пороговая оценка риска по множеству IoC на основе MITRE. Оповещения классифицируются по
rule.mitre.tactic(черезMITRE_TACTIC_TO_CATEGORY) иrule.mitre.id(разрешается через пакет ATT&CK STIX), оцениваются какrule.level × вес тактикии ограничиваются правилом цепочки атак из ≥2 категорий (threshold_scoreпо умолчанию 35).Движок B — объёмный Z-score по 3 источникам (MAD + проверка плеч), выявляющий одновременные всплески.
Плюс мультиразрешение (1h/24h/7d), единая оценка критичности и обнаружение деградации Indexer.
Аналитика угроз
9 провайдеров — CrowdSec, ThreatFox, OTX, URLhaus, GreyNoise, AbuseIPDB, VirusTotal, Netra, Argus — с единым blueteam_threat_intel_aggregate (конкурентный fan-out) и взвешенным blueteam_unified_threat_score. Плюс stealer_log_check (HudsonRock) и jarm_fingerprint (TLS-отпечаток для атрибуции C2/вредоносного ПО, без API-ключа), а также 3 RapidAPI-запроса (blueteam_ip_blacklist, blueteam_ioc_search, blueteam_breach_check).
Обогащение оповещений
blueteam_wazuh_alert_summarize, blueteam_beacon_detect, blueteam_attack_chain, blueteam_threat_card, blueteam_wazuh_alert_compare, blueteam_curated_threat_report.
Расследования, графы и рабочие процессы
blueteam_investigate_ip, blueteam_attack_graph (кластеры networkx + PageRank), blueteam_pivot_suggest, blueteam_campaign_watch, blueteam_stix_killchain, blueteam_investigation_workflow и blueteam_playbook_run (LangGraph), а также база знаний ложных срабатываний (blueteam_false_positive_kb), которая автоматически подавляет известные шумные IoC в 3-Sum.
Форензика хостов и доменов
WHOIS / CRT.sh, извлечение IoC, JARM-отпечатки, обнаружение тайпсквоттинга (blueteam_domain_permute), сканирование веб-шеллов, серверный экспорт в JSONL, экспорт отчётов в DOCX/XLSX/PPTX и 23 инструмента форензики хостов (чтение журналов, fail2ban, сканирование руткитов, lynis, процессы/cron/пользователи).
Безопасность и конфиденциальность
Входящая аутентификация (streamable_http)
streamable_http защищён предварительно согласованным API-ключом в mcp_server/core/server_auth.py:
MCP_API_KEY— форматbtm_<43-char-urlsafe-base64>(47 символов). Хранится только в виде SHA-256-дайджеста, сравнение черезhmac.compare_digest(константное время).MCP_API_KEY_SCOPES— по умолчаниюwazuh:read(только чтение). Добавьтеwazuh:write, чтобы разблокировать 9 инструментов записи (blueteam_fail2ban_unban,blueteam_case_*,blueteam_set_owned_domains,blueteam_mark_investigated,blueteam_wazuh_export,blueteam_export_report,blueteam_capture_traffic). Fail-closed: без области ⇒ только чтение.Защита привязки (
main.py::_start_http_transport): привязка не к loopback безMCP_API_KEYвызываетConfigurationErrorи отказывается запускаться. Loopback остаётся без аутентификации только если ключ не настроен; когда ключ задан, он применяется к каждому запросу.Защита глубины JSON (
parse_json_body_safe): каждое POST-тело ограничено 1 МБ (MAX_BODY_BYTES) и отклоняется, если вложенность превышает 100 уровней (MAX_JSON_DEPTH) до выполненияjson.loads— блокирует DoS-атаку на истощение стека через глубоко вложенные JSON-RPC-запросы.Входящий ограничитель скорости (
SlidingWindowRateLimiter): скользящее окно на IP клиента (BLUETEAM_HTTP_RATE_LIMIT, запросов/мин, по умолчанию0= выключено) →429при превышении. Отличается отBLUETEAM_RATE_LIMIT, который ограничивает разрушительные инструменты (разбан fail2ban, захват tcpdump) глобальным лимитом в минуту.Проверка Origin (
_origin_allowed): заголовокOriginдолжен быть loopback-источником или входить вBLUETEAM_ALLOWED_ORIGINS(точные источники через запятую), иначе403. Блокирует DNS-rebinding / эксфильтрацию localhost через браузер. Запросы без заголовкаOrigin(небраузерные клиенты) не затрагиваются. Промежуточное ПО устанавливается всегда — ограничение скорости и проверка Origin действуют даже при привязке к loopback без аутентификации.
Политика маскирования
Политика с тремя состояниями (BLUETEAM_REDACTION_POLICY, по умолчанию protect_victim):
Политика | Поведение |
| Маскирование на основе формы для email, частных IP, всех доменов, путей, user-agent — консервативный запасной вариант, когда у |
| Маскировать только индикаторы, принадлежащие жертве (собственные домены, частные IP, идентичности); IoC атакующего остаются видимыми. Рекомендуется для триажа в SOC. |
| Только снятие учётных данных уровня 1 — жёстко ограничено |
Уровень 1 (снятие учётных данных) применяется во всех состояниях и его нельзя обойти. Реестр IoC атакующего (core/attacker_registry.py) освобождает подтверждённые индикаторы атакующего от маскирования на основе формы — но никогда от уровня 1.
Двухуровневое снятие маски поверх политики:
Уровень 1 —
reveal_owned=true— показывает LLM только собственные активы*.tangerangkota.go.idи снимает маскировку с ключей корзин собственных доменов в инструментах агрегации (включаяwazuh_alert_dsl_query). Никогда не выходит за пределыBLUETEAM_OWNED_DOMAINS.Уровень 2 —
bypass_redaction=true+forensic_token— записывает сырые данные на диск; LLM получает только путь к файлу, но никогда сырое содержимое.
Укажите в BLUETEAM_OWNED_DOMAINS домены вашей организации (через запятую, например tangerangkota.go.id). Просмотр через blueteam_owned_domains; обновление в рантайме через blueteam_set_owned_domains (ограничено BLUETEAM_ALLOW_RUNTIME_DOMAINS=true, по умолчанию выключено).
Промпт для SOC-анализа (скопируйте для вашей LLM)
Готовый к вставке промпт для локальной LLM, подключённой к этому MCP-серверу. Два формата вывода — Markdown (встроенный) и DOCX (требуется officecli, blueteam_export_report).
⚠️ Calling convention & guardrails (read once — prevents "Field required" errors and false positives):
- Every tool takes a SINGLE ``params`` object. FastMCP double-nests it:
tool_invoke(name="<tool>", params={"params": {"field": value, ...}})
Call tool_inspect FIRST to read a tool's exact signature; never skip inspect on an unused tool.
- Default model = protect_victim: the LLM sees attacker public IPs/payloads/rule/severity/MITRE,
never internal emails, subdomains, private IPs (RFC1918), or internal paths.
- A private/RFC1918 srcip (10.x, 172.16-31.x, 192.168.x) is INTERNAL, never an attacker — do not
run threat-intel on it (those tools reject private IPs by design — SSRF guard).
- reveal_owned=true (Tier 1, LLM-safe): reveals only *.tangerangkota.go.id + @tangerangkota.go.id.
Accepted by the alert/aggregation tools — wazuh_domain_lookup, wazuh_alert_focused_crawl,
wazuh_email_lookup, wazuh_alert_dsl_query (unmasks owned-domain bucket keys), and others —
never expands beyond BLUETEAM_OWNED_DOMAINS.
- bypass_redaction=true + forensic_token (Tier 2, HUMAN ONLY): writes raw data to disk via
blueteam_wazuh_export; the LLM sees only the file path.
- ⚠️ NEVER pass redaction_policy="raw" OR bypass_redaction=true in a tool call — both are
HUMAN-ONLY and gated behind the operator forensic token, which the LLM does NOT hold. The
call fails with "requires the operator forensic token". For owned-domain visibility use
reveal_owned=true (above, no token); full raw forensics is blueteam_wazuh_export run by the
analyst on the server.
- redaction_policy="protect_victim" is accepted by 13 tools (blueteam_curated_threat_report,
blueteam_threat_card, blueteam_wazuh_alert_summarize, blueteam_wazuh_alerts,
blueteam_wazuh_geo_heatmap, blueteam_wazuh_indexer_search, three_sum_correlation,
wazuh_alert_aggregate_analysis, wazuh_alert_focused_crawl, wazuh_alert_timeline,
wazuh_attack_velocity, wazuh_domain_lookup, wazuh_email_lookup). blueteam_wazuh_export uses
bypass_redaction (NOT redaction_policy). Other tools reject redaction_policy — drop it and retry.
(Separately, wazuh_alert_dsl_query accepts reveal_owned=true but NOT redaction_policy.)
- blueteam_wazuh_export writes to BLUETEAM_EXPORT_DIR (default /var/log/blue-team-mcp/exports/)
with an AUTO-GENERATED filename (export_<timestamp>.jsonl). It has NO ``path`` parameter —
do not pass one (it will be rejected). Only blueteam_export_report accepts a ``path``.
LANGKAH 0 — Index schema (before any aggregation):
blueteam_index_schema(fields=["data.srcip","rule.id","rule.groups","agent.name",
"data.domain","data.url","GeoLocation.city_name"], response_format="json")
LANGKAH 1 — Full overview + own-asset forensics:
blueteam_curated_threat_report(since="24h", investigation_depth="deep",
response_format="json", redaction_policy="protect_victim")
wazuh_domain_lookup(domain="tangerangkota.go.id", since="24h", reveal_owned=true,
response_format="json", max_scanned=10000)
LANGKAH 2 — Per attacker (top 10): threat card + attack chain
blueteam_threat_card(srcip=<ip>, since="24h")
blueteam_attack_chain(srcip=<ip>, since="24h")
LANGKAH 3 — Unified threat intel:
blueteam_threat_intel_aggregate(indicator=<ip>, response_format="json")
argus_ip_lookup(ip=<ip>); otx_lookup(indicator=<ip>, section="general")
blueteam_ip_blacklist(ip=<ip>); blueteam_ioc_search(ip=<ip>) # RapidAPI
LANGKAH 4 — 3-Sum APT + auto-enrich + case:
three_sum_correlation(time_window_minutes=1440, follow_up="threat_intel",
multi_resolution=true, create_case=true, response_format="json",
redaction_policy="protect_victim")
LANGKAH 5 — Attack graph + pivot + campaign:
blueteam_attack_graph(window_days=30, top_n=20, response_format="json")
blueteam_pivot_suggest(ioc=<top_attacker_ip>)
blueteam_campaign_watch(response_format="json")
LANGKAH 6 — LangGraph investigation + verdict:
blueteam_investigation_workflow(alert_text="<...>", srcip=<ip>, window="24h",
use_attack_graph=true, generate_report=false, record_verdict=true, verdict_label="suspicious")
blueteam_mark_investigated(srcip=<ip>, verdict="<verdict>", case_id=<case_id>)
LANGKAH 7 — Compromised emails + breach/stealer check:
wazuh_compromised_emails_analysis(since="24h", response_format="json")
blueteam_breach_check(email=<email_dinas>); stealer_log_check(email=<email_dinas>)
LANGKAH 8 — MITRE kill-chain + C2 fingerprinting:
blueteam_stix_killchain(srcip=<ip>, since="24h")
jarm_fingerprint(host=<c2_domain_or_ip>, response_format="json")
blueteam_domain_permute(domain="tangerangkota.go.id") # typosquatting lookalikes
LANGKAH 9 — Suppression, telemetry, case review:
blueteam_false_positive_kb(); blueteam_owned_domains(); blueteam_metrics()
blueteam_case_list(); blueteam_case_get(case_id=<case_id>)
LANGKAH 10 — Geo heatmap:
blueteam_wazuh_geo_heatmap(since="24h", response_format="json")
Supplementary tools (by category — the full 123-tool set; LANGKAH 0–10 is the default path):
- Alert search/aggregation: blueteam_wazuh_indexer_search, blueteam_wazuh_alerts,
wazuh_alert_aggregate_analysis, wazuh_alert_focused_crawl, wazuh_alert_dsl_query,
wazuh_alert_timeline, wazuh_attack_velocity, blueteam_wazuh_alert_summarize,
blueteam_wazuh_alert_compare.
- Threat intel: crowdsec_ip_reputation(/bulk), threatfox_ioc_search(/bulk),
greynoise_ip_context, netra_ip_analysis, otx_lookup_bulk, urlhaus_lookup(/bulk),
urlhaus_hash_lookup, blueteam_lookup_domain_virustotal, blueteam_lookup_hash_virustotal,
blueteam_unified_threat_score, blueteam_mitre_lookup.
- Baselines & anomaly: blueteam_baseline_profile, blueteam_baseline_drift,
blueteam_calendar_heatmap, blueteam_beacon_detect.
- Wazuh Manager (agents/rules/config): blueteam_wazuh_agents, blueteam_wazuh_agents_summary,
blueteam_wazuh_get_cluster_nodes, blueteam_wazuh_get_rules, blueteam_wazuh_get_groups,
blueteam_wazuh_get_decoders, blueteam_wazuh_get_security_events, blueteam_wazuh_manager_logs,
blueteam_wazuh_get_rule_files, blueteam_wazuh_get_rule_file_content,
blueteam_wazuh_get_agent_sca, blueteam_wazuh_list_sca_policies, blueteam_wazuh_get_sca_policy_checks.
- Compliance/SCA/vuln: blueteam_wazuh_syscheck, blueteam_wazuh_compliance,
blueteam_wazuh_vulnerabilities.
- Host forensics: blueteam_read_auth_log, blueteam_read_syslog, blueteam_read_web_log,
blueteam_failed_logins, blueteam_last_logins, blueteam_who_is_logged_in,
blueteam_find_suid_files, blueteam_find_world_writable, blueteam_list_connections,
blueteam_list_listening_ports, blueteam_list_processes, blueteam_list_cron_jobs,
blueteam_list_users, blueteam_hash_file, blueteam_journalctl, blueteam_rootkit_scan,
blueteam_lynis_audit, blueteam_system_health, blueteam_sudo_history,
blueteam_check_open_firewall, blueteam_check_ssh_authorized_keys, blueteam_check_updates,
blueteam_fail2ban_status, blueteam_fail2ban_jail_status, blueteam_fail2ban_unban,
blueteam_capture_traffic.
- Domain/asset: blueteam_whois_lookup, blueteam_crtsh_lookup, blueteam_asset_context.
- Case/IOC/history: blueteam_case_create, blueteam_case_add_iocs, blueteam_case_add_verdict,
blueteam_case_list, blueteam_case_get, blueteam_extract_iocs, blueteam_ioc_lifecycle,
blueteam_investigate_ip, blueteam_playbook_run, blueteam_investigation_history,
blueteam_investigation_summary, blueteam_false_positive_tracker.
- Geo: blueteam_wazuh_geo_distribution (by country).
- Forensics/scanning/other: blueteam_check_webshell, blueteam_semantic_search,
blueteam_threat_hunt, blueteam_stix_analyze, blueteam_prompt_route.
- AI/LLM attack detection: blueteam_ai_bot_recon (AI-agent user-agents probing exploit paths).
- Sangfor blocklist: sangfor_blocklist_check(ip=<ip>) for a single IP;
sangfor_blocklist_list(limit=…, date_start="YYYY-MM-DD HH:MM:SS", date_end=…) for the list —
no ``since`` / ``offset`` params (use date_start/date_end).
—— FORMAT MARKDOWN: compose the report from steps 1–10 (ringkasan → subdomain → IOC →
threat intel → 3-Sum → attack graph → LangGraph → email → MITRE → geo).
—— FORMAT DOCX (officecli): blueteam_export_report(format="docx", title="<...>",
path="/var/log/blue-team-mcp/exports/laporan_24jam_<date>.docx", docx_sections=[...])
—— FORENSIC EXPORT (HUMAN ONLY): blueteam_wazuh_export(since="24h", bypass_redaction=true,
forensic_token="<BLUETEAM_FORENSIC_TOKEN>")
→ streams to /var/log/blue-team-mcp/exports/export_<timestamp>.jsonl (filename auto-generated;
NO ``path`` parameter). WITHOUT ``bypass_redaction=true`` the export is protect_victim-masked
(subdomains stay masked). Analyst reads the file on the server (cat/jq); the LLM assists only
with REDACTED analysis.Требования
Python 3.11+
mcp,httpx[http2],pydantic,networkx,langgraph,officecli-sdkСм.
requirements.txt.
Разработка
Перед слиянием:
python3 check_guardrails.py --strictдолжен завершиться с кодом 0, а логирование остаётся в stderr.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityAmaintenanceAn MCP server for the Wazuh SIEM/XDR platform that enables users to query agents, security alerts, detection rules, and decoders through Claude or other MCP clients. It provides specialized tools and prompts for investigating security alerts, performing agent health checks, and generating environmental security overviews.28343MIT
- AlicenseNot gradedqualityAmaintenanceAn MCP server that exposes a 60+ tool security and threat-intel stack to AI agents, enabling secret scanning, Sigma rule generation, ransomware lookup, OSINT, and deep research.1MIT
- AlicenseNot gradedqualityCmaintenanceAn MCP server that transforms Claude Code into an autonomous DFIR analyst by providing typed, audited forensic tools for disk, memory, timeline, registry, and IOC analysis on the SANS SIFT Workstation.Apache 2.0
- AlicenseNot gradedqualityDmaintenanceThis MCP server connects Claude Desktop to a Velociraptor instance and local forensic tools. It enables remote endpoint investigation and local evidence analysis through natural language commands.1MIT
Related MCP Connectors
Security-first WordPress MCP server. 129 tools for Claude, ChatGPT, Gemini. Free on wp.org.
Security scanner for MCP servers. Detect vulnerabilities, prompt injection, and tool poisoning.
MCP server for Pentest-Tools.com: run scans, manage findings and reports via your preffered LLM.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/INFOKOM-KI/Wazuh-MCP-Server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server