Teaching an LLM to hunt threats: building the Wazuh MCP server
Most SIEM tooling was never built with language models in mind. This is the story of wiring an LLM directly into Wazuh: 28 tools, nine security domains, and the design decisions that made it safe to run.
Most SIEM tooling was never built with language models in mind. The APIs assume a human clicking through dashboards, one query at a time and one panel at a time. But an LLM agent doesn't work like that. It reasons across domains at once: it wants to pull an alert, check the agent's health, cross-reference a MITRE technique, and look at vulnerability posture in the same breath.
So I built the bridge. sb-siem-mcp is a Model Context Protocol server that connects LLM agents (Claude, DeepSeek, Copilot) directly to Wazuh SIEM. Twenty-eight tools across nine security domains: alert analysis, threat hunting, compliance checks, agent management, vulnerability data, and incident response, all through natural language.
#Why MCP, and why now
The Model Context Protocol gives an agent a typed, discoverable contract with an external system. Instead of prompt-engineering an LLM to generate raw Wazuh API calls (fragile, dangerous), MCP lets you define exactly what the agent can do and, more importantly, what it can't.
That distinction is the entire project. A SIEM is a high-privilege system. An agent with unrestricted API access is an incident waiting to happen. The design question was never "how do I connect an LLM to Wazuh". It was "how do I connect an LLM to Wazuh without regretting it."
#The architecture
The server is built on FastMCP and ships as a Docker container. The shape of it:
LLM agent (Claude / DeepSeek / Copilot)
│ MCP protocol
▼
sb-siem-mcp ── RBAC layer
│ rate limiting
│ input validation
│ audit logging
│ output sanitization
▼
Wazuh manager API
Every tool call passes through the same defense-in-depth chain before it touches Wazuh:
- RBAC: tools are grouped by domain, and each deployment declares which domains the agent may use. A triage agent gets read-only alert tools; it never sees agent-management endpoints.
- Rate limiting: an agent in a reasoning loop can fire requests far faster than any analyst. Hard caps stop a runaway loop from hammering the manager.
- Input validation: every parameter is schema-validated before it becomes an API call. No string interpolation into queries, ever.
- Audit logging: every tool invocation is logged with its full context. If the agent did it, there's a record.
- Output sanitization: responses are stripped and shaped before they re-enter the agent's context, which keeps injection-carrying log content from steering the model.
That last one deserves its own post. Logs are attacker-controlled data. If an attacker knows an LLM will read their failed SSH banner, they will put instructions in it. Sanitizing the output path matters as much as the input path.
#What it actually feels like
The difference in investigation speed is the point. A typical triage question, "show me the top brute-force sources in the last 24 hours, check whether any of those agents have critical vulnerabilities, and summarize what happened", is a multi-panel, multi-query journey in a dashboard. Through the MCP server it's one sentence, and the agent orchestrates the tool calls itself. Mean time to investigate drops from minutes to seconds.
#What I'd do differently
Honest notes from the build:
- Start with fewer tools. I built broad first, 28 tools, then hardened. Security posture would have been cleaner going deep on five tools, then expanding.
- Design the RBAC model before the tools. Retrofitting permissions onto an existing tool surface is exactly as painful in MCP as it is everywhere else.
- Treat the agent as an untrusted user from day one. Not because the model is malicious, but because the data it reads might be.
The project is open source under MIT, and the repo has the full tool catalog, deployment guide, and threat model: sb-siem-mcp on GitHub.
If you run Wazuh and you've been wondering what agentic tooling actually looks like in a SOC context, this is one answer, built in the open. Issues and PRs welcome.
Written by Subhash Bharadwaj in Bengaluru. Say something back →