security-detections-mcp 3.2.1 → 3.3.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 +160 -1310
- package/dist/db/detections.d.ts +8 -8
- package/dist/db/detections.js +13 -1
- package/dist/db.d.ts +3 -3
- package/dist/db.js +13 -1
- package/dist/handlers/resources.js +13 -13
- package/dist/index.js +4 -3
- package/dist/indexer.d.ts +3 -1
- package/dist/indexer.js +21 -2
- package/dist/parsers/jamf_protect.d.ts +2 -0
- package/dist/parsers/jamf_protect.js +220 -0
- package/dist/resources/index.js +17 -22
- package/dist/server.js +1 -1
- package/dist/tools/autonomous/index.js +3 -2
- package/dist/tools/cache/index.js +6 -3
- package/dist/tools/detections/actor-analysis.js +1 -1
- package/dist/tools/detections/analysis.js +7 -7
- package/dist/tools/detections/comparison.js +3 -3
- package/dist/tools/detections/filters.js +1 -1
- package/dist/tools/detections/search.js +1 -1
- package/dist/tools/engineering/index.js +2 -2
- package/dist/types/detection.d.ts +27 -2
- package/dist/types/index.d.ts +1 -1
- package/dist/types/stats.d.ts +2 -0
- package/package.json +5 -2
|
@@ -17,6 +17,9 @@ const SPLUNK_PATHS = parsePaths(process.env.SPLUNK_PATHS);
|
|
|
17
17
|
const ELASTIC_PATHS = parsePaths(process.env.ELASTIC_PATHS);
|
|
18
18
|
const STORY_PATHS = parsePaths(process.env.STORY_PATHS);
|
|
19
19
|
const KQL_PATHS = parsePaths(process.env.KQL_PATHS);
|
|
20
|
+
const SUBLIME_PATHS = parsePaths(process.env.SUBLIME_PATHS);
|
|
21
|
+
const CQL_HUB_PATHS = parsePaths(process.env.CQL_HUB_PATHS);
|
|
22
|
+
const JAMF_PROTECT_PATHS = parsePaths(process.env.JAMF_PROTECT_PATHS);
|
|
20
23
|
// =============================================================================
|
|
21
24
|
// Saved Query Tools
|
|
22
25
|
// =============================================================================
|
|
@@ -154,10 +157,10 @@ const rebuildIndexTool = defineTool({
|
|
|
154
157
|
handler: async (args) => {
|
|
155
158
|
const confirmArg = args?.confirm;
|
|
156
159
|
const skipElicitation = args?.skip_elicitation;
|
|
157
|
-
if (SIGMA_PATHS.length === 0 && SPLUNK_PATHS.length === 0 && ELASTIC_PATHS.length === 0 && KQL_PATHS.length === 0) {
|
|
160
|
+
if (SIGMA_PATHS.length === 0 && SPLUNK_PATHS.length === 0 && ELASTIC_PATHS.length === 0 && KQL_PATHS.length === 0 && SUBLIME_PATHS.length === 0 && CQL_HUB_PATHS.length === 0 && JAMF_PROTECT_PATHS.length === 0) {
|
|
158
161
|
return {
|
|
159
162
|
error: true,
|
|
160
|
-
message: 'No paths configured. Set SIGMA_PATHS, SPLUNK_PATHS, ELASTIC_PATHS, and/or
|
|
163
|
+
message: 'No paths configured. Set SIGMA_PATHS, SPLUNK_PATHS, ELASTIC_PATHS, KQL_PATHS, SUBLIME_PATHS, CQL_HUB_PATHS, and/or JAMF_PROTECT_PATHS environment variables.',
|
|
161
164
|
};
|
|
162
165
|
}
|
|
163
166
|
const currentStats = getStats();
|
|
@@ -225,7 +228,7 @@ const rebuildIndexTool = defineTool({
|
|
|
225
228
|
console.error('[security-detections-mcp] Rebuilding index...');
|
|
226
229
|
// Recreate DB to apply schema changes
|
|
227
230
|
recreateDb();
|
|
228
|
-
const result = indexDetections(SIGMA_PATHS, SPLUNK_PATHS, STORY_PATHS, ELASTIC_PATHS, KQL_PATHS);
|
|
231
|
+
const result = indexDetections(SIGMA_PATHS, SPLUNK_PATHS, STORY_PATHS, ELASTIC_PATHS, KQL_PATHS, SUBLIME_PATHS, CQL_HUB_PATHS, JAMF_PROTECT_PATHS);
|
|
229
232
|
// Notify subscribers that resources have changed
|
|
230
233
|
try {
|
|
231
234
|
await notifyResourceChange('detection://stats');
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { defineTool } from '../registry.js';
|
|
8
8
|
import { isStixLoaded, getActorByName, listActors, getActorTechniques, getActorCoverage, getSoftwareForActor, getAttackStats, generateNavigatorLayer, } from '../../db/index.js';
|
|
9
|
-
const SOURCE_TYPES = ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql'];
|
|
9
|
+
const SOURCE_TYPES = ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql', 'jamf_protect'];
|
|
10
10
|
function stixNotLoadedError() {
|
|
11
11
|
return {
|
|
12
12
|
error: true,
|
|
@@ -24,7 +24,7 @@ export const analysisTools = [
|
|
|
24
24
|
properties: {
|
|
25
25
|
source_type: {
|
|
26
26
|
type: 'string',
|
|
27
|
-
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql'],
|
|
27
|
+
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql', 'jamf_protect'],
|
|
28
28
|
description: 'Filter by source type',
|
|
29
29
|
},
|
|
30
30
|
tactic: {
|
|
@@ -67,7 +67,7 @@ export const analysisTools = [
|
|
|
67
67
|
properties: {
|
|
68
68
|
source_type: {
|
|
69
69
|
type: 'string',
|
|
70
|
-
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql'],
|
|
70
|
+
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql', 'jamf_protect'],
|
|
71
71
|
description: 'Filter by source type (optional - analyzes all if not specified)',
|
|
72
72
|
},
|
|
73
73
|
},
|
|
@@ -91,7 +91,7 @@ export const analysisTools = [
|
|
|
91
91
|
},
|
|
92
92
|
source_type: {
|
|
93
93
|
type: 'string',
|
|
94
|
-
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql'],
|
|
94
|
+
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql', 'jamf_protect'],
|
|
95
95
|
description: 'Filter by source type (optional)',
|
|
96
96
|
},
|
|
97
97
|
},
|
|
@@ -125,7 +125,7 @@ export const analysisTools = [
|
|
|
125
125
|
},
|
|
126
126
|
source_type: {
|
|
127
127
|
type: 'string',
|
|
128
|
-
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql'],
|
|
128
|
+
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql', 'jamf_protect'],
|
|
129
129
|
description: 'Filter by source type (optional)',
|
|
130
130
|
},
|
|
131
131
|
},
|
|
@@ -177,7 +177,7 @@ export const analysisTools = [
|
|
|
177
177
|
},
|
|
178
178
|
source_type: {
|
|
179
179
|
type: 'string',
|
|
180
|
-
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql'],
|
|
180
|
+
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql', 'jamf_protect'],
|
|
181
181
|
description: 'Filter to specific source type (optional — includes all if omitted)',
|
|
182
182
|
},
|
|
183
183
|
tactic: {
|
|
@@ -228,7 +228,7 @@ export const analysisTools = [
|
|
|
228
228
|
},
|
|
229
229
|
source_type: {
|
|
230
230
|
type: 'string',
|
|
231
|
-
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql'],
|
|
231
|
+
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql', 'jamf_protect'],
|
|
232
232
|
description: 'Filter to specific source (optional — analyzes all if omitted)',
|
|
233
233
|
},
|
|
234
234
|
include_query_snippets: {
|
|
@@ -266,7 +266,7 @@ export const analysisTools = [
|
|
|
266
266
|
type: 'array',
|
|
267
267
|
items: {
|
|
268
268
|
type: 'string',
|
|
269
|
-
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql'],
|
|
269
|
+
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql', 'jamf_protect'],
|
|
270
270
|
},
|
|
271
271
|
description: 'Sources to compare (default: all available)',
|
|
272
272
|
},
|
|
@@ -15,7 +15,7 @@ export const comparisonTools = [
|
|
|
15
15
|
},
|
|
16
16
|
source_type: {
|
|
17
17
|
type: 'string',
|
|
18
|
-
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql'],
|
|
18
|
+
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql', 'jamf_protect'],
|
|
19
19
|
description: 'Optional: filter by source type',
|
|
20
20
|
},
|
|
21
21
|
limit: {
|
|
@@ -147,7 +147,7 @@ export const comparisonTools = [
|
|
|
147
147
|
},
|
|
148
148
|
source_type: {
|
|
149
149
|
type: 'string',
|
|
150
|
-
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql'],
|
|
150
|
+
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql', 'jamf_protect'],
|
|
151
151
|
description: 'Optional: filter to specific source',
|
|
152
152
|
},
|
|
153
153
|
},
|
|
@@ -235,7 +235,7 @@ export const comparisonTools = [
|
|
|
235
235
|
properties: {
|
|
236
236
|
source_type: {
|
|
237
237
|
type: 'string',
|
|
238
|
-
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql'],
|
|
238
|
+
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql', 'jamf_protect'],
|
|
239
239
|
description: 'Filter by source type (optional)',
|
|
240
240
|
},
|
|
241
241
|
},
|
|
@@ -10,7 +10,7 @@ export const filterTools = [
|
|
|
10
10
|
properties: {
|
|
11
11
|
source_type: {
|
|
12
12
|
type: 'string',
|
|
13
|
-
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql'],
|
|
13
|
+
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql', 'jamf_protect'],
|
|
14
14
|
description: 'Source type to filter by',
|
|
15
15
|
},
|
|
16
16
|
limit: {
|
|
@@ -22,7 +22,7 @@ export const searchTools = [
|
|
|
22
22
|
},
|
|
23
23
|
source_type: {
|
|
24
24
|
type: 'string',
|
|
25
|
-
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql'],
|
|
25
|
+
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql', 'jamf_protect'],
|
|
26
26
|
description: 'Filter results by detection source type',
|
|
27
27
|
},
|
|
28
28
|
},
|
|
@@ -27,7 +27,7 @@ const getQueryPatternsTool = defineTool({
|
|
|
27
27
|
},
|
|
28
28
|
source_type: {
|
|
29
29
|
type: 'string',
|
|
30
|
-
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql'],
|
|
30
|
+
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql', 'jamf_protect'],
|
|
31
31
|
description: 'Filter patterns by source type (optional)',
|
|
32
32
|
},
|
|
33
33
|
},
|
|
@@ -175,7 +175,7 @@ const findSimilarDetectionsTool = defineTool({
|
|
|
175
175
|
},
|
|
176
176
|
source_type: {
|
|
177
177
|
type: 'string',
|
|
178
|
-
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql'],
|
|
178
|
+
enum: ['sigma', 'splunk_escu', 'elastic', 'kql', 'sublime', 'crowdstrike_cql', 'jamf_protect'],
|
|
179
179
|
description: 'Filter by source type (optional)',
|
|
180
180
|
},
|
|
181
181
|
limit: {
|
|
@@ -10,7 +10,7 @@ export interface Detection {
|
|
|
10
10
|
name: string;
|
|
11
11
|
description: string;
|
|
12
12
|
query: string;
|
|
13
|
-
source_type: 'sigma' | 'splunk_escu' | 'elastic' | 'kql' | 'sublime' | 'crowdstrike_cql';
|
|
13
|
+
source_type: 'sigma' | 'splunk_escu' | 'elastic' | 'kql' | 'sublime' | 'crowdstrike_cql' | 'jamf_protect';
|
|
14
14
|
mitre_ids: string[];
|
|
15
15
|
logsource_category: string | null;
|
|
16
16
|
logsource_product: string | null;
|
|
@@ -49,7 +49,7 @@ export interface Detection {
|
|
|
49
49
|
export interface DetectionSummary {
|
|
50
50
|
id: string;
|
|
51
51
|
name: string;
|
|
52
|
-
source_type: 'sigma' | 'splunk_escu' | 'elastic' | 'kql' | 'sublime' | 'crowdstrike_cql';
|
|
52
|
+
source_type: 'sigma' | 'splunk_escu' | 'elastic' | 'kql' | 'sublime' | 'crowdstrike_cql' | 'jamf_protect';
|
|
53
53
|
mitre_ids: string[];
|
|
54
54
|
severity: string | null;
|
|
55
55
|
mitre_tactics: string[];
|
|
@@ -190,6 +190,31 @@ export interface ElasticTechnique {
|
|
|
190
190
|
reference?: string;
|
|
191
191
|
subtechnique?: ElasticTechnique[];
|
|
192
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* Jamf Protect custom analytic detection structure (YAML with NSPredicate filter).
|
|
195
|
+
* @see https://github.com/jamf/jamfprotect/tree/main/custom_analytic_detections
|
|
196
|
+
*/
|
|
197
|
+
export interface JamfProtectRule {
|
|
198
|
+
name: string;
|
|
199
|
+
uuid?: string;
|
|
200
|
+
label?: string;
|
|
201
|
+
shortDescription?: string;
|
|
202
|
+
longDescription?: string;
|
|
203
|
+
level?: number;
|
|
204
|
+
inputType?: 'GPProcessEvent' | 'GPFSEvent' | 'GPKeylogRegisterEvent' | 'GPUSBEvent' | string;
|
|
205
|
+
filter: string;
|
|
206
|
+
severity?: 'Informational' | 'Low' | 'Medium' | 'High' | 'Critical' | string;
|
|
207
|
+
categories?: string[];
|
|
208
|
+
MitreCategories?: string[] | null;
|
|
209
|
+
tags?: string[] | null;
|
|
210
|
+
snapshotFiles?: string[] | null;
|
|
211
|
+
actions?: Array<{
|
|
212
|
+
name?: string;
|
|
213
|
+
} | string>;
|
|
214
|
+
context?: string[] | null;
|
|
215
|
+
version?: number;
|
|
216
|
+
remediation?: string | null;
|
|
217
|
+
}
|
|
193
218
|
/**
|
|
194
219
|
* CQL Hub rule structure (CrowdStrike Query Language)
|
|
195
220
|
* @see https://github.com/ByteRay-Labs/Query-Hub
|
package/dist/types/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* - dynamic: Dynamic table types for runtime schema extension
|
|
12
12
|
* - meta: Meta-tool types for custom tools and workflows
|
|
13
13
|
*/
|
|
14
|
-
export type { Detection, DetectionSummary, SigmaRule, SplunkDetection, ElasticRule, ElasticThreat, ElasticTechnique, SublimeRule, CqlHubRule, } from './detection.js';
|
|
14
|
+
export type { Detection, DetectionSummary, SigmaRule, SplunkDetection, ElasticRule, ElasticThreat, ElasticTechnique, SublimeRule, CqlHubRule, JamfProtectRule, } from './detection.js';
|
|
15
15
|
export type { AnalyticStory, SplunkStoryYaml, } from './story.js';
|
|
16
16
|
export type { IndexStats, SourceComparison, SavedQuery, } from './stats.js';
|
|
17
17
|
export type { KnowledgeEntity, KnowledgeRelation, KnowledgeObservation, KnowledgeDecision, KnowledgeLearning, KnowledgeQueryOptions, } from './knowledge.js';
|
package/dist/types/stats.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "security-detections-mcp",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.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,11 +20,12 @@
|
|
|
20
20
|
"build": "tsc",
|
|
21
21
|
"start": "node dist/index.js",
|
|
22
22
|
"dev": "tsc --watch",
|
|
23
|
-
"test": "npm run build && node tests/cross-platform-test.js && node tests/integration-test.js && node tests/engineering-tools-test.js",
|
|
23
|
+
"test": "npm run build && node tests/cross-platform-test.js && node tests/jamf-parser-test.js && node tests/integration-test.js && node tests/engineering-tools-test.js",
|
|
24
24
|
"test:platform": "npm run build && node tests/cross-platform-test.js",
|
|
25
25
|
"test:ci": "npm run build && node tests/ci-integration-test.js",
|
|
26
26
|
"test:integration": "npm run build && node tests/integration-test.js",
|
|
27
27
|
"test:engineering": "npm run build && node tests/engineering-tools-test.js",
|
|
28
|
+
"test:jamf": "npm run build && node tests/jamf-parser-test.js",
|
|
28
29
|
"lint": "tsc --noEmit --strict",
|
|
29
30
|
"prepublishOnly": "npm run build && npm run lint"
|
|
30
31
|
},
|
|
@@ -43,6 +44,8 @@
|
|
|
43
44
|
"sublime",
|
|
44
45
|
"crowdstrike",
|
|
45
46
|
"cql",
|
|
47
|
+
"jamf",
|
|
48
|
+
"macos",
|
|
46
49
|
"siem",
|
|
47
50
|
"mitre",
|
|
48
51
|
"attack"
|