nano SIEM
Agents & MCPInvestigator

Triage & cases

Start a shift, read the alert queue, and turn alerts into cases with the nano-investigator MCP server

Triage & cases

nano-investigator is an MCP server that exposes the SIEM's alerts, cases, notebooks, search, risk, and enrichment surfaces as agent-callable tools. It runs alongside nanodac and shares the same three environment variables. Where nanodac authors detections and writes rules to the SIEM, nano-investigator runs SOC operations and is mostly read-only.

This page covers the start of a shift: getting a briefing, reading the alert queue, and the one model you have to internalize before you do anything else.

Start of shift: the morning briefing

The fastest way to start is the morning_briefing prompt. It takes one optional argument, hours (default 12), and chains a fixed set of read-only tools into a shift-handoff summary:

  1. get_alert_counts plus list_alerts filtered to critical and high severity
  2. get_case_stats for open/in-progress case load and average resolution time
  3. get_risky_entities for the top 10 entities by risk
  4. list_detections to flag rules that are noisy or have gone silent
  5. health_check to confirm ClickHouse and PostgreSQL are reachable

It returns a prioritized list of what needs attention, not just raw counts.

> morning briefing for the last 8 hours

Running morning_briefing (hours=8)...

Alerts (last 8h):  4 critical, 11 high, 38 medium  (get_alert_counts)
  CRIT  #1182  Impossible travel — user jdoe          (new)
  CRIT  #1180  Credential dumping — host WIN-FS01      (new)
  HIGH  #1175  DNS tunneling — 10.5.2.40               (new)
  ...
Cases:  6 open, 2 in progress, avg resolution 5.2h   (get_case_stats)
Top risk:  WIN-FS01 (88), jdoe (81), 10.5.2.40 (74)  (get_risky_entities)
Detections:  rule "Okta MFA fatigue" silent 36h; rule
  "Sysmon proc anomaly" fired 1.4k times (likely noisy)
Health:  ClickHouse OK, PostgreSQL OK

Suggested order of work:
  1. Triage CRIT #1180 (credential dumping) — touches top-risk host
  2. Triage CRIT #1182 (impossible travel) — same user as 3 medium alerts
  3. Look at "Sysmon proc anomaly" noise before it buries the queue

Reading the alert queue

Once you know where to look, the three alert tools are all read-only:

  • list_alerts lists with filters. All params are optional: status (new/acknowledged/closed), severity, rule_id, assigned_to, limit (default 50), offset.
  • get_alert returns the full detail for one alert by id, including the matched events and ai_triage_hints carried over from the detection that fired it.
  • get_alert_counts returns counts grouped by severity and status.
> show me the new critical alerts

Calling list_alerts (status=new, severity=critical)...

  #1182  Impossible travel — user jdoe         2026-05-31 06:12
  #1180  Credential dumping — host WIN-FS01    2026-05-31 05:48

> open 1180

Calling get_alert (id=1180)...

Rule:      Credential dumping via LSASS access
Severity:  critical
Entities:  host WIN-FS01, process rundll32.exe, user SYSTEM
Matched:   3 events (Sysmon EventID 10, target lsass.exe)
ai_triage_hints:
  ignore_when:  ["access from known EDR agent process"]
  suspicious_when: ["source process is rundll32 or regsvr32",
                    "outside maintenance window"]

The ai_triage_hints block is the detection author's guidance: read the ignore_when and suspicious_when lists before you decide whether the alert is worth a case.

Checking the risk picture

Two tools give you the org-wide risk view so you can prioritize across the queue rather than top-down:

  • get_risky_entities returns the top entities by risk score. Optional params: window (24h/7d/all), entity_type, min_score, limit (default 20).
  • get_risk_overview returns entity counts by risk level for both the 24h and 7d windows.

An alert against a host that is already the top-risk entity for the week is a different priority than the same alert against a quiet host.

> who are the riskiest entities right now?

Calling get_risky_entities (window=24h, limit=20)...

  host  WIN-FS01      88   (3 alerts, lateral-movement signals)
  user  jdoe          81   (impossible travel + failed MFA)
  ip    10.5.2.40     74   (DNS tunneling)

Turning an alert into a case

This is the actual act of triage. There is no alert state to change, so you move the signal into a case and record what you decided.

Create or pick a case. Use create_case (params: title, severity required; optional description, priority, assigned_to, tags) for a new investigation, or list_cases / get_case to find an existing one to attach to.

Attach the alert. Call add_alert_to_case with case_id and alert_id. Set is_primary when the alert is the case's root signal. You can attach more than one alert to the same case.

Record your reasoning on the wall. Call add_case_wall_entry with case_id, entry_type (comment, ai_analysis, or action_taken), and content. This is the short, human-readable status. Detailed analysis belongs in a notebook (see Investigate alerts).

> alert 1180 looks real. open a case for it and assign to me.

Calling create_case (title="Credential dumping on WIN-FS01",
  severity="critical", assigned_to="me")...
  → case #C-204 created

Calling add_alert_to_case (case_id=C-204, alert_id=1180,
  is_primary=true)...
  → alert linked

Calling add_case_wall_entry (case_id=C-204, entry_type="comment",
  content="LSASS access from rundll32 on WIN-FS01, outside
  maintenance window. Matches suspicious_when. Investigating
  parent process and lateral movement.")...
  → wall updated

Case C-204 is open and assigned to you. Want me to start the
investigation? (investigate_alert on 1180)

Working an existing case

When you pick up a case that already has history, do not page through it piece by piece. Call review_case with the case id or case number. It is a composite read that pulls the case, its wall, and all linked notebooks (entries and references, fetched in batches) in one shot. Use it as the first call whenever you resume a case.

get_related_cases (param: id) surfaces historically similar cases by shared entities, rules, or MITRE techniques, which is how you find out the same host has been investigated before.

Other case tools

The remaining case tools cover status and ownership changes:

  • update_case edits title, description, severity, or tags.
  • change_case_status sets status (open/in_progress/pending/resolved/closed) and an optional disposition (true_positive/false_positive/benign/inconclusive).
  • assign_case reassigns to a user_id.
  • get_case_stats returns counts by status and severity plus average resolution time.

What's next

  • Investigate alerts: the investigate_alert prompt, entity pivots, and recording findings in notebooks
  • Hunt: proactive hunting with search_sql, prevalence, and MITRE coverage
  • Detection-as-Code: author and ship the detections that produce these alerts
On this page

On this page