Skip to main content
Glama
chiomao23

mcp-hayabusa

by chiomao23
README.md
# mcp-hayabusa

MCP server that wraps the [Hayabusa](https://github.com/Yamato-Security/hayabusa) CLI for EVTX (Windows Event Log) analysis, exposing `scan_evtx` and `get_hayabusa_rules` tools.

## Prerequisites

- Python 3.10+ (this machine's default `python`/`py` is 3.8 — use `py -3.13` explicitly; see below)
- The Hayabusa binary — `download_hayabusa.py` (below) fetches it into `./hayabusa/`, which `server.py` finds automatically. Alternatively, set `HAYABUSA_PATH` or put `hayabusa` on `PATH`.

## Setup

```
py -3.13 -m pip install -r requirements.txt
py -3.13 download_hayabusa.py   # downloads Hayabusa for this platform into ./hayabusa/
```

`server.py` finds the downloaded binary automatically — no env var needed. On Linux, set `HAYABUSA_LIBC=musl` at download time if you need the musl build instead of the glibc default.

## Run

```
py -3.13 server.py
```

This starts the server on stdio, for use with an MCP client (e.g. Claude Code, Claude Desktop).

## Tool: `scan_evtx`

| Argument       | Type | Default    | Description                                                        |
|----------------|------|------------|----------------------------------------------------------------------|
| `evtx_path`    | str  | required   | Path to a single `.evtx` file to scan                              |
| `min_severity` | str  | `medium`   | Minimum severity to include: `informational`, `low`, `medium`, `high`, `critical` |

Returns a formatted JSON string (`total_detections` + a `detections` array), or `{"error": ...}` on failure (missing file, missing Hayabusa binary, non-zero exit, timeout, locked/inaccessible file, invalid `min_severity`).

## Tool: `get_hayabusa_rules`

| Argument  | Type | Default  | Description                                                                 |
|-----------|------|----------|------------------------------------------------------------------------------|
| `keyword` | str  | `""`     | Case-insensitive substring matched against each rule's title/id/tags/category. Empty = all rules. |
| `limit`   | int  | `50`     | Max rules returned, clamped to `[1, 500]` (there are ~5000 rule files total) |

Returns a formatted JSON string: `total_rules_scanned`, `total_matches`, `returned`, `truncated`, and a `rules` array (each with `title`, `id`, `level`, `status`, `category`, `tags`, `source`, `path`), sorted highest-severity-first. The first call per server process takes a few seconds (parsing ~5000 YAML rule files); results are cached in memory afterward, so subsequent calls are near-instant regardless of `keyword`/`limit`.

## Status

Verified against a real, locally downloaded Hayabusa v3.10.0 and real EVTX data (including a locked live Windows event log, to confirm error handling). See `CLAUDE.md` for architecture notes and known gaps.