wrg-sigma-rules
This MCP server lets you author, validate, and convert Sigma detection rules, turning natural-language threat descriptions into SIEM-native queries.
Draft Sigma rules from a plain-English threat description, optionally specifying MITRE TTPs, references, title, severity, rule type, and target platform.
Validate Sigma rules for schema correctness, pySigma compatibility, and best-practice linting; strict mode escalates warnings to errors.
Convert Sigma rules to Splunk SPL, Elasticsearch/Kibana Lucene, or Wazuh queries, with lossiness warnings for unsupported constructs.
Get structured results including YAML output, validation results, inferred MITRE technique IDs, draft notes, and actionable dependency-install errors.
Explore the published corpus of 296 rules across 14 ATT&CK tactic categories and coverage resources, including a computed MITRE ATT&CK matrix.
WRG Sigma Rules
Sigma detection-rule authoring, validation and multi-backend conversion, delivered as a Model Context Protocol (MCP) server with a published rule corpus. It runs under Claude Code, Codex, Cursor and any MCP-capable client.
What it does
Three MCP tools.
draft_ruleturns a natural-language description into a Sigma YAML scaffold.validate_rulechecks a rule against pySigma plus a best-practice linter.convert_rulecompiles a rule to a Splunk, Elastic, OpenSearch, Wazuh or Kibana query.Three Claude Code skills:
sigma-rule-writer,sigma-rule-reviewerandthreat-coverage-gap-analyzer. The packaged Codex variants retain the same evidence boundaries: coverage counts do not establish missing ATT&CK scope, conversion does not establish deployed semantics, andobserved_*public contributions require the sourcing bar inCONTRIBUTING.md.A published corpus of 296 rules across 14 MITRE ATT&CK tactic categories. Every rule carries an honest Sigma
status:(see Rule status).Multi-backend conversion on pySigma 1.x: Splunk SPL, Elastic and Kibana Lucene, OpenSearch Lucene and PPL, plus Wazuh. The Lucene-family targets cannot express Sigma correlation rules, so
convert_rulereports thecorrelation rules in the corpus as a capability gap and names the backends that can convert them.
The plugin is installed directly from this repository; it is not yet listed in a plugin marketplace.
Related MCP server: Wazuh SIEM Agent System
Install
The server is a single stdio MCP process (server.py). Each client points at it
in its own way.
Claude Code
git clone https://github.com/WRG-11/wrg-sigma-rules.git
cd wrg-sigma-rules
pip install -r requirements.txt
claude plugin validate .requirements.txt is not optional: validate_rule needs pySigma, convert_rule
needs the backend packages, and the pipeline packages drive the logsource
mapping. The repo ships .claude-plugin/plugin.json and .mcp.json (which wires
server.py through ${CLAUDE_PLUGIN_ROOT}). Point your Claude Code plugin
configuration at this checkout per
the plugin docs.
Codex
codex plugin marketplace add .
codex plugin add wrg-sigma-rules@wrg-11The Codex plugin carries a self-contained runtime snapshot of the server and
corpus, so its installed cache does not rely on checkout-relative paths. Keep it
current with python scripts/sync_codex_runtime.py. Check parity without
rewriting the snapshot via python scripts/sync_codex_runtime.py --check; CI
fails if it drifts. A Codex package may add a local build suffix to its version,
but its release base is regression-checked against the server manifest.
Snapshot parity proves packaged source and corpus identity, not that a
particular client has provisioned a compatible Python environment or refreshed
its installed cache. CI installs the bundled runtime requirements on a clean
runner and completes a package-wrapper MCP handshake, but that remains a
Python-runtime check rather than evidence that a particular client refreshed
its installed cache. After installation, verify a real MCP handshake in the
target client before treating the package as ready.
The repository smoke harness bounds every protocol reply, so an unresponsive
server fails the check rather than consuming the workflow timeout.
Cursor
Cursor speaks MCP directly, so the same server works with no plugin manifest. Add
it to your project .cursor/mcp.json (or the global ~/.cursor/mcp.json):
{
"mcpServers": {
"wrg-sigma-rules": {
"command": "python",
"args": ["/path/to/wrg-sigma-rules/server.py"],
"cwd": "/path/to/wrg-sigma-rules",
"env": { "PYTHONPATH": "/path/to/wrg-sigma-rules" }
}
}
}Replace the path with your clone, then reload Cursor's MCP servers.
Any MCP client
server.py is a standard stdio MCP server, so Cline, Continue, Zed and Windsurf
load it with the same mcpServers block shown for Cursor. MCP is model-agnostic:
the client's backend model does not change what the server exposes.
Quick example
Validate and convert a corpus rule end to end, from the repo root:
pip install pysigma pysigma-backend-splunk pysigma-backend-elasticsearchimport sys, json
sys.path.insert(0, '.')
from tools.validate_rule.validate_rule import validate_rule_body
from tools.convert_rule.convert_rule import convert_rule_body
rule = open('resources/examples/command_and_control/observed_mini_shai_hulud_npm_supply_chain_c2_t1071.yml', encoding='utf-8').read()
print(json.dumps(validate_rule_body(rule), indent=2))
print(json.dumps(convert_rule_body(rule, target='splunk'), indent=2))
print(json.dumps(convert_rule_body(rule, target='elasticsearch'), indent=2))Full captured output (validate JSON, Splunk SPL, Elasticsearch Lucene) is in
DEMO.md.
The corpus
Every rule lives under resources/examples/<tactic>/ and is one of two kinds:
template_*: a canonical detection shape to adapt to your own environment.observed_*: derived from a specific, cited incident.CONTRIBUTING.mdsets the bar these must clear.
resources/examples/INDEX.json enumerates every
rule, and the wrg-sigma://coverage/mitre-attack-matrix resource computes the
technique-by-tactic breakdown from the corpus at read time. Some rules add a
prose write-up under docs/detection-notes/.
Rule status
This corpus uses Sigma's status: field literally rather than aspirationally:
| Count | Meaning here |
| 82 | Derived from a real, cited incident (the |
| 214 | Canonical detection shapes, many self-described as synthetic exemplars |
| 0 | Unused, deliberately |
stable in the Sigma specification means a rule runs in production and is well
tested. Nothing here has earned that, so nothing claims it. Treat every rule as a
starting point to bind to your own logsource and tune; each rule's
falsepositives: block names the benign activity to expect first.
Resources
wrg-sigma://patterns/canonical-5andwrg-sigma://patterns/canonical-5/{01..05}: canonical detection-pattern definitions.wrg-sigma://coverage/mitre-attack-matrix: an ATT&CK coverage rollup computed from the corpus at read time. ItsRules-content SHA-256identifies the exact corpus bytes behind a count, so installed and checkout runtimes can be compared without treating different releases as measurement drift.
Quality and testing
modules cover rule validation and tool-integration smoke tests.
pySigma 1.x compatibility is verified against the Splunk, Elasticsearch and OpenSearch backend packages.
CI runs the full suite on Ubuntu, Windows and macOS runners on every push.
The Docker CI smoke exchange compares the container coverage resource's corpus fingerprint with the checked-out corpus, so an otherwise healthy image cannot silently serve stale rule data.
README counts are stamped from ground truth:
python readme_stamp.py --checkfails CI on any drift, so the numbers here cannot silently go stale.To compare an installed or cached Codex runtime with this checkout without modifying either one, run
python scripts/runtime_identity.py --runtime-root <runtime-path> --expect-same-as .. A match proves only local runtime/corpus identity. Itsrule_tree_sha256is a file-tree comparison digest, not the live MCP coverage resource's identity; neither value claims marketplace publication or a client cache refresh.
Evidence-review audits
The following local reports make review queues and conversion boundaries
visible. They are advisory: none promotes a rule, proves an actor attribution,
or replaces reading the cited source. Pass --examples-dir (and, where
applicable, --notes-dir) when auditing a copied or isolated corpus; a missing
examples directory is an error rather than an empty result.
The correlation-conversion audit also fails clearly if any selected corpus YAML
file cannot be read, decoded, or parsed; a partial conversion count is not a
reproducible measurement.
The observed-evidence inventory likewise fails clearly on unreadable or
invalid observed-rule YAML and unreadable detection notes, rather than
publishing a partial provenance inventory.
The detection-note gap report uses the same rule and note input boundary, so a
partial documentation queue cannot be mistaken for a complete review queue.
python scripts/observed_evidence_inventory.py --examples-dir resources/examples
python scripts/duplicate_rule_check.py --examples-dir resources/examples --exact-actor-logic
python scripts/duplicate_rule_check.py --examples-dir resources/examples --actor-review-queues
python scripts/correlation_conversion_audit.py --examples-dir resources/examples
python scripts/detection_note_gap.py --examples-dir resources/examples --notes-dir docs/detection-notesUse --json path/to/report.json with any report when a review needs a
machine-readable snapshot; the advisory reports carry their scope limitation
inside that JSON so a copied count is not detached from its evidence boundary.
Each report creates the parent directory of its --json target, so the same
automation path can be used across all four tools.
Object-shaped report payloads carry contract.tool and contract.version;
consumers should ignore unknown keys and only treat a version change as a
compatibility boundary. duplicate_rule_check preserves its legacy bare-list
default JSON for existing consumers; pass --json-envelope to receive its
versioned {contract, groups, limitations} form.
That option only changes the default fingerprint report: the exact-logic and
actor-review-queue modes always write their own versioned envelopes when
--json is supplied.
--actor-review-queues instead writes a versioned envelope with three separate
mechanical queues: exact logic, same comparison shape with different numeric
thresholds, and shared adjacent sidecar bytes. They are source-review inputs,
not semantic-equivalence, attribution, provenance, or consolidation verdicts.
Versioned duplicate-report envelopes also carry skipped_files for YAML files
that the selected mode could not read, decode, or parse. The legacy default
bare-list JSON remains unchanged; use --json-envelope when that visibility is
needed in a default-mode automation.
For a fixed corpus and option set, report arrays are emitted deterministically;
JSON object-member order is not a compatibility guarantee, so consumers should
parse fields rather than byte-diff raw JSON.
The inventory retains its attribution, platform and
telemetry-manifestation fields as not_assessed until a human has documented
the three source matches in CONTRIBUTING.md. Those
review records live under docs/source-reviews/: each
must cite a URL already on the rule, record a review date that is not in the
future, and include a source quote for every supported or not-supported
conclusion. The inventory rejects malformed or future-dated records rather
than treating them as evidence; source or rule drift still requires human
re-review.
It also records the literal presence of WRG breach catalog and whether a
multi-document rule keeps references only in a later document. Both are public
traceability review cues, never source-quality or attribution verdicts.
The JSON report preserves the public reference lists (including their
first/later-document split) for human review, without assigning source ranks.
Its summary distinguishes a structured review record, completion of all three
source matches, and an explicit unsupported boundary; none of those counts is
an attribution or promotion decision.
public_traceability_queue is a convenience subset for the two mechanical
public-review cues; it is not a verdict about a rule or its sources.
For per-rule JSON, prefer reference_shape and
is_mentioned_by_detection_note: both are literal inventory facts, not source
quality or note-endorsement labels. The older reference_hygiene and
has_companion_note fields remain compatibility aliases with identical values.
The correlation audit separately counts a backend's declared capability
boundaries (for example, correlation_rules or
correlation_type:temporal_ordered). A successful conversion remains syntax
evidence only; it does not assert equivalent alert behavior in a deployed SIEM.
Contributing
Contributions are welcome. Add YAML under resources/examples/<tactic>/ with an
ATT&CK mapping in tags: (for example attack.t1071), the observed_* or
template_* prefix, and a passing validate_rule. Corpus CI rejects broad empty
matches, unsafe regex, unroutable logsource blocks, draft scaffolding and
deprecated aggregation-pipe syntax.
Read CONTRIBUTING.md before submitting an observed_* rule.
It sets the sourcing bar (attribution, platform and manifestation, each matched
against the cited source) and documents the three upstream rejections that
produced it.
See ROADMAP.md for the repository's current direction, explicit
product boundaries and evidence required before an item is considered complete.
License
MIT; see LICENSE. One license covers both the tooling (server.py,
tools/, scripts/) and the corpus (resources/). That is a deliberate choice
for frictionless reuse by SOC teams adapting a rule into their own tooling, over
the attribution-preserving split that some Sigma corpora use.
Runtime dependencies bring in LGPL-2.1/3.0 packages (pySigma and its backends)
alongside MIT, BSD and Apache ones. Importing an LGPL library does not make this
repo's own code LGPL. The dependency-licenses CI job carries the re-derivable
list.
Part of the WRG-11 ecosystem
mcp-objauthz-lab: a vulnerable-by-design MCP server for learning BOLA and IDOR.
osint-trust-envelope: honest trust envelopes for OSINT results.
Full index at github.com/WRG-11.
Available Tools
3 toolsconvert_ruleA
Convert a sigma YAML rule into a SIEM-native query string.
Use when the caller has a validated sigma rule and needs the equivalent query for Splunk SPL, Elasticsearch / Kibana Lucene, or Wazuh. Returns the primary converted query plus conversion lossiness warnings (e.g. unsupported modifiers). Missing pySigma or missing backend packages return actionable error envelopes with the exact pip install command.
| Name | Required | Description | Default |
|---|---|---|---|
| yaml_content | Yes | ||
| target | No | splunk | |
| config | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description carries the full burden. It discloses successful output (converted query + warnings) and failure modes (missing pySigma or backend packages yield actionable pip install commands). Does not discuss auth or rate limits, but these are irrelevant for a conversion tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the main action and uses a clear structure: purpose, usage, details. It is concise with three sentences, no redundant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 3 parameters, no annotations, and an output schema (not shown), the description covers purpose, usage, primary output, and error handling. It lacks parameter explanations but is adequate for a simple conversion tool when combined with the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%. The description only implicitly associates yaml_content with the sigma rule and target with backend names, but does not explain the config parameter or enumerate target options. It adds limited semantic value beyond the raw schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it converts a sigma YAML rule to a SIEM-native query string, specifying three target backends. It distinguishes from sibling tools 'draft_rule' and 'validate_rule' by focusing on conversion rather than drafting or validation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use when the caller has a validated sigma rule' and lists target SIEMs. Does not explicitly exclude alternatives, but the context is clear. Mentions return of conversion warnings and error envelopes for missing dependencies.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
draft_ruleA
Draft a sigma detection YAML rule from a natural-language threat description.
Use when the caller needs a starting-point sigma rule and only has a plain-English threat summary plus optional MITRE TTP hints. Returns a structured envelope with the YAML body, a pySigma round-trip validation result, the inferred MITRE technique IDs, and draft notes covering redactions + open issues. Tool is deterministic and local -- no network, no LLM call.
| Name | Required | Description | Default |
|---|---|---|---|
| description | Yes | ||
| rule_type | No | process_creation | |
| references | No | ||
| target_platform | No | windows | |
| severity | No | medium | |
| mitre_ttps | No | ||
| title | No | ||
| author | No | WRG sigma-rule-writer |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses key behavioral traits: deterministic, local, no network or LLM call, and describes the return envelope contents. No annotations are provided, so the description carries the transparency burden well.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and front-loaded with the core purpose. It efficiently communicates usage context and behavior without unnecessary words, though could be slightly more structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the 8 parameters (1 required) and no schema descriptions, the description adequately covers the main input and optional MITRE hints but lacks detail on other parameters. The output schema is mentioned, which adds completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, yet the description only explains the 'description' and 'mitre_ttps' parameters. Other parameters like rule_type, references, target_platform, severity, title, and author are left unspecified, requiring inference from defaults.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool drafts a sigma detection YAML rule from natural language, distinguishing it from sibling tools convert_rule and validate_rule.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: when a starting-point sigma rule is needed from a plain-English threat summary. Does not mention when not to use or discuss alternatives explicitly, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_ruleA
Validate a sigma YAML rule for schema correctness, pySigma compatibility, and best-practices linting.
Use when the caller has a sigma rule (drafted, pasted, or
read from disk) and needs to know whether it is parseable, spec
compliant, and free of common quality smells (empty references,
missing falsepositives, missing MITRE tag, vague condition).
``target_backend`` is informational at this layer; the linter is
backend-agnostic. ``strict=True`` promotes warnings into the
error list.
| Name | Required | Description | Default |
|---|---|---|---|
| yaml_content | Yes | ||
| target_backend | No | default | |
| strict | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It describes specific checks (empty references, missing falsepositives, missing MITRE tag, vague condition). It also notes strict mode behavior and that target_backend is informational. No side effects mentioned but no destructive hints either.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise at ~80 words, front-loaded with purpose. Every sentence adds value. No repetition or fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given output schema exists (not shown), return values need not be explained. Description covers validation specifics, sibling differentiation, and parameter roles. Could briefly mention that it returns a list of issues, but output schema likely covers that.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so description compensates. It explains yaml_content is the rule to validate, target_backend is informational, and strict promotes warnings to errors. Adds meaningful context beyond bare parameter names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool validates sigma YAML rules for schema correctness, pySigma compatibility, and best-practices linting. It distinguishes from siblings (convert_rule, draft_rule) by focusing on validation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit use cases are given (rule drafted, pasted, or read from disk). It mentions when to use it: to check parseability, spec compliance, and quality. Does not explicitly state when not to use it but provides clear context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v1.0.0- First observed
convert_rule - First observed
draft_rule - First observed
validate_rule
TDQS
Scored across 3 tools
Each tool has a clear, non-overlapping purpose: drafting, validating, and converting Sigma rules. There is no ambiguity between them.
All tool names follow the consistent verb_noun pattern (convert_rule, draft_rule, validate_rule), making them predictable and easy to understand.
Three tools perfectly cover the core lifecycle of Sigma rules (create, validate, convert) without being too few or excessive.
The tool set provides a complete workflow for handling Sigma rules: drafting from description, validating for correctness, and converting to SIEM queries. No obvious gaps exist.
Maintenance
Related MCP Connectors
55 tools, 7 Resources, Sigma rules, email SPF/DMARC, MITRE, CVE/KEV, risk_score. No key.
AI-security knowledge as MCP: standards-mapped tools (OWASP, NIST, MITRE) for AI agents.
Zero-install security baseline for AI coding agents — OWASP/CWE-cited rules over MCP.
Claude Code / MCP skills for the dev pipeline: discover, spec, design, build, ship, operate.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceUnifies 7,283+ detection rules from Sigma, Splunk ESCU, Elastic, and KQL into a single queryable interface via MCP, with a web dashboard and autonomous agent pipeline for detection engineering.274 npm1Apache 2.0
- FlicenseNot gradedqualityDmaintenanceA Claude-powered MCP tool suite for interacting with a Wazuh SIEM manager, enabling triage, health monitoring, threat hunting, rule management, and active response execution.-
- FlicenseNot gradedqualityCmaintenanceEnables natural-language security operations by connecting Wazuh SIEM to Claude Desktop via MCP, allowing querying of alerts, agents, vulnerabilities, and generating security reports with Slack integration.1-
- AlicenseAqualityAmaintenanceRSigma is a Rust detection-engineering toolkit for the Sigma standard. Its MCP server (rsigma mcp serve) exposes the toolchain to AI agents over stdio or Streamable HTTP, with tools to author, lint, validate, and convert Sigma rules, evaluate and explain detections against log events, and inspect correlation state.15138MIT