security-detections-mcp 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,15 +1,20 @@
1
1
  # Security Detections MCP
2
2
 
3
- An MCP (Model Context Protocol) server that lets LLMs query a unified database of **Sigma** and **Splunk ESCU** security detection rules.
3
+ An MCP (Model Context Protocol) server that lets LLMs query a unified database of **Sigma**, **Splunk ESCU**, **Elastic**, and **KQL** security detection rules.
4
4
 
5
- [![Add to Cursor](https://img.shields.io/badge/Add%20to-Cursor-blue?style=for-the-badge&logo=cursor)](cursor://anysphere.cursor-deeplink/mcp/install?name=security-detections&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsInNlY3VyaXR5LWRldGVjdGlvbnMtbWNwIl0sImVudiI6eyJTSUdNQV9QQVRIUyI6Ii9wYXRoL3RvL3NpZ21hL3J1bGVzLC9wYXRoL3RvL3NpZ21hL3J1bGVzLXRocmVhdC1odW50aW5nIiwiU1BMVU5LX1BBVEhTIjoiL3BhdGgvdG8vc2VjdXJpdHlfY29udGVudC9kZXRlY3Rpb25zIn19)
5
+ [![Install MCP Server](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en/install-mcp?name=security-detections&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsInNlY3VyaXR5LWRldGVjdGlvbnMtbWNwIl0sImVudiI6eyJTSUdNQV9QQVRIUyI6Ii9wYXRoL3RvL3NpZ21hL3J1bGVzLC9wYXRoL3RvL3NpZ21hL3J1bGVzLXRocmVhdC1odW50aW5nIiwiU1BMVU5LX1BBVEhTIjoiL3BhdGgvdG8vc2VjdXJpdHlfY29udGVudC9kZXRlY3Rpb25zIiwiU1RPUllfUEFUSFMiOiIvcGF0aC90by9zZWN1cml0eV9jb250ZW50L3N0b3JpZXMiLCJFTEFTVElDX1BBVEhTIjoiL3BhdGgvdG8vZGV0ZWN0aW9uLXJ1bGVzL3J1bGVzIiwiS1FMX1BBVEhTIjoiL3BhdGgvdG8va3FsLXJ1bGVzIn19)
6
6
 
7
7
  ## Features
8
8
 
9
- - **Unified Search** - Query both Sigma and Splunk ESCU detections from a single interface
10
- - **Full-Text Search** - SQLite FTS5 powered search across names, descriptions, queries, and tags
11
- - **MITRE ATT&CK Mapping** - Filter detections by technique ID (e.g., T1059.001)
9
+ - **Unified Search** - Query Sigma, Splunk ESCU, Elastic, and KQL detections from a single interface
10
+ - **Full-Text Search** - SQLite FTS5 powered search across names, descriptions, queries, MITRE tactics, CVEs, process names, and more
11
+ - **MITRE ATT&CK Mapping** - Filter detections by technique ID or tactic
12
+ - **CVE Coverage** - Find detections for specific CVE vulnerabilities
13
+ - **Process Name Search** - Find detections that reference specific processes (e.g., powershell.exe, w3wp.exe)
14
+ - **Analytic Stories** - Query by Splunk analytic story (optional - enhances context)
15
+ - **KQL Categories** - Filter KQL queries by category (Defender For Endpoint, Azure AD, Threat Hunting, etc.)
12
16
  - **Auto-Indexing** - Automatically indexes detections on startup from configured paths
17
+ - **Multi-Format Support** - YAML (Sigma, Splunk), TOML (Elastic), Markdown (KQL)
13
18
  - **Logsource Filtering** - Filter Sigma rules by category, product, or service
14
19
  - **Severity Filtering** - Filter by criticality level
15
20
 
@@ -46,7 +51,10 @@ Add to your MCP config (`~/.cursor/mcp.json` or `.cursor/mcp.json` in your proje
46
51
  "args": ["-y", "security-detections-mcp"],
47
52
  "env": {
48
53
  "SIGMA_PATHS": "/path/to/sigma/rules,/path/to/sigma/rules-threat-hunting",
49
- "SPLUNK_PATHS": "/path/to/security_content/detections"
54
+ "SPLUNK_PATHS": "/path/to/security_content/detections",
55
+ "ELASTIC_PATHS": "/path/to/detection-rules/rules",
56
+ "STORY_PATHS": "/path/to/security_content/stories",
57
+ "KQL_PATHS": "/path/to/Hunting-Queries-Detection-Rules"
50
58
  }
51
59
  }
52
60
  }
@@ -65,7 +73,10 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
65
73
  "args": ["-y", "security-detections-mcp"],
66
74
  "env": {
67
75
  "SIGMA_PATHS": "/Users/you/sigma/rules,/Users/you/sigma/rules-threat-hunting",
68
- "SPLUNK_PATHS": "/Users/you/security_content/detections"
76
+ "SPLUNK_PATHS": "/Users/you/security_content/detections",
77
+ "ELASTIC_PATHS": "/Users/you/detection-rules/rules",
78
+ "STORY_PATHS": "/Users/you/security_content/stories",
79
+ "KQL_PATHS": "/Users/you/Hunting-Queries-Detection-Rules"
69
80
  }
70
81
  }
71
82
  }
@@ -74,79 +85,260 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
74
85
 
75
86
  ### Environment Variables
76
87
 
77
- | Variable | Description | Example |
78
- |----------|-------------|---------|
79
- | `SIGMA_PATHS` | Comma-separated paths to Sigma rule directories | `/path/to/sigma/rules,/path/to/sigma/rules-threat-hunting` |
80
- | `SPLUNK_PATHS` | Comma-separated paths to Splunk ESCU detection directories | `/path/to/security_content/detections` |
88
+ | Variable | Description | Required |
89
+ |----------|-------------|----------|
90
+ | `SIGMA_PATHS` | Comma-separated paths to Sigma rule directories | At least one source required |
91
+ | `SPLUNK_PATHS` | Comma-separated paths to Splunk ESCU detection directories | At least one source required |
92
+ | `ELASTIC_PATHS` | Comma-separated paths to Elastic detection rule directories | At least one source required |
93
+ | `KQL_PATHS` | Comma-separated paths to KQL hunting query directories | At least one source required |
94
+ | `STORY_PATHS` | Comma-separated paths to Splunk analytic story directories | No (enhances context) |
81
95
 
82
96
  ## Getting Detection Content
83
97
 
84
- ### Sigma Rules
98
+ ### Quick Start: Download All Rules (Copy & Paste)
99
+
100
+ Create a `detections` folder and download all sources with sparse checkout (only downloads the rules, not full repos):
85
101
 
86
102
  ```bash
87
- git clone https://github.com/SigmaHQ/sigma.git
88
- # Use rules/ and rules-threat-hunting/ directories
103
+ # Create detections directory
104
+ mkdir -p detections && cd detections
105
+
106
+ # Download Sigma rules (~3,000+ rules)
107
+ git clone --depth 1 --filter=blob:none --sparse https://github.com/SigmaHQ/sigma.git
108
+ cd sigma && git sparse-checkout set rules rules-threat-hunting && cd ..
109
+
110
+ # Download Splunk ESCU detections + stories (~2,000+ detections, ~330 stories)
111
+ git clone --depth 1 --filter=blob:none --sparse https://github.com/splunk/security_content.git
112
+ cd security_content && git sparse-checkout set detections stories && cd ..
113
+
114
+ # Download Elastic detection rules (~1,500+ rules)
115
+ git clone --depth 1 --filter=blob:none --sparse https://github.com/elastic/detection-rules.git
116
+ cd detection-rules && git sparse-checkout set rules && cd ..
117
+
118
+ # Download KQL hunting queries (~300+ queries)
119
+ git clone --depth 1 https://github.com/Bert-JanP/Hunting-Queries-Detection-Rules.git kql
120
+
121
+ echo "Done! Configure your MCP with these paths:"
122
+ echo " SIGMA_PATHS: $(pwd)/sigma/rules,$(pwd)/sigma/rules-threat-hunting"
123
+ echo " SPLUNK_PATHS: $(pwd)/security_content/detections"
124
+ echo " ELASTIC_PATHS: $(pwd)/detection-rules/rules"
125
+ echo " KQL_PATHS: $(pwd)/kql"
126
+ echo " STORY_PATHS: $(pwd)/security_content/stories"
89
127
  ```
90
128
 
91
- ### Splunk ESCU
129
+ ### Alternative: Full Clone
130
+
131
+ If you prefer full git history:
92
132
 
93
133
  ```bash
134
+ # Sigma Rules
135
+ git clone https://github.com/SigmaHQ/sigma.git
136
+ # Use rules/ and rules-threat-hunting/ directories
137
+
138
+ # Splunk ESCU
94
139
  git clone https://github.com/splunk/security_content.git
95
- # Use detections/ directory
140
+ # Use detections/ and stories/ directories
141
+
142
+ # Elastic Detection Rules
143
+ git clone https://github.com/elastic/detection-rules.git
144
+ # Use rules/ directory
145
+
146
+ # KQL Hunting Queries
147
+ git clone https://github.com/Bert-JanP/Hunting-Queries-Detection-Rules.git
148
+ # Use entire repo
96
149
  ```
97
150
 
98
151
  ## MCP Tools
99
152
 
153
+ ### Core Detection Tools
154
+
100
155
  | Tool | Description |
101
156
  |------|-------------|
102
- | `search(query, limit)` | Full-text search across all detection fields |
157
+ | `search(query, limit)` | Full-text search across all detection fields (names, descriptions, queries, CVEs, process names, etc.) |
103
158
  | `get_by_id(id)` | Get a single detection by its ID |
104
159
  | `list_all(limit, offset)` | Paginated list of all detections |
105
- | `list_by_source(source_type)` | Filter by `sigma` or `splunk_escu` |
106
- | `list_by_mitre(technique_id)` | Filter by MITRE ATT&CK technique ID |
107
- | `list_by_logsource(category, product, service)` | Filter Sigma rules by logsource |
108
- | `list_by_severity(level)` | Filter by severity (informational/low/medium/high/critical) |
160
+ | `list_by_source(source_type)` | Filter by `sigma`, `splunk_escu`, `elastic`, or `kql` |
161
+ | `get_raw_yaml(id)` | Get the original YAML/TOML/Markdown content |
109
162
  | `get_stats()` | Get index statistics |
110
163
  | `rebuild_index()` | Force re-index from configured paths |
111
- | `get_raw_yaml(id)` | Get the original YAML content |
112
164
 
113
- ## Example Workflow
165
+ ### MITRE ATT&CK Filters
166
+
167
+ | Tool | Description |
168
+ |------|-------------|
169
+ | `list_by_mitre(technique_id)` | Filter by MITRE ATT&CK technique ID (e.g., T1059.001) |
170
+ | `list_by_mitre_tactic(tactic)` | Filter by tactic (execution, persistence, credential-access, etc.) |
171
+
172
+ ### Vulnerability & Process Filters
173
+
174
+ | Tool | Description |
175
+ |------|-------------|
176
+ | `list_by_cve(cve_id)` | Find detections for a specific CVE (e.g., CVE-2024-27198) |
177
+ | `list_by_process_name(process_name)` | Find detections referencing a process (e.g., powershell.exe, w3wp.exe) |
178
+ | `list_by_data_source(data_source)` | Filter by data source (e.g., Sysmon, Windows Security) |
179
+
180
+ ### Classification Filters
181
+
182
+ | Tool | Description |
183
+ |------|-------------|
184
+ | `list_by_logsource(category, product, service)` | Filter Sigma rules by logsource |
185
+ | `list_by_severity(level)` | Filter by severity (informational/low/medium/high/critical) |
186
+ | `list_by_detection_type(type)` | Filter by type (TTP, Anomaly, Hunting, Correlation) |
187
+ | `list_by_analytic_story(story)` | Filter by Splunk analytic story |
188
+
189
+ ### KQL-Specific Filters
190
+
191
+ | Tool | Description |
192
+ |------|-------------|
193
+ | `list_by_kql_category(category)` | Filter KQL by category (e.g., "Defender For Endpoint", "Azure Active Directory", "Threat Hunting") |
194
+ | `list_by_kql_tag(tag)` | Filter KQL by tag (e.g., "ransomware", "hunting", "ti-feed", "dfir") |
195
+ | `list_by_kql_datasource(data_source)` | Filter KQL by Microsoft data source (e.g., "DeviceProcessEvents", "SigninLogs") |
196
+
197
+ ### Story Tools (Optional)
198
+
199
+ | Tool | Description |
200
+ |------|-------------|
201
+ | `search_stories(query, limit)` | Search analytic stories by narrative and description |
202
+ | `get_story(name)` | Get detailed story information |
203
+ | `list_stories(limit, offset)` | List all analytic stories |
204
+ | `list_stories_by_category(category)` | Filter stories by category (Malware, Adversary Tactics, etc.) |
205
+
206
+ ### Efficient Analysis Tools (Token-Optimized)
207
+
208
+ These tools do heavy processing server-side and return minimal, actionable data:
209
+
210
+ | Tool | Description | Output Size |
211
+ |------|-------------|-------------|
212
+ | `analyze_coverage(source_type?)` | Get coverage stats by tactic, top techniques, weak spots | ~2KB |
213
+ | `identify_gaps(threat_profile, source_type?)` | Find gaps for ransomware, apt, persistence, etc. | ~500B |
214
+ | `suggest_detections(technique_id, source_type?)` | Get detection ideas for a technique | ~2KB |
215
+ | `get_technique_ids(source_type?, tactic?, severity?)` | Get only technique IDs (no full objects) | ~200B |
216
+ | `generate_navigator_layer(name, source_type?, tactic?)` | Generate ATT&CK Navigator layer JSON | ~3KB |
217
+
218
+ **Why use these?** Traditional tools return full detection objects (~50KB+ per query). These return only what you need, saving 25x+ tokens.
219
+
220
+ ## Claude Code Skills
221
+
222
+ This repo includes [Claude Code Skills](https://code.claude.com/docs/en/skills) in `.claude/skills/` that teach Claude efficient workflows:
114
223
 
115
- 1. **Ask the LLM**: "Find me PowerShell detections related to base64 encoding"
224
+ | Skill | Purpose |
225
+ |-------|---------|
226
+ | `coverage-analysis` | Efficient coverage analysis using the token-optimized tools |
116
227
 
117
- 2. **LLM calls**: `search(query="powershell base64", limit=5)`
228
+ **Why skills?** Instead of figuring out methodology each time (wasting tokens), skills teach Claude once.
118
229
 
119
- 3. **LLM receives**: Top 5 detections with names, descriptions, and detection logic
230
+ You can also install personal skills to `~/.claude/skills/` for cross-project use.
120
231
 
121
- 4. **LLM explores**: Uses `get_by_id` to get full details on interesting detections
232
+ ### Example: Efficient Coverage Analysis
122
233
 
123
- 5. **LLM filters by MITRE**: `list_by_mitre(technique_id="T1059.001")` to find all PowerShell execution detections
234
+ ```
235
+ You: "What's my Elastic coverage against ransomware?"
236
+
237
+ AI uses skills + efficient tools:
238
+ 1. analyze_coverage(source_type="elastic") → Stats by tactic
239
+ 2. identify_gaps(threat_profile="ransomware") → Prioritized gaps
240
+ 3. suggest_detections(technique_id="T1486") → Fix top gap
241
+
242
+ Total: ~5KB of data vs ~500KB with traditional tools
243
+ ```
244
+
245
+ ## Example Workflows
246
+
247
+ ### Find PowerShell Detections
248
+
249
+ ```
250
+ LLM: "Find me PowerShell detections related to base64 encoding"
251
+ Tool: search(query="powershell base64", limit=5)
252
+ ```
253
+
254
+ ### Check CVE Coverage
255
+
256
+ ```
257
+ LLM: "Do we have detections for CVE-2024-27198?"
258
+ Tool: list_by_cve(cve_id="CVE-2024-27198")
259
+ ```
260
+
261
+ ### Compare Coverage Across Sources
262
+
263
+ ```
264
+ LLM: "What detections do we have for credential dumping?"
265
+ Tool: search(query="credential dumping", limit=10)
266
+ → Returns results from Sigma, Splunk, Elastic, AND KQL
267
+ ```
268
+
269
+ ### Find Web Server Attack Detections
270
+
271
+ ```
272
+ LLM: "What detections cover IIS web server attacks?"
273
+ Tool: list_by_process_name(process_name="w3wp.exe")
274
+ ```
275
+
276
+ ### Explore a Threat Campaign
277
+
278
+ ```
279
+ LLM: "Tell me about ransomware detections"
280
+ Tool: search_stories(query="ransomware")
281
+ Tool: list_by_analytic_story(story="Ransomware")
282
+ ```
283
+
284
+ ### Find KQL Hunting Queries for Defender
285
+
286
+ ```
287
+ LLM: "What KQL queries do we have for Defender For Endpoint?"
288
+ Tool: list_by_kql_category(category="Defender For Endpoint")
289
+ ```
290
+
291
+ ### Search for BloodHound Detections
292
+
293
+ ```
294
+ LLM: "Find detections for BloodHound usage"
295
+ Tool: search(query="bloodhound", limit=10)
296
+ → Returns KQL hunting queries and other source detections
297
+ ```
124
298
 
125
299
  ## Unified Schema
126
300
 
127
- Both Sigma and Splunk ESCU detections are normalized to a common schema:
301
+ All detection sources (Sigma, Splunk, Elastic, KQL) are normalized to a common schema:
302
+
303
+ ### Core Fields
128
304
 
129
305
  | Field | Description |
130
306
  |-------|-------------|
131
- | `id` | Unique identifier (UUID for Sigma, ID field for Splunk) |
307
+ | `id` | Unique identifier |
132
308
  | `name` | Detection name/title |
133
309
  | `description` | What the detection looks for |
134
- | `query` | Detection logic (Sigma YAML or Splunk SPL) |
135
- | `source_type` | `sigma` or `splunk_escu` |
136
- | `mitre_ids` | Mapped MITRE ATT&CK technique IDs |
137
- | `logsource_category` | Sigma logsource category |
138
- | `logsource_product` | Sigma logsource product (windows, linux, etc.) |
139
- | `logsource_service` | Sigma logsource service |
310
+ | `query` | Detection logic (Sigma YAML, Splunk SPL, Elastic EQL, or KQL) |
311
+ | `source_type` | `sigma`, `splunk_escu`, `elastic`, or `kql` |
140
312
  | `severity` | Detection severity level |
141
- | `status` | Rule status (stable, test, experimental, etc.) |
313
+ | `status` | Rule status (stable, test, experimental, production, etc.) |
142
314
  | `author` | Rule author |
143
- | `date_created` | Creation date |
144
- | `date_modified` | Last modification date |
145
- | `references` | External references |
146
- | `falsepositives` | Known false positive scenarios |
147
- | `tags` | All tags (MITRE, analytic stories, etc.) |
148
315
  | `file_path` | Original file path |
149
- | `raw_yaml` | Original YAML content |
316
+ | `raw_yaml` | Original YAML/TOML/Markdown content |
317
+
318
+ ### Enhanced Fields (for Semantic Search)
319
+
320
+ | Field | Description |
321
+ |-------|-------------|
322
+ | `mitre_ids` | Mapped MITRE ATT&CK technique IDs |
323
+ | `mitre_tactics` | Extracted MITRE tactics (execution, persistence, etc.) |
324
+ | `cves` | CVE identifiers (e.g., CVE-2024-27198) |
325
+ | `analytic_stories` | Splunk analytic story names |
326
+ | `process_names` | Process names referenced in detection |
327
+ | `file_paths` | Interesting file paths referenced |
328
+ | `registry_paths` | Registry paths referenced |
329
+ | `data_sources` | Required data sources (Sysmon, DeviceProcessEvents, etc.) |
330
+ | `detection_type` | TTP, Anomaly, Hunting, or Correlation |
331
+ | `asset_type` | Endpoint, Web Server, Cloud, Network |
332
+ | `security_domain` | endpoint, network, cloud, access |
333
+
334
+ ### KQL-Specific Fields
335
+
336
+ | Field | Description |
337
+ |-------|-------------|
338
+ | `kql_category` | Category derived from folder path (e.g., "Defender For Endpoint") |
339
+ | `kql_tags` | Extracted tags (e.g., "ransomware", "hunting", "ti-feed") |
340
+ | `kql_keywords` | Security keywords extracted for search |
341
+ | `platforms` | Platforms (windows, azure-ad, office-365, etc.) |
150
342
 
151
343
  ## Database
152
344
 
@@ -158,17 +350,42 @@ The index is stored at `~/.cache/security-detections-mcp/detections.sqlite`.
158
350
 
159
351
  ## Supported Detection Formats
160
352
 
161
- ### Sigma Rules
353
+ ### Sigma Rules (YAML)
162
354
 
163
355
  Based on the [official Sigma specification](https://github.com/SigmaHQ/sigma-specification):
164
356
  - All required fields: `title`, `logsource`, `detection`
165
357
  - All optional fields: `id`, `status`, `description`, `author`, `date`, `modified`, `references`, `tags`, `level`, `falsepositives`, etc.
358
+ - CVE tags extracted from `tags` field (e.g., `cve.2021-1675`)
166
359
 
167
- ### Splunk ESCU
360
+ ### Splunk ESCU (YAML)
168
361
 
169
362
  From [Splunk Security Content](https://github.com/splunk/security_content):
170
363
  - Required: `name`, `id`, `search`
171
- - Optional: `description`, `author`, `date`, `status`, `references`, `tags` (including `mitre_attack_id`, `analytic_story`)
364
+ - Optional: `description`, `author`, `date`, `status`, `references`, `tags` (including `mitre_attack_id`, `analytic_story`, `cve`)
365
+
366
+ ### Splunk Analytic Stories (YAML - Optional)
367
+
368
+ From [Splunk Security Content stories](https://github.com/splunk/security_content/tree/develop/stories):
369
+ - Provides rich narrative context for threat campaigns
370
+ - Enhances semantic search with detailed descriptions
371
+ - Links detections to broader threat context
372
+
373
+ ### Elastic Detection Rules (TOML)
374
+
375
+ From [Elastic Detection Rules](https://github.com/elastic/detection-rules):
376
+ - Required: `rule.name`, `rule.rule_id`
377
+ - Optional: `rule.description`, `rule.query`, `rule.severity`, `rule.tags`, `rule.threat` (MITRE mappings)
378
+ - Supports EQL, KQL, Lucene, and ESQL query languages
379
+
380
+ ### KQL Hunting Queries (Markdown)
381
+
382
+ From [Bert-JanP/Hunting-Queries-Detection-Rules](https://github.com/Bert-JanP/Hunting-Queries-Detection-Rules):
383
+ - Microsoft Defender XDR and Azure Sentinel hunting queries
384
+ - Extracts title from markdown heading
385
+ - Extracts KQL from fenced code blocks
386
+ - Extracts MITRE technique IDs from tables
387
+ - Derives category from folder path
388
+ - Extracts data sources (DeviceProcessEvents, SigninLogs, etc.)
172
389
 
173
390
  ## Development
174
391
 
@@ -180,7 +397,87 @@ npm install
180
397
  npm run build
181
398
 
182
399
  # Run with paths
183
- SIGMA_PATHS="./detections/sigma/rules" SPLUNK_PATHS="./detections/splunk/detections" npm start
400
+ SIGMA_PATHS="./detections/sigma/rules" \
401
+ SPLUNK_PATHS="./detections/splunk/detections" \
402
+ ELASTIC_PATHS="./detections/elastic/rules" \
403
+ KQL_PATHS="./detections/kql" \
404
+ STORY_PATHS="./detections/splunk/stories" \
405
+ npm start
406
+ ```
407
+
408
+ ## Stats (with full content)
409
+
410
+ When fully indexed with all sources:
411
+
412
+ | Source | Count |
413
+ |--------|-------|
414
+ | Sigma Rules | ~3,000+ |
415
+ | Splunk ESCU | ~2,000+ |
416
+ | Elastic Rules | ~1,500+ |
417
+ | KQL Queries | ~300+ |
418
+ | Analytic Stories | ~330 |
419
+ | **Total** | **~7,000+** |
420
+
421
+ ## 🔗 Using with MITRE ATT&CK MCP
422
+
423
+ **This MCP pairs perfectly with [mitre-attack-mcp](https://github.com/MHaggis/mitre-attack-mcp)** for complete threat coverage analysis:
424
+
425
+ | MCP | Purpose |
426
+ |-----|---------|
427
+ | **security-detections-mcp** | Query 7,000+ detection rules (Sigma, Splunk ESCU, Elastic, KQL) |
428
+ | **mitre-attack-mcp** | Analyze coverage against ATT&CK framework, generate Navigator layers |
429
+
430
+ ### Combined Workflow (Efficient)
431
+
432
+ ```
433
+ You: "What's my coverage against APT29?"
434
+
435
+ LLM workflow (3 calls, ~10KB total):
436
+ 1. mitre-attack-mcp → get_group_techniques("G0016") # APT29's TTPs
437
+ 2. detections-mcp → analyze_coverage(source_type="elastic") # Your coverage
438
+ 3. mitre-attack-mcp → find_group_gaps("G0016", your_coverage) # The gaps
439
+
440
+ Result: Prioritized gap list, not 500KB of raw data
441
+ ```
442
+
443
+ ### Generate Navigator Layer (1 call)
444
+
445
+ ```
446
+ You: "Generate a Navigator layer for my initial access coverage"
447
+
448
+ LLM: generate_navigator_layer(
449
+ name="Initial Access Coverage",
450
+ source_type="elastic",
451
+ tactic="initial-access"
452
+ )
453
+
454
+ → Returns ready-to-import Navigator JSON
455
+ ```
456
+
457
+ ### Install Both Together
458
+
459
+ ```json
460
+ {
461
+ "mcpServers": {
462
+ "security-detections": {
463
+ "command": "npx",
464
+ "args": ["-y", "security-detections-mcp"],
465
+ "env": {
466
+ "SIGMA_PATHS": "/path/to/sigma/rules",
467
+ "SPLUNK_PATHS": "/path/to/security_content/detections",
468
+ "ELASTIC_PATHS": "/path/to/detection-rules/rules",
469
+ "KQL_PATHS": "/path/to/kql-hunting-queries"
470
+ }
471
+ },
472
+ "mitre-attack": {
473
+ "command": "npx",
474
+ "args": ["-y", "mitre-attack-mcp"],
475
+ "env": {
476
+ "ATTACK_DOMAIN": "enterprise-attack"
477
+ }
478
+ }
479
+ }
480
+ }
184
481
  ```
185
482
 
186
483
  ## License
package/dist/db.d.ts CHANGED
@@ -1,17 +1,91 @@
1
1
  import Database from 'better-sqlite3';
2
- import type { Detection, IndexStats } from './types.js';
2
+ import type { Detection, IndexStats, AnalyticStory } from './types.js';
3
3
  export declare function getDbPath(): string;
4
4
  export declare function initDb(): Database.Database;
5
5
  export declare function clearDb(): void;
6
+ export declare function recreateDb(): void;
6
7
  export declare function insertDetection(detection: Detection): void;
7
8
  export declare function searchDetections(query: string, limit?: number): Detection[];
8
9
  export declare function getDetectionById(id: string): Detection | null;
9
10
  export declare function listDetections(limit?: number, offset?: number): Detection[];
10
- export declare function listBySource(sourceType: 'sigma' | 'splunk_escu', limit?: number, offset?: number): Detection[];
11
+ export declare function listBySource(sourceType: 'sigma' | 'splunk_escu' | 'elastic' | 'kql', limit?: number, offset?: number): Detection[];
11
12
  export declare function listByMitre(techniqueId: string, limit?: number, offset?: number): Detection[];
12
13
  export declare function listByLogsource(category?: string, product?: string, service?: string, limit?: number, offset?: number): Detection[];
13
14
  export declare function listBySeverity(level: string, limit?: number, offset?: number): Detection[];
15
+ export declare function listByCve(cveId: string, limit?: number, offset?: number): Detection[];
16
+ export declare function listByAnalyticStory(story: string, limit?: number, offset?: number): Detection[];
17
+ export declare function listByProcessName(processName: string, limit?: number, offset?: number): Detection[];
18
+ export declare function listByDetectionType(detectionType: string, limit?: number, offset?: number): Detection[];
19
+ export declare function listByDataSource(dataSource: string, limit?: number, offset?: number): Detection[];
20
+ export declare function listByKqlCategory(category: string, limit?: number, offset?: number): Detection[];
21
+ export declare function listByKqlTag(tag: string, limit?: number, offset?: number): Detection[];
22
+ export declare function listByKqlDatasource(dataSource: string, limit?: number, offset?: number): Detection[];
23
+ export declare function listByMitreTactic(tactic: string, limit?: number, offset?: number): Detection[];
14
24
  export declare function getStats(): IndexStats;
15
25
  export declare function getRawYaml(id: string): string | null;
16
26
  export declare function dbExists(): boolean;
17
27
  export declare function getDetectionCount(): number;
28
+ export declare function insertStory(story: AnalyticStory): void;
29
+ export declare function getStoryByName(name: string): AnalyticStory | null;
30
+ export declare function getStoryById(id: string): AnalyticStory | null;
31
+ export declare function searchStories(query: string, limit?: number): AnalyticStory[];
32
+ export declare function listStories(limit?: number, offset?: number): AnalyticStory[];
33
+ export declare function listStoriesByCategory(category: string, limit?: number, offset?: number): AnalyticStory[];
34
+ export declare function getStoryCount(): number;
35
+ export interface TechniqueIdFilters {
36
+ source_type?: 'sigma' | 'splunk_escu' | 'elastic';
37
+ tactic?: string;
38
+ severity?: string;
39
+ }
40
+ export declare function getTechniqueIds(filters?: TechniqueIdFilters): string[];
41
+ export interface CoverageReport {
42
+ summary: {
43
+ total_techniques: number;
44
+ total_detections: number;
45
+ coverage_by_tactic: Record<string, {
46
+ covered: number;
47
+ total: number;
48
+ percent: number;
49
+ }>;
50
+ };
51
+ top_covered: Array<{
52
+ technique: string;
53
+ detection_count: number;
54
+ }>;
55
+ weak_coverage: Array<{
56
+ technique: string;
57
+ detection_count: number;
58
+ }>;
59
+ }
60
+ export declare function analyzeCoverage(sourceType?: 'sigma' | 'splunk_escu' | 'elastic'): CoverageReport;
61
+ export interface GapAnalysis {
62
+ threat_profile: string;
63
+ total_gaps: number;
64
+ critical_gaps: Array<{
65
+ technique: string;
66
+ priority: string;
67
+ reason: string;
68
+ }>;
69
+ covered: string[];
70
+ recommendations: string[];
71
+ }
72
+ export declare function identifyGaps(threatProfile: string, sourceType?: 'sigma' | 'splunk_escu' | 'elastic'): GapAnalysis;
73
+ export interface DetectionSuggestion {
74
+ technique_id: string;
75
+ existing_detections: Array<{
76
+ id: string;
77
+ name: string;
78
+ source: string;
79
+ }>;
80
+ data_sources_needed: string[];
81
+ detection_ideas: string[];
82
+ }
83
+ export declare function suggestDetections(techniqueId: string, sourceType?: 'sigma' | 'splunk_escu' | 'elastic'): DetectionSuggestion;
84
+ export interface NavigatorLayerOptions {
85
+ name: string;
86
+ description?: string;
87
+ source_type?: 'sigma' | 'splunk_escu' | 'elastic';
88
+ tactic?: string;
89
+ severity?: string;
90
+ }
91
+ export declare function generateNavigatorLayer(options: NavigatorLayerOptions): object;