security-detections-mcp 2.1.0 → 3.0.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 +98 -0
- package/dist/db/connection.d.ts +1 -0
- package/dist/db/connection.js +36 -3
- package/dist/db.js +31 -3
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -2,8 +2,106 @@
|
|
|
2
2
|
|
|
3
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
|
+
> **New here? Start with the [Setup Guide](./SETUP.md)** -- covers macOS, Windows (WSL & native), and Linux step by step.
|
|
6
|
+
|
|
7
|
+
## What's New in 3.0 - Autonomous Detection Platform
|
|
8
|
+
|
|
9
|
+
Version 3.0 transforms this MCP into a **fully autonomous detection engineering platform**. Feed it threat intelligence, and it automatically:
|
|
10
|
+
|
|
11
|
+
1. **Extracts TTPs** from threat reports, CISA alerts, or manual input
|
|
12
|
+
2. **Analyzes coverage gaps** against your existing detections
|
|
13
|
+
3. **Generates detections** in your SIEM's native format (SPL, KQL, EQL, or Sigma)
|
|
14
|
+
4. **Runs Atomic Red Team tests** against your lab environment
|
|
15
|
+
5. **Validates detections fire** by querying your SIEM
|
|
16
|
+
6. **Exports attack data** for reproducibility
|
|
17
|
+
7. **Stages DRAFT PRs** to your detection repo (never auto-merges)
|
|
18
|
+
|
|
19
|
+
> **Multi-SIEM**: Set `SIEM_PLATFORM` to `splunk`, `sentinel`, `elastic`, or `sigma` in your `.env`. The pipeline was built on Splunk + Attack Range but adapts to any SIEM. See the **[E2E Testing Guide](./docs/E2E-TESTING-GUIDE.md)** for complete setup instructions per platform.
|
|
20
|
+
|
|
21
|
+
### Architecture: LangGraph + Cursor Subagents
|
|
22
|
+
|
|
23
|
+
The 3.0 architecture uses two complementary systems:
|
|
24
|
+
|
|
25
|
+
| Component | Purpose | Location |
|
|
26
|
+
|-----------|---------|----------|
|
|
27
|
+
| **LangGraph Pipeline** | Core autonomous workflow - portable, testable, CI/CD ready | `agents/` |
|
|
28
|
+
| **Cursor Subagents** | Interactive IDE agents for manual tasks | `.cursor/agents/` |
|
|
29
|
+
|
|
30
|
+
### Quick Start - Autonomous Mode
|
|
31
|
+
|
|
32
|
+
**Prerequisites**: Node.js 20+, an Anthropic API key. Full details in the [Setup Guide](./SETUP.md).
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# Install the agents package
|
|
36
|
+
cd agents && npm install --registry https://registry.npmjs.org/
|
|
37
|
+
|
|
38
|
+
# Configure
|
|
39
|
+
cp .env.example .env
|
|
40
|
+
# Edit .env: set SIEM_PLATFORM, ANTHROPIC_API_KEY, SECURITY_CONTENT_PATH
|
|
41
|
+
|
|
42
|
+
# Test with dry run first (uses mock data, no LLM calls)
|
|
43
|
+
DRY_RUN=true npm run orchestrate -- --type technique --input "T1566.004 Spearphishing Voice"
|
|
44
|
+
|
|
45
|
+
# Run with real LLM (creates actual detections)
|
|
46
|
+
npm run orchestrate -- --type technique --input "T1566.004 Spearphishing Voice"
|
|
47
|
+
|
|
48
|
+
# Or analyze a CISA alert
|
|
49
|
+
npm run orchestrate -- --type cisa_alert --url https://www.cisa.gov/news-events/alerts/...
|
|
50
|
+
|
|
51
|
+
# Or feed it a threat report
|
|
52
|
+
npm run orchestrate -- --type threat_report --file ./report.md
|
|
53
|
+
|
|
54
|
+
# Note: Use T1566.004 for testing - it has no existing coverage so will create a detection
|
|
55
|
+
# T1003.001 has 100+ existing detections, so the pipeline will correctly skip it (no gap)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Pipeline Stages
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
┌─────────────┐ ┌──────────────────┐ ┌────────────────────┐
|
|
62
|
+
│ CTI Analyst │───>│ Coverage Analyzer│───>│ Detection Engineer │
|
|
63
|
+
└─────────────┘ └──────────────────┘ └────────────────────┘
|
|
64
|
+
│
|
|
65
|
+
▼
|
|
66
|
+
┌───────────┐ ┌──────────────────┐ ┌──────────────────────┐
|
|
67
|
+
│ PR Stager │<───│ Data Dumper │<───│ Splunk Validator │
|
|
68
|
+
└───────────┘ └──────────────────┘ └──────────────────────┘
|
|
69
|
+
▲
|
|
70
|
+
│
|
|
71
|
+
┌──────────────────┐
|
|
72
|
+
│ Atomic Executor │
|
|
73
|
+
└──────────────────┘
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### MCP Integration
|
|
77
|
+
|
|
78
|
+
The autonomous pipeline integrates with existing MCPs:
|
|
79
|
+
- **security-detections** - Coverage analysis and gap identification
|
|
80
|
+
- **splunk-mcp** - Detection validation (`run_detection`, `export_dump`)
|
|
81
|
+
- **mitre-attack** - Technique lookups
|
|
82
|
+
|
|
83
|
+
### Human-in-the-Loop
|
|
84
|
+
|
|
85
|
+
**CRITICAL**: The system NEVER auto-commits or auto-merges. All PRs are created as **DRAFT** requiring human review:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
[PR Stager] ✓ security_content DRAFT PR created: https://github.com/splunk/security_content/pull/123
|
|
89
|
+
[PR Stager] ✓ attack_data DRAFT PR created: https://github.com/splunk/attack_data/pull/456
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
See the [Autonomous Platform Documentation](./docs/AUTONOMOUS.md) for full details, and the [E2E Testing Guide](./docs/E2E-TESTING-GUIDE.md) for per-SIEM setup (Splunk, Sentinel, Elastic, Sigma).
|
|
93
|
+
|
|
5
94
|
[](https://cursor.com/en/install-mcp?name=security-detections&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsInNlY3VyaXR5LWRldGVjdGlvbnMtbWNwIl0sImVudiI6eyJTSUdNQV9QQVRIUyI6Ii9wYXRoL3RvL3NpZ21hL3J1bGVzLC9wYXRoL3RvL3NpZ21hL3J1bGVzLXRocmVhdC1odW50aW5nIiwiU1BMVU5LX1BBVEhTIjoiL3BhdGgvdG8vc2VjdXJpdHlfY29udGVudC9kZXRlY3Rpb25zIiwiU1RPUllfUEFUSFMiOiIvcGF0aC90by9zZWN1cml0eV9jb250ZW50L3N0b3JpZXMiLCJFTEFTVElDX1BBVEhTIjoiL3BhdGgvdG8vZGV0ZWN0aW9uLXJ1bGVzL3J1bGVzIiwiS1FMX1BBVEhTIjoiL3BhdGgvdG8va3FsLXJ1bGVzIn19)
|
|
6
95
|
|
|
96
|
+
> **Detailed setup**: See the **[Setup Guide](./SETUP.md)** for step-by-step install on macOS, Windows (WSL & native), and Linux with troubleshooting for common issues.
|
|
97
|
+
|
|
98
|
+
## 🐛 Version 2.1.1 (Bug Fix)
|
|
99
|
+
|
|
100
|
+
- **Fixed Windows EBUSY crash** - SQLite database recreation now handles Windows file locking with retry logic. Previously, Windows users would get `EBUSY: resource busy or locked` on startup.
|
|
101
|
+
- **SQLite journal cleanup** - WAL, SHM, and journal companion files are now cleaned up during database recreation.
|
|
102
|
+
- **Windows CI** - Added Windows to the CI matrix. Build, tests, and full Sigma indexing pipeline now run on both Linux and Windows.
|
|
103
|
+
- **Cross-platform test suite** - New `tests/cross-platform-test.js` validates database lifecycle on all platforms. New `tests/ci-integration-test.js` downloads and indexes 3,200+ Sigma rules to validate the full pipeline.
|
|
104
|
+
|
|
7
105
|
## 🚀 Version 2.1 Features
|
|
8
106
|
|
|
9
107
|
**Security Detections MCP v2.1** introduces powerful new capabilities for detection engineering intelligence, analytical memory, autonomous analysis, and advanced MCP protocol features:
|
package/dist/db/connection.d.ts
CHANGED
package/dist/db/connection.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Manages SQLite connection singleton, path management, and database lifecycle.
|
|
5
5
|
*/
|
|
6
6
|
import Database from 'better-sqlite3';
|
|
7
|
-
import { homedir } from 'os';
|
|
7
|
+
import { homedir, platform } from 'os';
|
|
8
8
|
import { join } from 'path';
|
|
9
9
|
import { mkdirSync, existsSync, unlinkSync } from 'fs';
|
|
10
10
|
import { createSchema } from './schema.js';
|
|
@@ -143,18 +143,51 @@ export function clearDb() {
|
|
|
143
143
|
const database = initDb();
|
|
144
144
|
database.exec('DELETE FROM detections');
|
|
145
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* Safely delete a file with retry logic for Windows.
|
|
148
|
+
* Windows can throw EBUSY/EPERM if the file handle isn't fully released yet.
|
|
149
|
+
*/
|
|
150
|
+
function safeUnlink(filePath, maxRetries = 5, delayMs = 100) {
|
|
151
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
152
|
+
try {
|
|
153
|
+
if (existsSync(filePath)) {
|
|
154
|
+
unlinkSync(filePath);
|
|
155
|
+
}
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
const code = err.code;
|
|
160
|
+
// EBUSY = file is busy, EPERM = operation not permitted, EACCES = access denied
|
|
161
|
+
if ((code === 'EBUSY' || code === 'EPERM' || code === 'EACCES') && attempt < maxRetries - 1) {
|
|
162
|
+
// Spin-wait since we need synchronous behavior
|
|
163
|
+
const end = Date.now() + delayMs * (attempt + 1);
|
|
164
|
+
while (Date.now() < end) { /* wait */ }
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
throw err;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
146
171
|
/**
|
|
147
172
|
* Force recreation of the database.
|
|
148
173
|
* Useful when schema changes require a fresh start.
|
|
174
|
+
* Handles Windows file locking (EBUSY) with retry logic.
|
|
149
175
|
*/
|
|
150
176
|
export function recreateDb() {
|
|
151
177
|
if (db) {
|
|
152
178
|
db.close();
|
|
153
179
|
db = null;
|
|
154
180
|
}
|
|
155
|
-
|
|
156
|
-
|
|
181
|
+
// Small delay on Windows to let file handles fully release
|
|
182
|
+
if (platform() === 'win32') {
|
|
183
|
+
const end = Date.now() + 100;
|
|
184
|
+
while (Date.now() < end) { /* wait */ }
|
|
157
185
|
}
|
|
186
|
+
// Delete main db and SQLite journal/WAL files
|
|
187
|
+
safeUnlink(DB_PATH);
|
|
188
|
+
safeUnlink(DB_PATH + '-wal');
|
|
189
|
+
safeUnlink(DB_PATH + '-shm');
|
|
190
|
+
safeUnlink(DB_PATH + '-journal');
|
|
158
191
|
}
|
|
159
192
|
/**
|
|
160
193
|
* Check if the database file exists.
|
package/dist/db.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Database from 'better-sqlite3';
|
|
2
|
-
import { homedir } from 'os';
|
|
2
|
+
import { homedir, platform } from 'os';
|
|
3
3
|
import { join } from 'path';
|
|
4
4
|
import { mkdirSync, existsSync, unlinkSync } from 'fs';
|
|
5
5
|
const CACHE_DIR = join(homedir(), '.cache', 'security-detections-mcp');
|
|
@@ -158,15 +158,43 @@ export function clearDb() {
|
|
|
158
158
|
const database = initDb();
|
|
159
159
|
database.exec('DELETE FROM detections');
|
|
160
160
|
}
|
|
161
|
+
// Safely delete a file with retry logic for Windows (EBUSY/EPERM)
|
|
162
|
+
function safeUnlink(filePath, maxRetries = 5, delayMs = 100) {
|
|
163
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
164
|
+
try {
|
|
165
|
+
if (existsSync(filePath)) {
|
|
166
|
+
unlinkSync(filePath);
|
|
167
|
+
}
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
const code = err.code;
|
|
172
|
+
if ((code === 'EBUSY' || code === 'EPERM' || code === 'EACCES') && attempt < maxRetries - 1) {
|
|
173
|
+
const end = Date.now() + delayMs * (attempt + 1);
|
|
174
|
+
while (Date.now() < end) { /* wait */ }
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
throw err;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
161
181
|
// Force recreation of the database (needed when schema changes)
|
|
182
|
+
// Handles Windows file locking with retry logic
|
|
162
183
|
export function recreateDb() {
|
|
163
184
|
if (db) {
|
|
164
185
|
db.close();
|
|
165
186
|
db = null;
|
|
166
187
|
}
|
|
167
|
-
|
|
168
|
-
|
|
188
|
+
// Small delay on Windows to let file handles fully release
|
|
189
|
+
if (platform() === 'win32') {
|
|
190
|
+
const end = Date.now() + 100;
|
|
191
|
+
while (Date.now() < end) { /* wait */ }
|
|
169
192
|
}
|
|
193
|
+
// Delete main db and SQLite journal/WAL files
|
|
194
|
+
safeUnlink(DB_PATH);
|
|
195
|
+
safeUnlink(DB_PATH + '-wal');
|
|
196
|
+
safeUnlink(DB_PATH + '-shm');
|
|
197
|
+
safeUnlink(DB_PATH + '-journal');
|
|
170
198
|
}
|
|
171
199
|
export function insertDetection(detection) {
|
|
172
200
|
const database = initDb();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "security-detections-mcp",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Advanced MCP server for security detections with Detection Engineering Intelligence, Knowledge Graph (Tribal Knowledge), Elicitation, and Resource Subscriptions",
|
|
5
5
|
"sigmaSpecVersion": "2.0.0",
|
|
6
6
|
"type": "module",
|
|
@@ -20,7 +20,9 @@
|
|
|
20
20
|
"build": "tsc",
|
|
21
21
|
"start": "node dist/index.js",
|
|
22
22
|
"dev": "tsc --watch",
|
|
23
|
-
"test": "npm run build && node tests/integration-test.js && node tests/engineering-tools-test.js",
|
|
23
|
+
"test": "npm run build && node tests/cross-platform-test.js && node tests/integration-test.js && node tests/engineering-tools-test.js",
|
|
24
|
+
"test:platform": "npm run build && node tests/cross-platform-test.js",
|
|
25
|
+
"test:ci": "npm run build && node tests/ci-integration-test.js",
|
|
24
26
|
"test:integration": "npm run build && node tests/integration-test.js",
|
|
25
27
|
"test:engineering": "npm run build && node tests/engineering-tools-test.js",
|
|
26
28
|
"lint": "tsc --noEmit --strict",
|