klaxon
Klaxon is an MCP server that provides a natural language, read-only interface to a Wazuh 5 SIEM cluster, enabling plain-language investigation, schema analysis, decoder debugging, and diagnostic querying.
search: Run raw OpenSearch query DSL against any Wazuh 5 index pattern; returns full JSON with aggregations and a diagnostics block for empty or truncated results.
schema: List fields of an index and show which are actually populated, helping avoid aggregations on empty fields (e.g.,
agent.idvs.wazuh.agent.id).field_coverage: Measure the percentage of documents carrying values per field, both in a time window and across the entire datastream, to detect normalization changes.
findings_overview: Pre-built summary of security findings by severity, agent, rule title, and category, needing no query DSL.
logtest: Push a raw log line through the decoder chain to see matched decoders, normalized output, and where the chain stopped; essential for debugging empty fields.
manager: Read-only passthrough to the Wazuh manager REST API (e.g.,
/agents) for agent and cluster info.detectors: List or fetch OpenSearch Security Analytics detectors that produce findings.
tester_sessions: List available logtest environments to avoid "environment does not exist" errors (which return HTTP 200 with a buried error).
Enables querying OpenSearch indices, retrieving schema and field coverage, and running aggregations for security analytics investigation.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@klaxonShow me blocked connections by source country in the last 24 hours."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Klaxon
The alarm tells you that. Klaxon tells you what.
Klaxon is a read-only proxy in front of your Wazuh 5 indexer. A language model asks questions in plain language; Klaxon queries the indexer, reads the schema, tests decoders, and reports what it actually found — including when it found nothing, and why. Works with Claude Desktop, Claude Code, local models through Ollama, and Open WebUI.
Every query runs through Klaxon, and the response is masked before it reaches
an external LLM: a value under a configured field (user.name, source.ip, …)
always becomes the same deterministic token ([USER_…], [IP_…]), aggregation
keys included. This is pseudonymization, not anonymization — tokens are
deterministic and reversible by anyone holding the salt (see
LLM-safety guarantees).
Quick start
Requirements
Wazuh 5.x indexer reachable over HTTPS (
search/schemaalso work against 4.x)Python 3.11+ or Docker
an MCP client — Claude Desktop, Claude Code,
ollmcp, Open WebUI 0.6.31+
1. Install
python3 -m venv .venv
.venv/bin/pip install klaxon-mcpOr build the Docker image (klaxon-mcp is the entry point):
docker build -t klaxon-mcp .2. Point it at your indexer
export KLAXON_INDEXER_URL=https://indexer.example:9200
export KLAXON_INDEXER_USER=wazuh-readonly
export KLAXON_INDEXER_PASSWORD=...KLAXON_INDEXER_URL is the only required variable. Add KLAXON_MANAGER_URL for
manager/detectors and KLAXON_ENGINE_URL for tester_sessions; set
KLAXON_VERIFY_SSL=false only for a self-signed lab cluster.
3. Enable masking (recommended for external LLMs)
Masking is off by default and opt-in:
export KLAXON_ANONYMIZE_EXTERNAL_LLM=true # mask tool output for external models
export KLAXON_ANONYMIZATION_SALT=change-me-to-a-long-random-secret # stable tokensWith the switch on, output is masked unless KLAXON_LLM_BASE_URL points at a
loopback address (http://localhost:11434 for Ollama) — a local model keeps
receiving unchanged data. An optional config.yaml (KLAXON_CONFIG) holds only
what you change; environment variables always win:
anonymization:
mask_fields: # or KLAXON_ANONYMIZATION_MASK_FIELDS
- "source.ip"
- "user.name"
- "host.hostname"
mask_aggregation_keys: true # ON by default; false disables agg-key masking4. Start it
klaxon-mcp # stdio — your MCP client spawns it (klaxon is an alias)With Docker: docker run --rm -i --env-file .env klaxon-mcp.
5. First masked result
Ask your client: "Show me the last login by user.name=alice in
wazuh-events-v5-*." Klaxon runs search(index="wazuh-events-v5-*", body=…) and returns the masked response:
{
"hits": { "hits": [ { "_source": {
"user": { "name": "[USER_9f2a1c467dd5e2b8]" },
"source": { "ip": "[IP_5c01e73f9a2b4c1d]" },
"message": "user [USER_9f2a1c467dd5e2b8] logged in via ssh from [IP_5c01e73f9a2b4c1d]"
} } ] }
}The same value always maps to the same token. Masking is pseudonymization, not
anonymization, and it has documented blind spots — see
docs/llm-safety.md (in particular the verified leaks in
"Known limitations") before pointing an external model at Klaxon.
Related MCP server: wazuh-mcp
Basic usage
The handful of tools a normal user needs (full reference:
docs/TOOLS.md):
Tool | What it does | One-liner example |
| Any query against any index, raw JSON back |
|
| Which fields exist — and which actually carry data |
|
| How complete each field is, window vs all history |
|
| Findings by severity, agent, title, category |
|
| Push a raw line through the decoder chain |
|
| Find sensitive fields the mask list should cover |
|
| Read-only security posture: facts + gaps, no verdict |
|
On an unfamiliar cluster, start with field_coverage. Every thin result gets a
notice block before the data (empty aggregation, capped size, missing index —
all return HTTP 200 with nothing).
Configuration (essentials)
The keys a normal user changes day to day. Full reference: docs/configuration.md.
Variable / key | What it does | Default |
| Indexer endpoint | — (required) |
| Basic-auth credentials | empty |
| Master masking switch |
|
| Secret for token derivation (stable tokens) | random+persisted |
| Fields masked wholesale ( | built-in list |
| Mask aggregation bucket keys too |
|
| Mask usernames inside free text |
|
| TLS verification |
|
| Required bearer token when serving over HTTP | empty |
Advanced topics
The deep material lives in dedicated docs — linked, not duplicated:
GDPR plausibility checker (classification layers, custom rules, sampling, reports) →
docs/gdpr-checker.mdIngest masking / Option B masked stream (pipeline, ISM, index templates, quarantine for masking failures, sync job) →
docs/option-b-masked-stream.mdMulti-tenant setup (
fields.yaml,klaxon masking generate, salt, namespacing) →docs/multi-tenant.mdDrift prevention & CI (pre-commit drift hook, provenance fingerprints, fail-closed startup, sync preflight,
--verify-config) →docs/drift-prevention.mdToken scheme & security model (HMAC, salt, self-test, why 16 hex) →
docs/security-model.mdSecurity concept: brute-force re-identification risk (pseudonymization vs anonymization, salt as secret) →
docs/security-concept.mdSalt rotation runbook (no scheduled rotation; only on suspicion; response-layer + masked-stream paths) →
docs/salt-rotation-runbook.mdLLM-safety guarantees & limits (pseudonymization caveat, residual gate) →
docs/llm-safety.mdRunning it on another machine (HTTP transport, auth, TLS, CORS) →
docs/TOOLS.md,ARCHITECTURE.md
Development
.venv/bin/pip install -e ".[dev]"
.venv/bin/pytest # full suite
.venv/bin/mypy # strict type check
.venv/bin/ruff check srcOption B generator self-tests (see docs/drift-prevention.md):
klaxon masking selftest --tenant customer-a
klaxon masking generate --check # CI/pre-commit drift checkDeploy the masking artifacts to the indexer in one idempotent, ordered,
self-verifying step (preflight + GET-back verification + a _simulate smoke
test; --dry-run / --rollback):
klaxon masking deploy --tenant customer-a --dry-run # plan only, no writes
klaxon masking deploy --tenant customer-a # needs KLAXON_INDEXER_*Remove the Option B masking infrastructure from the indexer cleanly, leaving the
raw Wazuh streams untouched (destructive — preview with --dry-run; a
mandatory verification phase proves nothing klaxon-* is left and the raw
streams are intact):
klaxon masking teardown --tenant customer-a --dry-run # plan only, no writes
klaxon masking teardown --tenant customer-a --yes # needs KLAXON_INDEXER_*
klaxon masking teardown --tenant customer-a --yes --purge-sync-state
# ^ also delete the sync checkpoint marker (default: keep it so a future
# re-setup can resume from the last checkpoint)The live integration test (klaxon masking test) needs real indexer credentials —
see docs/option-b-masked-stream.md.
Release history: CHANGELOG.md.
Documentation
docs/TOOLS.md— full tool reference & parametersdocs/configuration.md— complete configuration referencedocs/gdpr-checker.md— the GDPR plausibility checkerdocs/option-b-masked-stream.md— ingest-side maskingdocs/multi-tenant.md— multi-tenant setupdocs/drift-prevention.md— drift prevention & CIdocs/security-model.md— token scheme & security modeldocs/security-concept.md— pseudonymization / brute-force re-identification riskdocs/salt-rotation-runbook.md— salt rotation runbook (only on suspicion)docs/llm-safety.md— masking guarantees & limitsARCHITECTURE.md— design rationaleCHANGELOG.md— release history
License
Apache-2.0 — see LICENSE.
Built by sec73 GmbH.
Wazuh is a registered trademark of Wazuh Inc. Klaxon is an independent project and is not affiliated with, endorsed by, or sponsored by Wazuh Inc.
Maintenance
Related MCP Servers
- FlicenseBqualityDmaintenanceA Model Context Protocol server that enables querying and analyzing Wazuh security logs stored in OpenSearch, with features for searching alerts, getting detailed information, generating statistics, and visualizing trends.92
- 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.28233MIT
- AlicenseAqualityAmaintenanceAI-powered MCP server that enables security analysts to query Wazuh SIEM/XDR for alert triage, threat hunting, compliance audits, and incident response through natural language prompts.2813MIT
- AlicenseNot gradedqualityDmaintenanceA production-ready Model Context Protocol (MCP) server for seamless integration between Wazuh SIEM and Large Language Models (LLMs).89AGPL 3.0
Related MCP Connectors
MCP server providing access to the Scorecard API to evaluate and optimize LLM systems.
GibsonAI MCP server: manage your databases with natural language
Official Microsoft MCP Server to query Microsoft Entra data using natural language
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/sec73/klaxon'
If you have feedback or need assistance with the MCP directory API, please join our Discord server