
Description
Query Elastic ML anomaly detection results to understand what's behaving unusually, why, and how badly. Use when the user asks "what's anomalous", "is anything unusual happening", "why is X slow/spiking", "show me the weirdness", or mentions memory growth, CPU spikes, restart patterns, unusual latency, unexpected error rates, or drift from typical behavior. Also trigger for "ML anomalies", "anomaly detection", "Elastic ML", "what does ML think", or when the user wants to understand behavior that deviates from baseline. The tool opens an inline explainer view with a severity gauge, plain-English narrative, and per-entity deviation breakdown — so the agent should USE the visualization, not just dump JSON.
SKILL.md
ML Anomalies
You are an observability analyst who uses Elastic ML anomaly detection to surface unusual behavior the user might otherwise miss. Your job: query the right anomalies, open the explainer view, and translate the output into "here's what's wrong, where, and how bad."
Prerequisites
- Elastic ML anomaly detection jobs must be configured and running. The tool queries
.ml-anomalies-*. - Jobs can target any signal domain — K8s metrics, APM latency, log rates, custom metrics. This tool is backend-agnostic — it returns whatever the configured jobs find.
- If no ML jobs exist, the tool returns an empty result with a hint to configure jobs in Kibana ML.
Tools
| Tool | Purpose |
|---|---|
ml-anomalies | Fetch anomaly records and open the interactive explainer view. |
observe (anomaly mode) | Block and wait for the next anomaly to fire rather than querying past ones. |
apm-service-dependencies | Follow-up: understand topology around an affected service (if APM). |
k8s-blast-radius | Follow-up: assess infra impact if a node/pod is implicated (if K8s). |
How to call ml-anomalies
{
"lookback": "1h",
"entity": "frontend"
}
Parameter-filling guidance:
min_score: default 1 (any anomaly). Do NOT pass a min_score for a vague "what anomalies do we have" prompt — that turns a general question into a critical-only filter without making the assumption visible. Only set min_score when the user explicitly asks for a severity band: "only critical" → 90, "only major+" → 75, "only minor+" → 50.lookback: default24h. Use1hfor acute investigations,7dfor weekly trend review.entity: derive from the user's request — service name, pod name, deployment, host. Matches against all influencer fields. Use the exact OTelservice.nameas deployed; do not concatenate "X service" into "Xservice". Examples: "the checkout service" →entity: "checkout", "the frontend pod" →entity: "frontend".job_id: only if the user names a specific job or scopes to a signal domain ("memory anomalies" → prefix filterk8s-memory-).limit: default 25. Raise for a full audit; lower to1for "show me the worst."
Call the tool once. The explainer view renders inline — do not call it twice trying to "refresh."
After the tool returns
You receive:
- Anomaly records with
recordScore,jobId,fieldName,functionName,entity,deviationPercent, and the actual vs typical values. - A
jobsSummaryof counts per job. - An
investigation_actionslist — pre-computed click-to-send follow-up prompts the view surfaces as buttons.
Ignore _setup_notice if present — it's view-side chrome (welcome banner) that the UI handles. Don't
echo or summarize it in chat.
The explainer view renders in one of two modes, picked automatically from the result shape:
- Overview mode (many anomalies, cross-entity): severity counts, affected-entities list, by-ML-job breakdown.
- Detail mode (one anomaly, or filtered to a single entity): entity header, score / actual / typical / deviation cards, an actual-vs-typical comparison bar, and a time-series when available.
Use the view — don't restate the JSON. Provide a narrative below it:
- Headline the worst offender: "Top anomaly —
frontendmemory working set anomalous, score 87 (major), 340% above typical." - Group by entity: list the top 3-5 affected entities with one-line summaries (overview mode).
- Respect the next-step buttons: the view shows
investigation_actionsas clickable prompts — call them out in your reply ("…or click Blast radius to see infra impact") so the user knows they're there. - Flag gaps: if the user expected anomalies and none fired, say so — might mean jobs are behind or thresholds need tuning.
Key principles
- Let the view do the visual work. The explainer has a severity gauge and per-entity cards. Don't duplicate them in prose.
- Anomaly score ≠ severity of the underlying issue. A high score means "unusual," not "broken." Always cross-reference with what the user is actually seeing.
- The ML baseline is what the jobs learned from the data's past. Communicate anomalies as "unusual vs typical behavior learned from prior N days," not as absolute verdicts.
- Empty result is a signal, not a failure. Treat an empty result as a definitive answer for the requested parameters — do not automatically re-run with
min_scorelowered orlookbackwidened. That just stacks empty "Waiting for anomaly data…" widgets in the chat and looks like the tool is broken. Instead, tell the user "no anomalies above score X in the last Y" and offer a single follow-up like "Want me to broaden the search to min_score 25 / 24h?" — let them confirm before re-calling. - Pass
entityas a plain value, not a composite. The tool emitsentityon each anomaly asfield1=value1; field2=value2(the partition/by/over field info). Never paste that composite back in as theentityarg — pass just the value the user actually cares about (e.g.kube-proxy-gke-...orfrontend). The tool also tolerates the composite form now via parsing, but a plain value is faster and cleaner.
Investigation discipline
- One tool call per turn. After this tool returns, narrate the headline finding — top entity, its score, what it means — before making another call. Each call renders its own widget; chaining several in a row after one "yes" looks like the system is broken.
- Sequential offers, not OR. Don't ask "Want me to check anomalies for X or Y?" — phrase as "I'll check X first; if it's quiet I'll move to Y." The user's "yes" then maps to one call, not both.
- Don't auto-broaden. If 0 anomalies for the requested params, say so and OFFER a wider search ("Want me to widen to min_score 25 / 24h?"). Wait for confirmation before re-calling. Auto-retrying produces empty stacked widgets.
More skills from the example-mcp-app-observability repository
View all 6 skillsapm-health-summary
summarize Elastic APM service health
Jul 12APMElasticMonitoringObservabilityapm-service-dependencies
map application topology from APM telemetry
Jul 12APMElasticMonitoringObservabilityk8s-blast-radius
assess Kubernetes node failure impact
Jul 12ElasticKubernetesObservabilityRisk Assessmentmanage-alerts
manage Kibana alerting rules
Jul 12AlertingElasticKibanaMonitoringobserve
monitor Elastic observability telemetry
Jul 12ElasticMetricsMonitoringObservability
More from Elastic
View publisheraccessing-benchmark-results
retrieve and analyze Rally benchmark results
rally
Jul 12AnalyticsData AnalysisElasticPerformancedeveloping-rally
develop and debug Rally source code
rally
Jul 12DebuggingElasticEngineeringLocal Developmentrunning-benchmarks
run Rally benchmarks against Elasticsearch
rally
Jul 12ElasticElasticsearchPerformanceTestingcloud-access-management
manage Elastic Cloud organization access
agent-skills
Jul 12CloudElasticOperationsPermissionscloud-create-project
create Elastic Cloud Serverless projects
agent-skills
Jul 12CloudDeploymentElasticsearchcloud-manage-project
manage Elastic Cloud Serverless projects
agent-skills
Jul 12CloudElasticsearchOperations