nano SIEM
Agents & MCPInvestigator

Investigate alerts

Run a structured investigation with the investigate_alert prompt, pivot on entities, and record findings in notebooks

Investigate alerts

Once an alert is worth more than a glance, the investigate_alert prompt drives a structured workflow: read the alert, pull the detection's intent, enrich the entities, look for related activity, and land on a recommendation. This page covers that prompt, the entity pivots it uses, and where the findings go.

This page assumes you've read Triage & cases, since an investigation usually ends in a case.

The investigate_alert prompt

investigate_alert takes alert_id (required) and depth (optional: quick, standard, or deep). It runs a fixed chain:

  1. get_alert for the matched events and ai_triage_hints
  2. get_detection to read the rule's intent and its ignore_when / suspicious_when lists
  3. Assess false-positive versus true-positive against those hints
  4. Enrich the entities with get_entity_context, lookup_ip, and get_prevalence (IOC hits surface on the ioc_* columns in search results)
  5. Run one or two search queries for related activity
  6. get_related_cases to check for prior history
  7. Recommend: false positive, needs more investigation, or true positive
> investigate alert 456

Running investigate_alert (alert_id=456, depth=standard)...

get_alert(456): rule "DNS tunneling — high entropy subdomains",
  severity high, entity ip 10.5.2.40, 47 matched DNS events.
get_detection: ai_triage_hints.suspicious_when =
  ["query volume to a single domain > 200/hr",
   "subdomain entropy > 4.0"]. ignore_when =
  ["domain is a known CDN or telemetry endpoint"].

Assessment: matched events show 612 queries/hr to
*.dataxfil-c2.example.com, entropy 4.7. Not a known CDN.
Leaning true positive.

Enriching 10.5.2.40 (get_entity_context):
  GeoIP: internal RFC1918, asset = VPN-issued laptop (jdoe)
  IOC:   no threat-intel hits on the IP itself
  Risk timeline: score climbed 22 → 74 over 6 hours
search dataxfil-c2.example.com | where ioc_matched=true:
  ThreatFox match, ioc_threat_type "generic_exfil", ioc_confidence 75.
get_prevalence(domain, dataxfil-c2.example.com):
  seen on 1 host, first seen 6h ago, is_rare = true.

Related activity search returned 2 hits on the same host.
get_related_cases: 1 similar case (DNS exfil, different host,
  closed true_positive 3 weeks ago).

Recommendation: TRUE POSITIVE. Rare C2-like domain, threat-intel
match, single host, risk climbing. Suggest a case and a host
isolation action. Want me to open one?

Resuming an investigation

When you come back to a case that already has an investigation in it, start with review_case rather than re-reading the pieces by hand. It is a composite read: it returns the case, its wall, and every linked notebook with entries and references, batched so you get the whole context in one call. Treat it as the resume-an-investigation entry point.

> pick up case C-204

Calling review_case (id=C-204)...

Case C-204 — Credential dumping on WIN-FS01 (critical, in_progress)
Wall (4 entries): last status "confirmed lateral move to WIN-FS02"
Notebooks (1): "WIN-FS01 credential dumping" — 9 entries
  (timeline, 2 ioc_markers, 3 search_executed, ai_summary)

You left off pivoting from WIN-FS01 to WIN-FS02. Continue there?

Pivoting on entities

The investigation widens by pivoting from one entity to its context:

  • get_entity_context is a composite pivot. Given entity_type (ip/user/host/domain/hash) and value, it runs GeoIP (for IPs) and the risk timeline in parallel and returns them together. This is the usual first pivot.
  • lookup_ip returns GeoIP and ASN for one ip.
  • IOC matches are applied at ingest into the ioc_matched / ioc_threat_type / ioc_confidence columns — surface them by filtering search results (e.g. ... | where ioc_matched=true), not a dedicated lookup.
  • get_prevalence answers how common an artifact is (host count, occurrences, first and last seen, is_rare). It accepts type of hash or domain only. Passing an IP errors; use the rare/new artifact tools for IPs instead.
> what do we know about the domain dataxfil-c2.example.com?

Calling get_entity_context (entity_type=domain,
  value=dataxfil-c2.example.com)...
  IOC:  ThreatFox hit, family generic_exfil
  Risk: associated with 1 entity (10.5.2.40), trending up

Calling get_prevalence (type=domain,
  value=dataxfil-c2.example.com)...
  host_count=1, occurrences=47, first_seen=6h ago, is_rare=true

Recording findings: the case wall vs notebooks

Two surfaces hold investigation output, and they have different jobs.

The case wall holds short status. Use add_case_wall_entry for a one-or-two-line update an analyst can scan: "confirmed C2 beacon, isolating host." Keep the wall readable.

Notebooks hold the detailed analysis: the queries you ran, the entities you touched, the timeline you built. Create one per investigation with create_notebook (param: title; optional visibility of private/shared/public), then append structured entries.

add_notebook_entry takes notebook_id, entry_type, and content (an object). The entry_type is one of a fixed set, each expecting its own JSON content shape:

  • manual_note
  • search_executed
  • ai_suggestion
  • ai_summary
  • entity_reference
  • ioc_marker
  • timeline_marker
  • investigation_timeline

add_notebook_reference links a notebook to an alert, detection, saved_search, or case so the two stay connected.

> log this investigation. case C-204, build me a notebook.

Calling create_notebook (title="DNS exfil from 10.5.2.40",
  visibility="shared")...  → notebook NB-77

Calling add_notebook_entry (NB-77, entry_type="ioc_marker",
  content={value:"dataxfil-c2.example.com", type:"domain",
  source:"ThreatFox", family:"generic_exfil"})...
Calling add_notebook_entry (NB-77, entry_type="search_executed",
  content={query:"...", hits:47, window:"-24h"})...
Calling add_notebook_entry (NB-77, entry_type="ai_summary",
  content={text:"Rare C2-like domain, single host, risk 74..."})...

Calling add_notebook_reference (NB-77, reference_type="case",
  reference_id="C-204")...
Calling add_notebook_reference (NB-77, reference_type="alert",
  reference_id="456")...

Calling add_case_wall_entry (C-204, entry_type="ai_analysis",
  content="DNS exfil confirmed to dataxfil-c2.example.com
  (ThreatFox, rare). Detail in notebook NB-77.")...

Notebook NB-77 created and linked. Wall updated with a short
status pointing at it.

get_related_cases (param: id) returns cases that share entities, rules, or MITRE techniques with the current one. Use it to find out whether the same host, user, or domain has been investigated before, which often changes the disposition.

find_notebooks_by_reference goes the other direction: given a reference_type (alert/detection/saved_search/case) and reference_id, it finds notebooks that already reference that object, so you do not redo analysis someone else already wrote up.

What's next

  • Hunt: go looking before an alert fires, with search_sql, prevalence, and MITRE coverage
  • Triage & cases: the case model and the start-of-shift briefing
  • Detection-as-Code: turn a confirmed pattern into a scheduled detection
On this page

On this page