EvoHub Docs Sign in

Integrations

Wazuh

Use with AI
View as MarkdownThis page as plain text, for pasting into an AI tool Open in ClaudeAsk Claude questions about this page Open in ChatGPTAsk ChatGPT questions about this page
Connect to Cursor / VS Code / ClaudeSearch and read these docs from your AI tool (MCP server)

MCP server URL

https://docs-dev.evohub.io/mcp

Claude Code

claude mcp add --transport http evohub-docs-docs https://docs-dev.evohub.io/mcp

Claude (claude.ai and Claude Desktop): Settings → Connectors → Add custom connector, and paste the URL above.

Claude Desktop — claude_desktop_config.json

{
  "mcpServers": {
    "evohub-docs-docs": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://docs-dev.evohub.io/mcp"
      ]
    }
  }
}

Cursor — ~/.cursor/mcp.json

{
  "mcpServers": {
    "evohub-docs-docs": {
      "url": "https://docs-dev.evohub.io/mcp"
    }
  }
}

VS Code — .vscode/mcp.json

{
  "servers": {
    "evohub-docs-docs": {
      "type": "http",
      "url": "https://docs-dev.evohub.io/mcp"
    }
  }
}

Wazuh has no webhook of its own: its integrator daemon runs a script for every alert at or above a level you choose. EvoHub provides that script. It posts the alert exactly as Wazuh wrote it, and uses only Python's standard library and the Python that ships with the Wazuh manager.

Set it up

Create the integration

In EvoHub, go to On-Call → Integrations → + Add Integration, choose Wazuh, pick an Escalation Policy and click Create Integration. Copy the Webhook URL.

Install the script

On the Wazuh manager, save the script below as /var/ossec/integrations/custom-evohub, then make it executable by the wazuh group:

chmod 750 /var/ossec/integrations/custom-evohub
chown root:wazuh /var/ossec/integrations/custom-evohub

Test the connection

Run the script once by hand. EvoHub answers with success and opens no alert:

/var/ossec/integrations/custom-evohub --test 'https://evohub.io/ingest/wazuh?key=YOUR_INTEGRATION_KEY'

Turn on the integration

Add the block below to /var/ossec/etc/ossec.conf, inside <ossec_config>, and restart the manager with systemctl restart wazuh-manager.

Script (/var/ossec/integrations/custom-evohub):

#!/var/ossec/framework/python/bin/python3
# EvoHub On-Call — Wazuh custom integration.
# Install as /var/ossec/integrations/custom-evohub (root:wazuh, mode 750).
# integratord runs it as: custom-evohub <alert file> <api key> <hook url>
# Test by hand:           custom-evohub --test <hook url>
import json
import sys
import urllib.error
import urllib.request


def post(url, payload):
    req = urllib.request.Request(
        url,
        data=json.dumps(payload).encode("utf-8"),
        method="POST",
        headers={"Content-Type": "application/json", "User-Agent": "evohub-wazuh/1"},
    )
    try:
        with urllib.request.urlopen(req, timeout=10) as resp:
            resp.read()
        return 0
    except urllib.error.HTTPError as e:
        sys.stderr.write("evohub: EvoHub answered HTTP %d\n" % e.code)
    except (urllib.error.URLError, OSError) as e:
        sys.stderr.write("evohub: could not reach EvoHub: %s\n" % getattr(e, "reason", e))
    return 1


def main(argv):
    if len(argv) == 3 and argv[1] == "--test":
        return post(argv[2], {"evohub_test": True})
    if len(argv) < 4:
        sys.stderr.write("usage: custom-evohub <alert file> <api key> <hook url>\n")
        return 2
    with open(argv[1], encoding="utf-8") as f:
        alert = json.load(f)
    return post(argv[3], alert)


if __name__ == "__main__":
    sys.exit(main(sys.argv))

ossec.conf:

<integration>
  <name>custom-evohub</name>
  <hook_url>https://evohub.io/ingest/wazuh?key=YOUR_INTEGRATION_KEY</hook_url>
  <level>10</level>
  <alert_format>json</alert_format>
</integration>

Every alert at level 10 or higher is sent. Add <group> or <rule_id> to the block to send only some rules, or lower the level to send more. If the script cannot reach EvoHub it prints the reason — never the URL — and exits with an error.

Note

The first line of the script points at the Python bundled with Wazuh. If your manager has its own Python 3, #!/usr/bin/env python3 works too.

What EvoHub reads

EvoHub alert Taken from
Title rule.description and the agent name, for example sshd: brute force trying to get access to the system. Authentication failed. – web-01.
Description full_log, followed by the log location.
Labels rule_id, rule_level, groups, mitre_id, mitre_tactic, agent_id, agent_name, agent_ip, manager, decoder, location, alert_id, timestamp and, when the decoder found them, srcip, srcport, srcuser, dstuser, dstip.

Severity

Wazuh rule level EvoHub severity
12 and above critical
10–11 high
7–9 medium
4–6 low
below 4 info

Resolve and deduplication

An alert is identified by the rule and the agent. While it is open, the same rule firing again on the same agent is recorded as Retriggered instead of paging again; the same rule on another agent is a separate alert.

Wazuh alerts are events and Wazuh sends no recovery, so alerts stay open until someone resolves them in EvoHub.

Last updated