@pmoses-s1/s1-secops-mcp 1.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.
@@ -0,0 +1,128 @@
1
+ /**
2
+ * UAM Alert Interface tools: push OCSF indicators + alerts INTO UAM
3
+ * via the SentinelOne HEC ingest host (ingest.us1.sentinelone.net).
4
+ *
5
+ * Tools:
6
+ * uam_ingest_alert End-to-end: build + POST one FileSystem indicator + one SecurityAlert
7
+ * uam_post_indicators Low-level: POST raw OCSF indicators to /v1/indicators
8
+ * uam_post_alert Low-level: POST a single raw OCSF SecurityAlert to /v1/alerts
9
+ *
10
+ * These tools require S1_HEC_INGEST_URL in credentials.json in addition to
11
+ * S1_CONSOLE_API_TOKEN (same token, Bearer prefix instead of ApiToken).
12
+ */
13
+
14
+ import { ingestAlert, ingestAlertInline, postIndicators, postAlert } from '../lib/uam-ingest.js';
15
+
16
+ export const tools = [
17
+
18
+ // ─── uam_ingest_alert ─────────────────────────────────────────────────────
19
+ {
20
+ name: 'uam_ingest_alert',
21
+ description: `Create a synthetic test alert in Unified Alert Management (UAM) via the SentinelOne HEC ingest API. Supports two modes controlled by the "inline" parameter:
22
+
23
+ Two-call mode (inline=false, default): POST indicator to /v1/indicators, sleep 3s, POST SecurityAlert to /v1/alerts referencing the indicator uid. The stitcher resolves the full indicator into alert.rawIndicators. Best for testing deep indicator stitching and the Indicators tab in UAM.
24
+
25
+ Inline mode (inline=true): POST a single SecurityAlert to /v1/alerts with the indicator's file/device/actor fields embedded inside finding_info.related_events[]. No separate indicator POST, no sleep, one round-trip. Best for rapid alert creation or when a single call is preferred.
26
+
27
+ Both modes return indicator_uid and alert_uid. The alert surfaces in UAM within 30-60s. Requires S1_HEC_INGEST_URL in credentials.json.`,
28
+ inputSchema: {
29
+ type: 'object',
30
+ properties: {
31
+ scope: {
32
+ type: 'string',
33
+ description: 'Mandatory. accountId or "accountId:siteId" (colon-separated). Find the accountId via s1_api_get /web/api/v2.1/accounts?limit=1.',
34
+ },
35
+ title: {
36
+ type: 'string',
37
+ description: 'Alert name shown in UAM. Default: "MCP Test Alert".',
38
+ default: 'MCP Test Alert',
39
+ },
40
+ description: {
41
+ type: 'string',
42
+ description: 'Alert description body. Default: generic synthetic alert text.',
43
+ },
44
+ hostname: {
45
+ type: 'string',
46
+ description: 'Hostname to use for the synthetic indicator device. Default: "mcp-test-host".',
47
+ default: 'mcp-test-host',
48
+ },
49
+ filename: {
50
+ type: 'string',
51
+ description: 'Filename for the OCSF FileSystem Activity indicator. Default: "test-payload.exe".',
52
+ default: 'test-payload.exe',
53
+ },
54
+ sha256: {
55
+ type: 'string',
56
+ description: 'SHA-256 hash (64 lowercase hex chars). If omitted, a zeroed placeholder hash is used.',
57
+ },
58
+ sleep_ms: {
59
+ type: 'number',
60
+ description: 'Two-call mode only. Milliseconds to sleep between the indicator POST and the alert POST. Default 3000. Do not go below 2000 on loaded tenants.',
61
+ default: 3000,
62
+ },
63
+ inline: {
64
+ type: 'boolean',
65
+ description: 'When true, embed indicator data (file, device, actor, observables) directly inside the alert\'s finding_info.related_events[] and POST only to /v1/alerts; no separate /v1/indicators call, no sleep. When false (default), use the two-call flow: POST indicator first, sleep, then POST alert.',
66
+ default: false,
67
+ },
68
+ },
69
+ required: ['scope'],
70
+ },
71
+ async handler({ scope, title, description, hostname, filename, sha256, sleep_ms = 3000, inline = false }) {
72
+ const result = inline
73
+ ? await ingestAlertInline({ scope, title, description, hostname, filename, sha256 })
74
+ : await ingestAlert({ scope, title, description, hostname, filename, sha256, sleepMs: sleep_ms });
75
+ return JSON.stringify(result, null, 2);
76
+ },
77
+ },
78
+
79
+ // ─── uam_post_indicators ──────────────────────────────────────────────────
80
+ {
81
+ name: 'uam_post_indicators',
82
+ description: `POST one or more raw OCSF behavioral indicators to /v1/indicators on the SentinelOne HEC ingest host. Batching is supported; pass multiple indicators in the array and they are sent in a single gzip-compressed request. Each indicator must carry metadata.profiles=["s1/security_indicator"] and a unique metadata.uid (used as the join key when an alert references it). After posting, wait at least 3s before posting a SecurityAlert that references these indicator uids (use uam_post_alert or uam_ingest_alert which enforce the sleep). Requires S1_HEC_INGEST_URL in credentials.json.`,
83
+ inputSchema: {
84
+ type: 'object',
85
+ properties: {
86
+ scope: {
87
+ type: 'string',
88
+ description: 'accountId or "accountId:siteId". Mandatory.',
89
+ },
90
+ indicators: {
91
+ type: 'array',
92
+ description: 'Array of OCSF indicator objects. Each must have metadata.uid, metadata.profiles=["s1/security_indicator"], class_uid, and observables[]. file.hashes must be a Fingerprint array [{algorithm_id, algorithm, value}], not a plain dict.',
93
+ items: { type: 'object', additionalProperties: true },
94
+ },
95
+ },
96
+ required: ['scope', 'indicators'],
97
+ },
98
+ async handler({ scope, indicators }) {
99
+ const result = await postIndicators({ scope, indicators });
100
+ return JSON.stringify(result, null, 2);
101
+ },
102
+ },
103
+
104
+ // ─── uam_post_alert ───────────────────────────────────────────────────────
105
+ {
106
+ name: 'uam_post_alert',
107
+ description: `POST a single raw OCSF SecurityAlert to /v1/alerts on the SentinelOne HEC ingest host. IMPORTANT: one alert per call. The HEC stitcher silently drops all but one alert in a multi-alert POST body (HTTP 202 still returned), so this tool rejects arrays. To send multiple alerts, loop this call. Always post indicator(s) first via uam_post_indicators and sleep at least 3s before calling this; posting an alert before its indicator uids are registered causes a silent drop. Requires S1_HEC_INGEST_URL in credentials.json.`,
108
+ inputSchema: {
109
+ type: 'object',
110
+ properties: {
111
+ scope: {
112
+ type: 'string',
113
+ description: 'accountId or "accountId:siteId". Mandatory.',
114
+ },
115
+ alert: {
116
+ type: 'object',
117
+ description: 'Single OCSF SecurityAlert object. class_uid MUST be 99602001 (S1 Security Alert extension class) with type_uid 9960200101; the generic OCSF 2002 is silently dropped by the stitcher even though HEC returns HTTP 202. Must have metadata.uid, finding_info.related_events[] each referencing a previously-posted indicator via uid. Each related_events entry needs class_uid, type_uid, category_uid, activity_id, severity_id, time, message, and observables[] with type+typeName.',
118
+ additionalProperties: true,
119
+ },
120
+ },
121
+ required: ['scope', 'alert'],
122
+ },
123
+ async handler({ scope, alert }) {
124
+ const result = await postAlert({ scope, alert });
125
+ return JSON.stringify(result, null, 2);
126
+ },
127
+ },
128
+ ];