chron-mcp 0.1.14 → 0.1.17

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,138 @@
1
+ # Chron → Splunk
2
+
3
+ Stream AI session telemetry from developer machines into Splunk via HTTP Event Collector (HEC). Works with Splunk Enterprise, Splunk Cloud, and a local Docker instance for testing.
4
+
5
+ ## Quickest way to see it working — Splunk Docker
6
+
7
+ The fastest path to visually verify the integration with no accounts or licenses:
8
+
9
+ ```bash
10
+ docker run -d \
11
+ --name splunk-chron \
12
+ --platform linux/amd64 \
13
+ -p 8000:8000 \
14
+ -p 8088:8088 \
15
+ -e SPLUNK_START_ARGS=--accept-license \
16
+ -e SPLUNK_PASSWORD=Admin1234! \
17
+ -e SPLUNK_HEC_TOKEN=chron-test-token \
18
+ splunk/splunk:latest
19
+ ```
20
+
21
+ > **Apple Silicon (M1/M2/M3):** The `--platform linux/amd64` flag is required — the Splunk image has no ARM64 manifest. Docker Desktop uses Rosetta 2 to emulate it automatically.
22
+
23
+ Wait ~2 minutes for Splunk to start, then:
24
+
25
+ ```bash
26
+ chron connect splunk
27
+ # URL: https://localhost:8088 ← HTTPS (Splunk 9.x uses SSL by default)
28
+ # Token: chron-test-token
29
+ ```
30
+
31
+ > Certificate verification is automatically skipped for localhost URLs — no extra flags needed.
32
+
33
+ Add to your MCP config and use your AI tool. Open [http://localhost:8000](http://localhost:8000) (admin / Admin1234!) and search:
34
+
35
+ ```
36
+ sourcetype="chron:event"
37
+ ```
38
+
39
+ Events appear in real time as you have AI conversations.
40
+
41
+ > Note: The default Docker image auto-creates a HEC token with the value you set in `SPLUNK_HEC_TOKEN`. If events aren't arriving, verify HEC is enabled under **Settings → Data Inputs → HTTP Event Collector**.
42
+
43
+ ---
44
+
45
+ ## Production setup — Splunk Enterprise or Cloud
46
+
47
+ ### Step 1 — Enable HTTP Event Collector
48
+
49
+ **Splunk Enterprise:** Settings → Data Inputs → HTTP Event Collector → Global Settings → Enable
50
+
51
+ **Splunk Cloud:** Settings → Data Inputs → HTTP Event Collector → New Token
52
+
53
+ ### Step 2 — Create a HEC token
54
+
55
+ 1. Settings → Data Inputs → HTTP Event Collector → New Token
56
+ 2. Name: `chron-ingest`
57
+ 3. Source type: `chron:event` (create new if prompted)
58
+ 4. Index: `main` (or a dedicated `chron` index)
59
+ 5. Copy the token value
60
+
61
+ ### Step 3 — Connect from the developer machine
62
+
63
+ ```bash
64
+ chron connect splunk
65
+ ```
66
+
67
+ Enter the HEC base URL and token when prompted. The command sends a test event and confirms before saving.
68
+
69
+ ### Step 4 — Add env vars to your MCP client
70
+
71
+ The `connect` command prints the exact block to paste. For Claude Code, add to the `chron` entry in `~/.claude.json`:
72
+
73
+ ```json
74
+ {
75
+ "mcpServers": {
76
+ "chron": {
77
+ "type": "stdio",
78
+ "command": "node",
79
+ "args": ["/path/to/dist/index.js"],
80
+ "env": {
81
+ "CHRON_SPLUNK_URL": "https://your-splunk-host:8088",
82
+ "CHRON_SPLUNK_TOKEN": "<your-hec-token>"
83
+ }
84
+ }
85
+ }
86
+ }
87
+ ```
88
+
89
+ ### Step 5 — Run SPL queries
90
+
91
+ In Splunk → Search & Reporting, run queries from this directory:
92
+
93
+ | File | Use |
94
+ |---|---|
95
+ | `events-by-type.spl` | Time-series — event volume by type |
96
+ | `sessions-by-developer.spl` | Table — sessions per host and AI tool |
97
+ | `secrets-detected.spl` | Table — credential exposures for SOC review |
98
+ | `ai-tool-usage.spl` | Summary — tool adoption breakdown |
99
+ | `daily-active-developers.spl` | Time-series — distinct active machines per day |
100
+ | `secrets-alert.spl` | Alert search — credential exposures (last 1h) |
101
+
102
+ ### Step 6 — Set up the credential alert (recommended)
103
+
104
+ 1. Search & Reporting → paste `secrets-alert.spl` → Save As → Alert
105
+ 2. Schedule: Run every hour
106
+ 3. Trigger: Number of results is greater than 0
107
+ 4. Action: Send email or create a notable event
108
+
109
+ ---
110
+
111
+ ## Event schema
112
+
113
+ All events arrive with `sourcetype=chron:event` and these fields:
114
+
115
+ | Field | Present on |
116
+ |---|---|
117
+ | `host` | All events: developer's machine hostname |
118
+ | `source` | All events: `chron-mcp` |
119
+ | `event_type` | All: `session_started`, `message_logged`, `secret_detected` |
120
+ | `session_id_prefix` | All events |
121
+ | `ai_tool` | All events: `claude`, `cursor`, `windsurf`, etc. |
122
+ | `os` | All events: `darwin`, `linux`, `win32` |
123
+ | `chron_version` | All events |
124
+ | `role` | `message_logged` only: `user` or `assistant` |
125
+ | `detection_type` | `secret_detected` only: `api_key`, `aws_key`, `jwt`, etc. |
126
+ | `masked_value` | `secret_detected` only: e.g. `AKIA****F3K2` |
127
+
128
+ **What is never transmitted:** message content, actual secret values, file paths, or any user-typed text.
129
+
130
+ ## Env vars
131
+
132
+ | Env var | Description |
133
+ |---|---|
134
+ | `CHRON_SPLUNK_URL` | Splunk HEC base URL, e.g. `https://localhost:8088` or `https://your-host:8088` |
135
+ | `CHRON_SPLUNK_TOKEN` | HEC ingest token |
136
+ | `CHRON_SPLUNK_INSECURE` | Set to `1` to skip TLS certificate verification (local Docker with self-signed cert) |
137
+
138
+ `CHRON_SPLUNK_URL` and `CHRON_SPLUNK_TOKEN` must both be set for events to flow. If unset, the integration is silently disabled.
@@ -0,0 +1,3 @@
1
+ sourcetype="chron:event" event_type="session_started" earliest=-30d
2
+ | stats count AS Sessions BY ai_tool
3
+ | sort -Sessions
@@ -0,0 +1,2 @@
1
+ sourcetype="chron:event" event_type="session_started" earliest=-30d
2
+ | timechart span=1d dc(host) AS ActiveDevelopers
@@ -0,0 +1,2 @@
1
+ | tstats count WHERE index=* sourcetype="chron:event" BY event_type _time span=1d
2
+ | timechart span=1d count BY event_type
@@ -0,0 +1,3 @@
1
+ sourcetype="chron:event" event_type="secret_detected" earliest=-1h
2
+ | where detection_type IN ("api_key","aws_key","gcp_key","azure_key","private_key","jwt")
3
+ | table _time, host, ai_tool, detection_type, masked_value, session_id_prefix
@@ -0,0 +1,4 @@
1
+ sourcetype="chron:event" event_type="secret_detected" earliest=-30d
2
+ | where detection_type IN ("api_key","aws_key","gcp_key","azure_key","private_key","jwt")
3
+ | table _time, host, ai_tool, detection_type, masked_value, session_id_prefix
4
+ | sort -_time
@@ -0,0 +1,3 @@
1
+ sourcetype="chron:event" event_type="session_started" earliest=-30d
2
+ | stats count AS Sessions BY host, ai_tool
3
+ | sort -Sessions
package/dist/cli/index.js CHANGED
@@ -17031,7 +17031,7 @@ var require_package = __commonJS({
17031
17031
  "package.json"(exports2, module2) {
17032
17032
  module2.exports = {
17033
17033
  name: "chron-mcp",
17034
- version: "0.1.14",
17034
+ version: "0.1.17",
17035
17035
  mcpName: "io.github.sirinivask/chron",
17036
17036
  description: "Audit-grade timestamped logs for every AI conversation",
17037
17037
  repository: {
@@ -17122,6 +17122,24 @@ function saveConfig(data) {
17122
17122
  (0, import_fs2.mkdirSync)(dir, { recursive: true });
17123
17123
  (0, import_fs2.writeFileSync)(configPath(), JSON.stringify(data, null, 2), "utf8");
17124
17124
  }
17125
+ function patchClaudeJson(vars) {
17126
+ const path = (0, import_path3.join)((0, import_os3.homedir)(), ".claude.json");
17127
+ if (!(0, import_fs2.existsSync)(path))
17128
+ return false;
17129
+ try {
17130
+ const raw = (0, import_fs2.readFileSync)(path, "utf8");
17131
+ const doc = JSON.parse(raw);
17132
+ const servers = doc.mcpServers ?? {};
17133
+ const chron = servers.chron ?? {};
17134
+ chron.env = { ...chron.env ?? {}, ...vars };
17135
+ servers.chron = chron;
17136
+ doc.mcpServers = servers;
17137
+ (0, import_fs2.writeFileSync)(path, JSON.stringify(doc, null, 2), "utf8");
17138
+ return true;
17139
+ } catch {
17140
+ return false;
17141
+ }
17142
+ }
17125
17143
  async function connectCrowdStrike() {
17126
17144
  process.stdout.write(`
17127
17145
  ${BOLD5}Connect Chron \u2192 CrowdStrike LogScale${RESET5}
@@ -17230,6 +17248,276 @@ ${DIM4}Sending test event...${RESET5} `);
17230
17248
  `);
17231
17249
  process.stdout.write(`${DIM4}Connection saved to ~/.chron/config.json${RESET5}
17232
17250
 
17251
+ `);
17252
+ }
17253
+ function isLocalhost(url) {
17254
+ return url.includes("localhost") || url.includes("127.0.0.1") || url.includes("::1");
17255
+ }
17256
+ async function connectSplunk() {
17257
+ process.stdout.write(`
17258
+ ${BOLD5}Connect Chron \u2192 Splunk${RESET5}
17259
+
17260
+ `);
17261
+ process.stdout.write(`${DIM4}Chron will send session telemetry to your Splunk instance via HTTP Event
17262
+ `);
17263
+ process.stdout.write(`Collector (HEC). Message content is never transmitted.${RESET5}
17264
+
17265
+ `);
17266
+ process.stdout.write(`${DIM4}Works with Splunk Enterprise, Splunk Cloud, and local Docker instances.
17267
+ `);
17268
+ process.stdout.write(`See dashboards/splunk/README.md for setup steps.${RESET5}
17269
+
17270
+ `);
17271
+ process.stdout.write(`${DIM4}Note: Splunk 9.x Docker uses HTTPS on port 8088 with a self-signed cert.
17272
+ `);
17273
+ process.stdout.write(`Use https://localhost:8088 \u2014 certificate verification is skipped for localhost.${RESET5}
17274
+
17275
+ `);
17276
+ const rl = (0, import_readline.createInterface)({ input: process.stdin, output: process.stdout });
17277
+ let url, token;
17278
+ try {
17279
+ url = (await prompt(rl, ` Splunk HEC base URL ${DIM4}(e.g. https://localhost:8088 or https://your.splunkcloud.com:8088)${RESET5}
17280
+ ${CYAN4}>${RESET5} `)).trim();
17281
+ token = (await prompt(rl, `
17282
+ HEC token
17283
+ ${CYAN4}>${RESET5} `)).trim();
17284
+ } finally {
17285
+ rl.close();
17286
+ }
17287
+ if (!url.startsWith("http")) {
17288
+ process.stdout.write(`
17289
+ ${RED}URL must start with http:// or https://${RESET5}
17290
+ `);
17291
+ process.exit(1);
17292
+ }
17293
+ if (!token) {
17294
+ process.stdout.write(`
17295
+ ${RED}HEC token cannot be empty${RESET5}
17296
+ `);
17297
+ process.exit(1);
17298
+ }
17299
+ if (isLocalhost(url)) {
17300
+ process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
17301
+ }
17302
+ process.stdout.write(`
17303
+ ${DIM4}Sending test event...${RESET5} `);
17304
+ const hecUrl = `${url.replace(/\/$/, "")}/services/collector/event`;
17305
+ const testPayload = JSON.stringify({
17306
+ time: Date.now() / 1e3,
17307
+ host: require("os").hostname(),
17308
+ source: "chron-mcp",
17309
+ sourcetype: "chron:event",
17310
+ event: {
17311
+ event_type: "connection_test",
17312
+ chron_version: require_package().version,
17313
+ os: process.platform,
17314
+ message: "chron connect splunk \u2014 test event"
17315
+ }
17316
+ });
17317
+ try {
17318
+ const res = await fetch(hecUrl, {
17319
+ method: "POST",
17320
+ headers: {
17321
+ "Authorization": `Splunk ${token}`,
17322
+ "Content-Type": "application/json"
17323
+ },
17324
+ body: testPayload
17325
+ });
17326
+ if (!res.ok) {
17327
+ const err = await res.text();
17328
+ process.stdout.write(`${RED}failed (HTTP ${res.status})${RESET5}
17329
+ `);
17330
+ process.stderr.write(` ${RED}${err}${RESET5}
17331
+
17332
+ `);
17333
+ process.exit(1);
17334
+ }
17335
+ process.stdout.write(`${GREEN}OK${RESET5}
17336
+
17337
+ `);
17338
+ } catch (e) {
17339
+ process.stdout.write(`${RED}failed${RESET5}
17340
+ `);
17341
+ process.stderr.write(` ${RED}Error: ${e.message}${RESET5}
17342
+
17343
+ `);
17344
+ process.exit(1);
17345
+ }
17346
+ const config = loadConfig();
17347
+ config.splunk = { url, token, insecure: isLocalhost(url), connected_at: (/* @__PURE__ */ new Date()).toISOString() };
17348
+ saveConfig(config);
17349
+ const splunkVars = { CHRON_SPLUNK_URL: url, CHRON_SPLUNK_TOKEN: token };
17350
+ if (isLocalhost(url))
17351
+ splunkVars.CHRON_SPLUNK_INSECURE = "1";
17352
+ patchClaudeJson(splunkVars);
17353
+ process.stdout.write(`${GREEN}${BOLD5}Connected!${RESET5} Splunk is receiving chron events.
17354
+
17355
+ `);
17356
+ process.stdout.write(`${DIM4}Config saved to ~/.chron/config.json \u2014 events will flow immediately in all running sessions.${RESET5}
17357
+
17358
+ `);
17359
+ }
17360
+ async function connectSentinel() {
17361
+ process.stdout.write(`
17362
+ ${BOLD5}Connect Chron \u2192 Microsoft Sentinel${RESET5}
17363
+
17364
+ `);
17365
+ process.stdout.write(`${DIM4}Chron will send session telemetry to your Sentinel workspace via the
17366
+ `);
17367
+ process.stdout.write(`Azure Monitor Logs Ingestion API. Message content is never transmitted.${RESET5}
17368
+
17369
+ `);
17370
+ process.stdout.write(`${DIM4}Prerequisites: Azure App Registration, Data Collection Endpoint (DCE),
17371
+ `);
17372
+ process.stdout.write(`and a Data Collection Rule (DCR) pointing to a ChronEvents_CL custom table.
17373
+ `);
17374
+ process.stdout.write(`See dashboards/sentinel/README.md for full setup steps.${RESET5}
17375
+
17376
+ `);
17377
+ const rl = (0, import_readline.createInterface)({ input: process.stdin, output: process.stdout });
17378
+ let tenantId, clientId, clientSecret, dce, dcrId, stream;
17379
+ try {
17380
+ tenantId = (await prompt(rl, ` Azure Tenant ID ${DIM4}(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)${RESET5}
17381
+ ${CYAN4}>${RESET5} `)).trim();
17382
+ clientId = (await prompt(rl, `
17383
+ App Registration Client ID
17384
+ ${CYAN4}>${RESET5} `)).trim();
17385
+ clientSecret = (await prompt(rl, `
17386
+ Client Secret
17387
+ ${CYAN4}>${RESET5} `)).trim();
17388
+ dce = (await prompt(rl, `
17389
+ Data Collection Endpoint URL ${DIM4}(https://...)${RESET5}
17390
+ ${CYAN4}>${RESET5} `)).trim();
17391
+ dcrId = (await prompt(rl, `
17392
+ DCR Immutable ID ${DIM4}(dcr-xxxx)${RESET5}
17393
+ ${CYAN4}>${RESET5} `)).trim();
17394
+ stream = (await prompt(rl, `
17395
+ Stream name ${DIM4}(press Enter for Custom-ChronEvents_CL)${RESET5}
17396
+ ${CYAN4}>${RESET5} `)).trim() || "Custom-ChronEvents_CL";
17397
+ } finally {
17398
+ rl.close();
17399
+ }
17400
+ if (!tenantId || !clientId || !clientSecret) {
17401
+ process.stdout.write(`
17402
+ ${RED}Tenant ID, Client ID, and Client Secret are all required.${RESET5}
17403
+ `);
17404
+ process.exit(1);
17405
+ }
17406
+ if (!dce.startsWith("https://")) {
17407
+ process.stdout.write(`
17408
+ ${RED}DCE URL must start with https://${RESET5}
17409
+ `);
17410
+ process.exit(1);
17411
+ }
17412
+ if (dcrId && !dcrId.startsWith("dcr-")) {
17413
+ process.stdout.write(`
17414
+ ${YELLOW3}Warning: DCR Immutable ID usually starts with "dcr-"${RESET5}
17415
+ `);
17416
+ }
17417
+ process.stdout.write(`
17418
+ ${DIM4}Authenticating with Azure AD...${RESET5} `);
17419
+ let accessToken;
17420
+ try {
17421
+ const tokenRes = await fetch(`https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`, {
17422
+ method: "POST",
17423
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
17424
+ body: new URLSearchParams({
17425
+ grant_type: "client_credentials",
17426
+ client_id: clientId,
17427
+ client_secret: clientSecret,
17428
+ scope: "https://monitor.azure.com/.default"
17429
+ }).toString()
17430
+ });
17431
+ if (!tokenRes.ok) {
17432
+ const err = await tokenRes.text();
17433
+ process.stdout.write(`${RED}failed (HTTP ${tokenRes.status})${RESET5}
17434
+ `);
17435
+ process.stderr.write(` ${RED}${err}${RESET5}
17436
+
17437
+ `);
17438
+ process.exit(1);
17439
+ }
17440
+ const tokenData = await tokenRes.json();
17441
+ accessToken = tokenData.access_token;
17442
+ process.stdout.write(`${GREEN}OK${RESET5}
17443
+ `);
17444
+ } catch (e) {
17445
+ process.stdout.write(`${RED}failed${RESET5}
17446
+ `);
17447
+ process.stderr.write(` ${RED}Error: ${e.message}${RESET5}
17448
+
17449
+ `);
17450
+ process.exit(1);
17451
+ }
17452
+ process.stdout.write(`${DIM4}Sending test event...${RESET5} `);
17453
+ const ingestUrl = `${dce}/dataCollectionRules/${dcrId}/streams/${stream}?api-version=2023-01-01`;
17454
+ const testRecord = {
17455
+ TimeGenerated: (/* @__PURE__ */ new Date()).toISOString(),
17456
+ EventType: "connection_test",
17457
+ SessionIdPrefix: "test",
17458
+ AiTool: "",
17459
+ OS: process.platform,
17460
+ ChronVersion: require_package().version,
17461
+ Computer: require("os").hostname(),
17462
+ Role: "",
17463
+ DetectionType: "",
17464
+ MaskedValue: ""
17465
+ };
17466
+ try {
17467
+ const res = await fetch(ingestUrl, {
17468
+ method: "POST",
17469
+ headers: {
17470
+ "Authorization": `Bearer ${accessToken}`,
17471
+ "Content-Type": "application/json"
17472
+ },
17473
+ body: JSON.stringify([testRecord])
17474
+ });
17475
+ if (!res.ok) {
17476
+ const err = await res.text();
17477
+ process.stdout.write(`${RED}failed (HTTP ${res.status})${RESET5}
17478
+ `);
17479
+ process.stderr.write(` ${RED}${err}${RESET5}
17480
+
17481
+ `);
17482
+ process.exit(1);
17483
+ }
17484
+ process.stdout.write(`${GREEN}OK${RESET5}
17485
+
17486
+ `);
17487
+ } catch (e) {
17488
+ process.stdout.write(`${RED}failed${RESET5}
17489
+ `);
17490
+ process.stderr.write(` ${RED}Error: ${e.message}${RESET5}
17491
+
17492
+ `);
17493
+ process.exit(1);
17494
+ }
17495
+ const config = loadConfig();
17496
+ config.sentinel = { dce, dcrId, stream, tenantId, clientId, connected_at: (/* @__PURE__ */ new Date()).toISOString() };
17497
+ saveConfig(config);
17498
+ process.stdout.write(`${GREEN}${BOLD5}Connected!${RESET5} Test event sent to Sentinel workspace.
17499
+
17500
+ `);
17501
+ process.stdout.write(`${BOLD5}Add these env vars to your MCP client config:${RESET5}
17502
+
17503
+ `);
17504
+ process.stdout.write(` ${CYAN4}CHRON_SENTINEL_TENANT_ID${RESET5} ${tenantId}
17505
+ `);
17506
+ process.stdout.write(` ${CYAN4}CHRON_SENTINEL_CLIENT_ID${RESET5} ${clientId}
17507
+ `);
17508
+ process.stdout.write(` ${CYAN4}CHRON_SENTINEL_CLIENT_SECRET${RESET5} ${DIM4}<your-client-secret>${RESET5}
17509
+ `);
17510
+ process.stdout.write(` ${CYAN4}CHRON_SENTINEL_DCE${RESET5} ${dce}
17511
+ `);
17512
+ process.stdout.write(` ${CYAN4}CHRON_SENTINEL_DCR_ID${RESET5} ${dcrId}
17513
+ `);
17514
+ process.stdout.write(` ${CYAN4}CHRON_SENTINEL_STREAM${RESET5} ${stream}
17515
+
17516
+ `);
17517
+ process.stdout.write(`${DIM4}For Claude Code \u2014 add to the "env" block of the chron entry in ~/.claude.json.
17518
+ `);
17519
+ process.stdout.write(`Connection saved to ~/.chron/config.json${RESET5}
17520
+
17233
17521
  `);
17234
17522
  }
17235
17523
  async function runConnect(args2) {
@@ -17238,6 +17526,12 @@ async function runConnect(args2) {
17238
17526
  case "crowdstrike":
17239
17527
  await connectCrowdStrike();
17240
17528
  break;
17529
+ case "sentinel":
17530
+ await connectSentinel();
17531
+ break;
17532
+ case "splunk":
17533
+ await connectSplunk();
17534
+ break;
17241
17535
  default: {
17242
17536
  const name = subcommand ? `Unknown integration: ${subcommand}
17243
17537
 
@@ -17247,13 +17541,15 @@ async function runConnect(args2) {
17247
17541
 
17248
17542
  Integrations:
17249
17543
  crowdstrike Connect to CrowdStrike LogScale (direct ingest)
17544
+ sentinel Connect to Microsoft Sentinel (Azure Monitor Logs Ingestion API)
17545
+ splunk Connect to Splunk via HTTP Event Collector (HEC)
17250
17546
  `
17251
17547
  );
17252
17548
  process.exit(subcommand ? 1 : 0);
17253
17549
  }
17254
17550
  }
17255
17551
  }
17256
- var import_readline, import_os3, import_path3, import_fs2, RESET5, BOLD5, DIM4, CYAN4, GREEN, RED;
17552
+ var import_readline, import_os3, import_path3, import_fs2, RESET5, BOLD5, DIM4, CYAN4, GREEN, RED, YELLOW3;
17257
17553
  var init_connect = __esm({
17258
17554
  "src/cli/connect.ts"() {
17259
17555
  "use strict";
@@ -17267,6 +17563,7 @@ var init_connect = __esm({
17267
17563
  CYAN4 = "\x1B[36m";
17268
17564
  GREEN = "\x1B[32m";
17269
17565
  RED = "\x1B[31m";
17566
+ YELLOW3 = "\x1B[33m";
17270
17567
  }
17271
17568
  });
17272
17569
 
@@ -17317,7 +17614,7 @@ Commands:
17317
17614
  export Export a session as markdown
17318
17615
  secrets List detected secrets across sessions
17319
17616
  settings View current configuration
17320
- connect Connect to a SIEM integration (crowdstrike)
17617
+ connect Connect to a SIEM integration (crowdstrike, sentinel, splunk)
17321
17618
 
17322
17619
  Options (history):
17323
17620
  --limit=<n> Max sessions to show (default: 20)