security-detections-mcp 1.0.0 → 1.1.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,19 @@
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**, and **Elastic** 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=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsInNlY3VyaXR5LWRldGVjdGlvbnMtbWNwIl0sImVudiI6eyJTSUdNQV9QQVRIUyI6Ii9wYXRoL3RvL3NpZ21hL3J1bGVzLC9wYXRoL3RvL3NpZ21hL3J1bGVzLXRocmVhdC1odW50aW5nIiwiU1BMVU5LX1BBVEhTIjoiL3BhdGgvdG8vc2VjdXJpdHlfY29udGVudC9kZXRlY3Rpb25zIiwiU1RPUllfUEFUSFMiOiIvcGF0aC90by9zZWN1cml0eV9jb250ZW50L3N0b3JpZXMiLCJFTEFTVElDX1BBVEhTIjoiL3BhdGgvdG8vZGV0ZWN0aW9uLXJ1bGVzL3J1bGVzIn19)
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, and Elastic 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)
12
15
  - **Auto-Indexing** - Automatically indexes detections on startup from configured paths
16
+ - **Multi-Format Support** - YAML (Sigma, Splunk), TOML (Elastic)
13
17
  - **Logsource Filtering** - Filter Sigma rules by category, product, or service
14
18
  - **Severity Filtering** - Filter by criticality level
15
19
 
@@ -46,7 +50,9 @@ Add to your MCP config (`~/.cursor/mcp.json` or `.cursor/mcp.json` in your proje
46
50
  "args": ["-y", "security-detections-mcp"],
47
51
  "env": {
48
52
  "SIGMA_PATHS": "/path/to/sigma/rules,/path/to/sigma/rules-threat-hunting",
49
- "SPLUNK_PATHS": "/path/to/security_content/detections"
53
+ "SPLUNK_PATHS": "/path/to/security_content/detections",
54
+ "ELASTIC_PATHS": "/path/to/detection-rules/rules",
55
+ "STORY_PATHS": "/path/to/security_content/stories"
50
56
  }
51
57
  }
52
58
  }
@@ -65,7 +71,9 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
65
71
  "args": ["-y", "security-detections-mcp"],
66
72
  "env": {
67
73
  "SIGMA_PATHS": "/Users/you/sigma/rules,/Users/you/sigma/rules-threat-hunting",
68
- "SPLUNK_PATHS": "/Users/you/security_content/detections"
74
+ "SPLUNK_PATHS": "/Users/you/security_content/detections",
75
+ "ELASTIC_PATHS": "/Users/you/detection-rules/rules",
76
+ "STORY_PATHS": "/Users/you/security_content/stories"
69
77
  }
70
78
  }
71
79
  }
@@ -74,79 +82,180 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
74
82
 
75
83
  ### Environment Variables
76
84
 
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` |
85
+ | Variable | Description | Required |
86
+ |----------|-------------|----------|
87
+ | `SIGMA_PATHS` | Comma-separated paths to Sigma rule directories | Yes (at least one source) |
88
+ | `SPLUNK_PATHS` | Comma-separated paths to Splunk ESCU detection directories | Yes (at least one source) |
89
+ | `ELASTIC_PATHS` | Comma-separated paths to Elastic detection rule directories | Yes (at least one source) |
90
+ | `STORY_PATHS` | Comma-separated paths to Splunk analytic story directories | No (enhances context) |
81
91
 
82
92
  ## Getting Detection Content
83
93
 
84
- ### Sigma Rules
94
+ ### Quick Start: Download All Rules (Copy & Paste)
95
+
96
+ Create a `detections` folder and download all three sources with sparse checkout (only downloads the rules, not full repos):
85
97
 
86
98
  ```bash
87
- git clone https://github.com/SigmaHQ/sigma.git
88
- # Use rules/ and rules-threat-hunting/ directories
99
+ # Create detections directory
100
+ mkdir -p detections && cd detections
101
+
102
+ # Download Sigma rules (~3,000+ rules)
103
+ git clone --depth 1 --filter=blob:none --sparse https://github.com/SigmaHQ/sigma.git
104
+ cd sigma && git sparse-checkout set rules rules-threat-hunting && cd ..
105
+
106
+ # Download Splunk ESCU detections + stories (~2,000+ detections, ~330 stories)
107
+ git clone --depth 1 --filter=blob:none --sparse https://github.com/splunk/security_content.git
108
+ cd security_content && git sparse-checkout set detections stories && cd ..
109
+
110
+ # Download Elastic detection rules (~1,500+ rules)
111
+ git clone --depth 1 --filter=blob:none --sparse https://github.com/elastic/detection-rules.git
112
+ cd detection-rules && git sparse-checkout set rules && cd ..
113
+
114
+ echo "Done! Configure your MCP with these paths:"
115
+ echo " SIGMA_PATHS: $(pwd)/sigma/rules,$(pwd)/sigma/rules-threat-hunting"
116
+ echo " SPLUNK_PATHS: $(pwd)/security_content/detections"
117
+ echo " ELASTIC_PATHS: $(pwd)/detection-rules/rules"
118
+ echo " STORY_PATHS: $(pwd)/security_content/stories"
89
119
  ```
90
120
 
91
- ### Splunk ESCU
121
+ ### Alternative: Full Clone
122
+
123
+ If you prefer full git history:
92
124
 
93
125
  ```bash
126
+ # Sigma Rules
127
+ git clone https://github.com/SigmaHQ/sigma.git
128
+ # Use rules/ and rules-threat-hunting/ directories
129
+
130
+ # Splunk ESCU
94
131
  git clone https://github.com/splunk/security_content.git
95
- # Use detections/ directory
132
+ # Use detections/ and stories/ directories
133
+
134
+ # Elastic Detection Rules
135
+ git clone https://github.com/elastic/detection-rules.git
136
+ # Use rules/ directory
96
137
  ```
97
138
 
98
139
  ## MCP Tools
99
140
 
141
+ ### Core Detection Tools
142
+
100
143
  | Tool | Description |
101
144
  |------|-------------|
102
- | `search(query, limit)` | Full-text search across all detection fields |
145
+ | `search(query, limit)` | Full-text search across all detection fields (names, descriptions, queries, CVEs, process names, etc.) |
103
146
  | `get_by_id(id)` | Get a single detection by its ID |
104
147
  | `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) |
148
+ | `list_by_source(source_type)` | Filter by `sigma`, `splunk_escu`, or `elastic` |
149
+ | `get_raw_yaml(id)` | Get the original YAML/TOML content |
109
150
  | `get_stats()` | Get index statistics |
110
151
  | `rebuild_index()` | Force re-index from configured paths |
111
- | `get_raw_yaml(id)` | Get the original YAML content |
112
152
 
113
- ## Example Workflow
153
+ ### MITRE ATT&CK Filters
154
+
155
+ | Tool | Description |
156
+ |------|-------------|
157
+ | `list_by_mitre(technique_id)` | Filter by MITRE ATT&CK technique ID (e.g., T1059.001) |
158
+ | `list_by_mitre_tactic(tactic)` | Filter by tactic (execution, persistence, credential-access, etc.) |
159
+
160
+ ### Vulnerability & Process Filters
161
+
162
+ | Tool | Description |
163
+ |------|-------------|
164
+ | `list_by_cve(cve_id)` | Find detections for a specific CVE (e.g., CVE-2024-27198) |
165
+ | `list_by_process_name(process_name)` | Find detections referencing a process (e.g., powershell.exe, w3wp.exe) |
166
+ | `list_by_data_source(data_source)` | Filter by data source (e.g., Sysmon, Windows Security) |
167
+
168
+ ### Classification Filters
169
+
170
+ | Tool | Description |
171
+ |------|-------------|
172
+ | `list_by_logsource(category, product, service)` | Filter Sigma rules by logsource |
173
+ | `list_by_severity(level)` | Filter by severity (informational/low/medium/high/critical) |
174
+ | `list_by_detection_type(type)` | Filter by type (TTP, Anomaly, Hunting, Correlation) |
175
+ | `list_by_analytic_story(story)` | Filter by Splunk analytic story |
176
+
177
+ ### Story Tools (Optional)
178
+
179
+ | Tool | Description |
180
+ |------|-------------|
181
+ | `search_stories(query, limit)` | Search analytic stories by narrative and description |
182
+ | `get_story(name)` | Get detailed story information |
183
+ | `list_stories(limit, offset)` | List all analytic stories |
184
+ | `list_stories_by_category(category)` | Filter stories by category (Malware, Adversary Tactics, etc.) |
185
+
186
+ ## Example Workflows
114
187
 
115
- 1. **Ask the LLM**: "Find me PowerShell detections related to base64 encoding"
188
+ ### Find PowerShell Detections
116
189
 
117
- 2. **LLM calls**: `search(query="powershell base64", limit=5)`
190
+ ```
191
+ LLM: "Find me PowerShell detections related to base64 encoding"
192
+ Tool: search(query="powershell base64", limit=5)
193
+ ```
194
+
195
+ ### Check CVE Coverage
196
+
197
+ ```
198
+ LLM: "Do we have detections for CVE-2024-27198?"
199
+ Tool: list_by_cve(cve_id="CVE-2024-27198")
200
+ ```
118
201
 
119
- 3. **LLM receives**: Top 5 detections with names, descriptions, and detection logic
202
+ ### Compare Coverage Across Sources
120
203
 
121
- 4. **LLM explores**: Uses `get_by_id` to get full details on interesting detections
204
+ ```
205
+ LLM: "What detections do we have for credential dumping?"
206
+ Tool: search(query="credential dumping", limit=10)
207
+ → Returns results from Sigma, Splunk, AND Elastic
208
+ ```
122
209
 
123
- 5. **LLM filters by MITRE**: `list_by_mitre(technique_id="T1059.001")` to find all PowerShell execution detections
210
+ ### Find Web Server Attack Detections
211
+
212
+ ```
213
+ LLM: "What detections cover IIS web server attacks?"
214
+ Tool: list_by_process_name(process_name="w3wp.exe")
215
+ ```
216
+
217
+ ### Explore a Threat Campaign
218
+
219
+ ```
220
+ LLM: "Tell me about ransomware detections"
221
+ Tool: search_stories(query="ransomware")
222
+ Tool: list_by_analytic_story(story="Ransomware")
223
+ ```
124
224
 
125
225
  ## Unified Schema
126
226
 
127
- Both Sigma and Splunk ESCU detections are normalized to a common schema:
227
+ All detection sources (Sigma, Splunk, Elastic) are normalized to a common schema:
228
+
229
+ ### Core Fields
128
230
 
129
231
  | Field | Description |
130
232
  |-------|-------------|
131
- | `id` | Unique identifier (UUID for Sigma, ID field for Splunk) |
233
+ | `id` | Unique identifier (UUID for Sigma, ID field for Splunk, rule_id for Elastic) |
132
234
  | `name` | Detection name/title |
133
235
  | `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 |
236
+ | `query` | Detection logic (Sigma YAML, Splunk SPL, or Elastic EQL/KQL) |
237
+ | `source_type` | `sigma`, `splunk_escu`, or `elastic` |
140
238
  | `severity` | Detection severity level |
141
- | `status` | Rule status (stable, test, experimental, etc.) |
239
+ | `status` | Rule status (stable, test, experimental, production, etc.) |
142
240
  | `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
241
  | `file_path` | Original file path |
149
- | `raw_yaml` | Original YAML content |
242
+ | `raw_yaml` | Original YAML/TOML content |
243
+
244
+ ### Enhanced Fields (for Semantic Search)
245
+
246
+ | Field | Description |
247
+ |-------|-------------|
248
+ | `mitre_ids` | Mapped MITRE ATT&CK technique IDs |
249
+ | `mitre_tactics` | Extracted MITRE tactics (execution, persistence, etc.) |
250
+ | `cves` | CVE identifiers (e.g., CVE-2024-27198) |
251
+ | `analytic_stories` | Splunk analytic story names |
252
+ | `process_names` | Process names referenced in detection |
253
+ | `file_paths` | Interesting file paths referenced |
254
+ | `registry_paths` | Registry paths referenced |
255
+ | `data_sources` | Required data sources |
256
+ | `detection_type` | TTP, Anomaly, Hunting, or Correlation |
257
+ | `asset_type` | Endpoint, Web Server, Cloud, Network |
258
+ | `security_domain` | endpoint, network, cloud, access |
150
259
 
151
260
  ## Database
152
261
 
@@ -158,17 +267,32 @@ The index is stored at `~/.cache/security-detections-mcp/detections.sqlite`.
158
267
 
159
268
  ## Supported Detection Formats
160
269
 
161
- ### Sigma Rules
270
+ ### Sigma Rules (YAML)
162
271
 
163
272
  Based on the [official Sigma specification](https://github.com/SigmaHQ/sigma-specification):
164
273
  - All required fields: `title`, `logsource`, `detection`
165
274
  - All optional fields: `id`, `status`, `description`, `author`, `date`, `modified`, `references`, `tags`, `level`, `falsepositives`, etc.
275
+ - CVE tags extracted from `tags` field (e.g., `cve.2021-1675`)
166
276
 
167
- ### Splunk ESCU
277
+ ### Splunk ESCU (YAML)
168
278
 
169
279
  From [Splunk Security Content](https://github.com/splunk/security_content):
170
280
  - Required: `name`, `id`, `search`
171
- - Optional: `description`, `author`, `date`, `status`, `references`, `tags` (including `mitre_attack_id`, `analytic_story`)
281
+ - Optional: `description`, `author`, `date`, `status`, `references`, `tags` (including `mitre_attack_id`, `analytic_story`, `cve`)
282
+
283
+ ### Splunk Analytic Stories (YAML - Optional)
284
+
285
+ From [Splunk Security Content stories](https://github.com/splunk/security_content/tree/develop/stories):
286
+ - Provides rich narrative context for threat campaigns
287
+ - Enhances semantic search with detailed descriptions
288
+ - Links detections to broader threat context
289
+
290
+ ### Elastic Detection Rules (TOML)
291
+
292
+ From [Elastic Detection Rules](https://github.com/elastic/detection-rules):
293
+ - Required: `rule.name`, `rule.rule_id`
294
+ - Optional: `rule.description`, `rule.query`, `rule.severity`, `rule.tags`, `rule.threat` (MITRE mappings)
295
+ - Supports EQL, KQL, Lucene, and ESQL query languages
172
296
 
173
297
  ## Development
174
298
 
@@ -180,9 +304,25 @@ npm install
180
304
  npm run build
181
305
 
182
306
  # Run with paths
183
- SIGMA_PATHS="./detections/sigma/rules" SPLUNK_PATHS="./detections/splunk/detections" npm start
307
+ SIGMA_PATHS="./detections/sigma/rules" \
308
+ SPLUNK_PATHS="./detections/splunk/detections" \
309
+ ELASTIC_PATHS="./detections/elastic/rules" \
310
+ STORY_PATHS="./detections/splunk/stories" \
311
+ npm start
184
312
  ```
185
313
 
314
+ ## Stats (with full content)
315
+
316
+ When fully indexed with all sources:
317
+
318
+ | Source | Count |
319
+ |--------|-------|
320
+ | Sigma Rules | ~3,000+ |
321
+ | Splunk ESCU | ~2,000+ |
322
+ | Elastic Rules | ~1,500+ |
323
+ | Analytic Stories | ~330 |
324
+ | **Total** | **~6,500+** |
325
+
186
326
  ## License
187
327
 
188
328
  Apache 2.0
package/dist/db.d.ts CHANGED
@@ -1,17 +1,31 @@
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', 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 listByMitreTactic(tactic: string, limit?: number, offset?: number): Detection[];
14
21
  export declare function getStats(): IndexStats;
15
22
  export declare function getRawYaml(id: string): string | null;
16
23
  export declare function dbExists(): boolean;
17
24
  export declare function getDetectionCount(): number;
25
+ export declare function insertStory(story: AnalyticStory): void;
26
+ export declare function getStoryByName(name: string): AnalyticStory | null;
27
+ export declare function getStoryById(id: string): AnalyticStory | null;
28
+ export declare function searchStories(query: string, limit?: number): AnalyticStory[];
29
+ export declare function listStories(limit?: number, offset?: number): AnalyticStory[];
30
+ export declare function listStoriesByCategory(category: string, limit?: number, offset?: number): AnalyticStory[];
31
+ export declare function getStoryCount(): number;