[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-elastic-apm-service-dependencies":3,"mdc--f5pylf-key":33,"related-repo-elastic-apm-service-dependencies":916,"related-org-elastic-apm-service-dependencies":992},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":23,"repoUrl":24,"updatedAt":25,"license":26,"forks":27,"topics":28,"repo":29,"sourceUrl":31,"mdContent":32},"apm-service-dependencies","map application topology from APM telemetry","Map the application topology from APM telemetry — which services call which, over what protocols, with what call volume and latency. Use when the user asks \"what calls X\", \"what depends on X\", \"show me the topology\", \"what are the upstream\u002Fdownstream services\", \"where does this service fit\", or is doing root-cause investigation and needs to trace how a problem propagates through the call graph. Also trigger for \"service map\", \"dependency graph\", \"blast radius of service X\", or \"who's the dependency of Y\". Requires Elastic APM — do not trigger for log-only or metrics-only customers.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"elastic","Elastic","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Felastic.png",[12,16,19,22],{"name":13,"slug":14,"type":15},"Observability","observability","tag",{"name":17,"slug":18,"type":15},"Monitoring","monitoring",{"name":20,"slug":21,"type":15},"APM","apm",{"name":9,"slug":8,"type":15},10,"https:\u002F\u002Fgithub.com\u002Felastic\u002Fexample-mcp-app-observability","2026-07-12T07:49:23.167442",null,7,[],{"repoUrl":24,"stars":23,"forks":27,"topics":30,"description":26},[],"https:\u002F\u002Fgithub.com\u002Felastic\u002Fexample-mcp-app-observability\u002Ftree\u002FHEAD\u002Fskills\u002Fapm-service-dependencies","---\nname: apm-service-dependencies\ndescription: >\n  Map the application topology from APM telemetry — which services call which, over what protocols, with\n  what call volume and latency. Use when the user asks \"what calls X\", \"what depends on X\", \"show me\n  the topology\", \"what are the upstream\u002Fdownstream services\", \"where does this service fit\", or is doing\n  root-cause investigation and needs to trace how a problem propagates through the call graph. Also trigger\n  for \"service map\", \"dependency graph\", \"blast radius of service X\", or \"who's the dependency of Y\".\n  Requires Elastic APM — do not trigger for log-only or metrics-only customers.\n---\n\n# APM Service Dependencies\n\nThis tool answers \"how is my application wired together?\" It returns the APM dependency graph — a set of\ndirected edges from caller services to callee services, with protocol (http, grpc, dns, etc.), call volume,\nand per-service health (span count, latency, errors) when requested.\n\n## Prerequisites\n\n- **Elastic APM with OTel-instrumented services** producing `span.destination.service.resource` values.\n- Optional: Kubernetes metadata on the spans (for namespace filtering).\n\nIf the user is log-only or metrics-only (no APM), this tool won't work. Do not reach for it.\n\n## Tools\n\n| Tool | Purpose |\n|------|---------|\n| `apm-service-dependencies` | Fetch the dependency graph (full or focal). |\n| `apm-health-summary` | Prerequisite view: which services are degraded? Then map their neighborhood with this skill. |\n| `ml-anomalies` | Drill into anomalies affecting a service discovered in the graph. |\n| `k8s-blast-radius` | If a service is K8s-deployed and a node is implicated. |\n\n## How to call apm-service-dependencies\n\n### Focal mode (most common)\n\nUse when you know which service is the investigation target. Returns only that service's direct upstream\nand downstream neighbors — much easier to reason about than the full graph.\n\n```json\n{\n  \"service\": \"checkout\",\n  \"lookback\": \"1h\",\n  \"include_health\": true\n}\n```\n\n### Full-graph mode\n\nUse sparingly — only when the user explicitly wants the whole topology, or during initial environment\ndiscovery.\n\n```json\n{\n  \"lookback\": \"1h\",\n  \"include_health\": false\n}\n```\n\nParameter-filling guidance:\n\n- **`service`**: the exact OTel `service.name` as deployed — typically lowercase and hyphenated for\n  multi-word services (`frontend`, `checkout`, `product-catalog`). **Do not concatenate spaces** — if\n  the user says \"checkout service\" pass `checkout`, not `checkoutservice`. If the name is ambiguous,\n  ask the user to confirm before calling. If the tool returns no edges for the named focal service,\n  confirm the name with the user before fuzzy-matching.\n- **`namespace`**: only if the user scopes to a K8s namespace AND services are K8s-deployed.\n- **`lookback`**: **default `1h`** for any unqualified prompt. Don't drop to 15m unless the user explicitly says something time-localized (\"right now \u002F this second\"). Use `24h` to smooth transient topology changes; use the user's literal window when they give one (\"past 30 minutes\" → `30m`).\n- **`include_health`**: default true. Set false for a topology-only response when you don't need latency\u002Ferror\n  data.\n\n## After the tool returns\n\nResponse shape:\n- `services`: list of nodes with optional language\u002Fdeployment\u002Fnamespace metadata and health stats.\n- `edges`: directed edges with `source`, `target`, `protocol`, `port`, `call_count`, `avg_latency_us`.\n- `focal_service` + `upstream` + `downstream` (focal mode only).\n- `service_count` \u002F `edge_count`.\n- `data_coverage_note` (only on focal mode when the focal service has inbound but zero outbound\n  edges): flags a likely instrumentation gap — don't claim the service is a `leaf`; relay the note\n  to the user as an advisory.\n\nIgnore `_setup_notice` if present — it's view-side chrome (welcome banner) that the UI handles. Don't\necho or summarize it in chat.\n\nLead your narrative with:\n\n1. **Focal service**: \"checkoutservice has 3 upstream callers and 5 downstream dependencies.\"\n2. **Upstream callers** (who depends on this service): name them, note call volumes. Outage here cascades up.\n3. **Downstream dependencies** (what this service relies on): name them. Problems here cascade in.\n4. **Hot edges**: highest call volume or latency — likely the load-bearing paths.\n5. **Follow-ups**: suggest `ml-anomalies` on a specific neighbor if its health shows errors or elevated latency.\n\n## Key principles\n\n- **Prefer focal mode.** The full graph is hard to narrate; a focal subgraph is crisp.\n- **Direction matters.** Upstream = who calls me (blast radius goes up). Downstream = what I call (problems\n  cascade in). Don't mix them up in explanations.\n- **Protocols and ports are clues.** A DNS edge tells you the callee is resolved by name (k8s service?). A\n  high-port HTTP call to a specific target hints at a sidecar or proxy.\n- **Empty or tiny graphs are a signal.** If the focal service has zero edges, either the lookback is too\n  narrow, the service isn't instrumented, or the name is wrong. Do not silently report \"no dependencies.\"\n\n## Investigation discipline\n\n- **One tool call per turn.** After this tool returns, narrate what the topology shows — root, leaves, edges with abnormal latency or error rates — *before* firing another tool. Each call adds a widget to the chat; piling 3-4 in a row after a single \"yes\" looks like a runaway agent.\n- **Sequential offers, not OR.** Don't ask \"Want me to check pod health *or* ML anomalies?\" — phrase as a chain: \"Want me to start with X? If that doesn't explain it, I can follow up with Y.\" The user's \"yes\" then maps to one call, not several.\n- **Commit to a plan before \"yes.\"** When a follow-up needs multiple tools (e.g. flagd pod resources → flagd traces → upstream caller anomalies), lay out the chain first and execute one step at a time, narrating between each. Don't pre-fire the chain because the user agreed in principle.\n",{"data":34,"body":35},{"name":4,"description":6},{"type":36,"children":37},"root",[38,46,52,59,89,94,100,195,201,208,213,354,360,365,445,450,586,592,597,728,741,746,807,813,856,862,910],{"type":39,"tag":40,"props":41,"children":42},"element","h1",{"id":4},[43],{"type":44,"value":45},"text","APM Service Dependencies",{"type":39,"tag":47,"props":48,"children":49},"p",{},[50],{"type":44,"value":51},"This tool answers \"how is my application wired together?\" It returns the APM dependency graph — a set of\ndirected edges from caller services to callee services, with protocol (http, grpc, dns, etc.), call volume,\nand per-service health (span count, latency, errors) when requested.",{"type":39,"tag":53,"props":54,"children":56},"h2",{"id":55},"prerequisites",[57],{"type":44,"value":58},"Prerequisites",{"type":39,"tag":60,"props":61,"children":62},"ul",{},[63,84],{"type":39,"tag":64,"props":65,"children":66},"li",{},[67,73,75,82],{"type":39,"tag":68,"props":69,"children":70},"strong",{},[71],{"type":44,"value":72},"Elastic APM with OTel-instrumented services",{"type":44,"value":74}," producing ",{"type":39,"tag":76,"props":77,"children":79},"code",{"className":78},[],[80],{"type":44,"value":81},"span.destination.service.resource",{"type":44,"value":83}," values.",{"type":39,"tag":64,"props":85,"children":86},{},[87],{"type":44,"value":88},"Optional: Kubernetes metadata on the spans (for namespace filtering).",{"type":39,"tag":47,"props":90,"children":91},{},[92],{"type":44,"value":93},"If the user is log-only or metrics-only (no APM), this tool won't work. Do not reach for it.",{"type":39,"tag":53,"props":95,"children":97},{"id":96},"tools",[98],{"type":44,"value":99},"Tools",{"type":39,"tag":101,"props":102,"children":103},"table",{},[104,123],{"type":39,"tag":105,"props":106,"children":107},"thead",{},[108],{"type":39,"tag":109,"props":110,"children":111},"tr",{},[112,118],{"type":39,"tag":113,"props":114,"children":115},"th",{},[116],{"type":44,"value":117},"Tool",{"type":39,"tag":113,"props":119,"children":120},{},[121],{"type":44,"value":122},"Purpose",{"type":39,"tag":124,"props":125,"children":126},"tbody",{},[127,144,161,178],{"type":39,"tag":109,"props":128,"children":129},{},[130,139],{"type":39,"tag":131,"props":132,"children":133},"td",{},[134],{"type":39,"tag":76,"props":135,"children":137},{"className":136},[],[138],{"type":44,"value":4},{"type":39,"tag":131,"props":140,"children":141},{},[142],{"type":44,"value":143},"Fetch the dependency graph (full or focal).",{"type":39,"tag":109,"props":145,"children":146},{},[147,156],{"type":39,"tag":131,"props":148,"children":149},{},[150],{"type":39,"tag":76,"props":151,"children":153},{"className":152},[],[154],{"type":44,"value":155},"apm-health-summary",{"type":39,"tag":131,"props":157,"children":158},{},[159],{"type":44,"value":160},"Prerequisite view: which services are degraded? Then map their neighborhood with this skill.",{"type":39,"tag":109,"props":162,"children":163},{},[164,173],{"type":39,"tag":131,"props":165,"children":166},{},[167],{"type":39,"tag":76,"props":168,"children":170},{"className":169},[],[171],{"type":44,"value":172},"ml-anomalies",{"type":39,"tag":131,"props":174,"children":175},{},[176],{"type":44,"value":177},"Drill into anomalies affecting a service discovered in the graph.",{"type":39,"tag":109,"props":179,"children":180},{},[181,190],{"type":39,"tag":131,"props":182,"children":183},{},[184],{"type":39,"tag":76,"props":185,"children":187},{"className":186},[],[188],{"type":44,"value":189},"k8s-blast-radius",{"type":39,"tag":131,"props":191,"children":192},{},[193],{"type":44,"value":194},"If a service is K8s-deployed and a node is implicated.",{"type":39,"tag":53,"props":196,"children":198},{"id":197},"how-to-call-apm-service-dependencies",[199],{"type":44,"value":200},"How to call apm-service-dependencies",{"type":39,"tag":202,"props":203,"children":205},"h3",{"id":204},"focal-mode-most-common",[206],{"type":44,"value":207},"Focal mode (most common)",{"type":39,"tag":47,"props":209,"children":210},{},[211],{"type":44,"value":212},"Use when you know which service is the investigation target. Returns only that service's direct upstream\nand downstream neighbors — much easier to reason about than the full graph.",{"type":39,"tag":214,"props":215,"children":220},"pre",{"className":216,"code":217,"language":218,"meta":219,"style":219},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"service\": \"checkout\",\n  \"lookback\": \"1h\",\n  \"include_health\": true\n}\n","json","",[221],{"type":39,"tag":76,"props":222,"children":223},{"__ignoreMap":219},[224,236,281,319,345],{"type":39,"tag":225,"props":226,"children":229},"span",{"class":227,"line":228},"line",1,[230],{"type":39,"tag":225,"props":231,"children":233},{"style":232},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[234],{"type":44,"value":235},"{\n",{"type":39,"tag":225,"props":237,"children":239},{"class":227,"line":238},2,[240,245,251,256,261,266,272,276],{"type":39,"tag":225,"props":241,"children":242},{"style":232},[243],{"type":44,"value":244},"  \"",{"type":39,"tag":225,"props":246,"children":248},{"style":247},"--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA",[249],{"type":44,"value":250},"service",{"type":39,"tag":225,"props":252,"children":253},{"style":232},[254],{"type":44,"value":255},"\"",{"type":39,"tag":225,"props":257,"children":258},{"style":232},[259],{"type":44,"value":260},":",{"type":39,"tag":225,"props":262,"children":263},{"style":232},[264],{"type":44,"value":265}," \"",{"type":39,"tag":225,"props":267,"children":269},{"style":268},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[270],{"type":44,"value":271},"checkout",{"type":39,"tag":225,"props":273,"children":274},{"style":232},[275],{"type":44,"value":255},{"type":39,"tag":225,"props":277,"children":278},{"style":232},[279],{"type":44,"value":280},",\n",{"type":39,"tag":225,"props":282,"children":284},{"class":227,"line":283},3,[285,289,294,298,302,306,311,315],{"type":39,"tag":225,"props":286,"children":287},{"style":232},[288],{"type":44,"value":244},{"type":39,"tag":225,"props":290,"children":291},{"style":247},[292],{"type":44,"value":293},"lookback",{"type":39,"tag":225,"props":295,"children":296},{"style":232},[297],{"type":44,"value":255},{"type":39,"tag":225,"props":299,"children":300},{"style":232},[301],{"type":44,"value":260},{"type":39,"tag":225,"props":303,"children":304},{"style":232},[305],{"type":44,"value":265},{"type":39,"tag":225,"props":307,"children":308},{"style":268},[309],{"type":44,"value":310},"1h",{"type":39,"tag":225,"props":312,"children":313},{"style":232},[314],{"type":44,"value":255},{"type":39,"tag":225,"props":316,"children":317},{"style":232},[318],{"type":44,"value":280},{"type":39,"tag":225,"props":320,"children":322},{"class":227,"line":321},4,[323,327,332,336,340],{"type":39,"tag":225,"props":324,"children":325},{"style":232},[326],{"type":44,"value":244},{"type":39,"tag":225,"props":328,"children":329},{"style":247},[330],{"type":44,"value":331},"include_health",{"type":39,"tag":225,"props":333,"children":334},{"style":232},[335],{"type":44,"value":255},{"type":39,"tag":225,"props":337,"children":338},{"style":232},[339],{"type":44,"value":260},{"type":39,"tag":225,"props":341,"children":342},{"style":232},[343],{"type":44,"value":344}," true\n",{"type":39,"tag":225,"props":346,"children":348},{"class":227,"line":347},5,[349],{"type":39,"tag":225,"props":350,"children":351},{"style":232},[352],{"type":44,"value":353},"}\n",{"type":39,"tag":202,"props":355,"children":357},{"id":356},"full-graph-mode",[358],{"type":44,"value":359},"Full-graph mode",{"type":39,"tag":47,"props":361,"children":362},{},[363],{"type":44,"value":364},"Use sparingly — only when the user explicitly wants the whole topology, or during initial environment\ndiscovery.",{"type":39,"tag":214,"props":366,"children":368},{"className":216,"code":367,"language":218,"meta":219,"style":219},"{\n  \"lookback\": \"1h\",\n  \"include_health\": false\n}\n",[369],{"type":39,"tag":76,"props":370,"children":371},{"__ignoreMap":219},[372,379,414,438],{"type":39,"tag":225,"props":373,"children":374},{"class":227,"line":228},[375],{"type":39,"tag":225,"props":376,"children":377},{"style":232},[378],{"type":44,"value":235},{"type":39,"tag":225,"props":380,"children":381},{"class":227,"line":238},[382,386,390,394,398,402,406,410],{"type":39,"tag":225,"props":383,"children":384},{"style":232},[385],{"type":44,"value":244},{"type":39,"tag":225,"props":387,"children":388},{"style":247},[389],{"type":44,"value":293},{"type":39,"tag":225,"props":391,"children":392},{"style":232},[393],{"type":44,"value":255},{"type":39,"tag":225,"props":395,"children":396},{"style":232},[397],{"type":44,"value":260},{"type":39,"tag":225,"props":399,"children":400},{"style":232},[401],{"type":44,"value":265},{"type":39,"tag":225,"props":403,"children":404},{"style":268},[405],{"type":44,"value":310},{"type":39,"tag":225,"props":407,"children":408},{"style":232},[409],{"type":44,"value":255},{"type":39,"tag":225,"props":411,"children":412},{"style":232},[413],{"type":44,"value":280},{"type":39,"tag":225,"props":415,"children":416},{"class":227,"line":283},[417,421,425,429,433],{"type":39,"tag":225,"props":418,"children":419},{"style":232},[420],{"type":44,"value":244},{"type":39,"tag":225,"props":422,"children":423},{"style":247},[424],{"type":44,"value":331},{"type":39,"tag":225,"props":426,"children":427},{"style":232},[428],{"type":44,"value":255},{"type":39,"tag":225,"props":430,"children":431},{"style":232},[432],{"type":44,"value":260},{"type":39,"tag":225,"props":434,"children":435},{"style":232},[436],{"type":44,"value":437}," false\n",{"type":39,"tag":225,"props":439,"children":440},{"class":227,"line":321},[441],{"type":39,"tag":225,"props":442,"children":443},{"style":232},[444],{"type":44,"value":353},{"type":39,"tag":47,"props":446,"children":447},{},[448],{"type":44,"value":449},"Parameter-filling guidance:",{"type":39,"tag":60,"props":451,"children":452},{},[453,518,532,573],{"type":39,"tag":64,"props":454,"children":455},{},[456,464,466,472,474,480,482,487,488,494,496,501,503,508,510,516],{"type":39,"tag":68,"props":457,"children":458},{},[459],{"type":39,"tag":76,"props":460,"children":462},{"className":461},[],[463],{"type":44,"value":250},{"type":44,"value":465},": the exact OTel ",{"type":39,"tag":76,"props":467,"children":469},{"className":468},[],[470],{"type":44,"value":471},"service.name",{"type":44,"value":473}," as deployed — typically lowercase and hyphenated for\nmulti-word services (",{"type":39,"tag":76,"props":475,"children":477},{"className":476},[],[478],{"type":44,"value":479},"frontend",{"type":44,"value":481},", ",{"type":39,"tag":76,"props":483,"children":485},{"className":484},[],[486],{"type":44,"value":271},{"type":44,"value":481},{"type":39,"tag":76,"props":489,"children":491},{"className":490},[],[492],{"type":44,"value":493},"product-catalog",{"type":44,"value":495},"). ",{"type":39,"tag":68,"props":497,"children":498},{},[499],{"type":44,"value":500},"Do not concatenate spaces",{"type":44,"value":502}," — if\nthe user says \"checkout service\" pass ",{"type":39,"tag":76,"props":504,"children":506},{"className":505},[],[507],{"type":44,"value":271},{"type":44,"value":509},", not ",{"type":39,"tag":76,"props":511,"children":513},{"className":512},[],[514],{"type":44,"value":515},"checkoutservice",{"type":44,"value":517},". If the name is ambiguous,\nask the user to confirm before calling. If the tool returns no edges for the named focal service,\nconfirm the name with the user before fuzzy-matching.",{"type":39,"tag":64,"props":519,"children":520},{},[521,530],{"type":39,"tag":68,"props":522,"children":523},{},[524],{"type":39,"tag":76,"props":525,"children":527},{"className":526},[],[528],{"type":44,"value":529},"namespace",{"type":44,"value":531},": only if the user scopes to a K8s namespace AND services are K8s-deployed.",{"type":39,"tag":64,"props":533,"children":534},{},[535,543,545,555,557,563,565,571],{"type":39,"tag":68,"props":536,"children":537},{},[538],{"type":39,"tag":76,"props":539,"children":541},{"className":540},[],[542],{"type":44,"value":293},{"type":44,"value":544},": ",{"type":39,"tag":68,"props":546,"children":547},{},[548,550],{"type":44,"value":549},"default ",{"type":39,"tag":76,"props":551,"children":553},{"className":552},[],[554],{"type":44,"value":310},{"type":44,"value":556}," for any unqualified prompt. Don't drop to 15m unless the user explicitly says something time-localized (\"right now \u002F this second\"). Use ",{"type":39,"tag":76,"props":558,"children":560},{"className":559},[],[561],{"type":44,"value":562},"24h",{"type":44,"value":564}," to smooth transient topology changes; use the user's literal window when they give one (\"past 30 minutes\" → ",{"type":39,"tag":76,"props":566,"children":568},{"className":567},[],[569],{"type":44,"value":570},"30m",{"type":44,"value":572},").",{"type":39,"tag":64,"props":574,"children":575},{},[576,584],{"type":39,"tag":68,"props":577,"children":578},{},[579],{"type":39,"tag":76,"props":580,"children":582},{"className":581},[],[583],{"type":44,"value":331},{"type":44,"value":585},": default true. Set false for a topology-only response when you don't need latency\u002Ferror\ndata.",{"type":39,"tag":53,"props":587,"children":589},{"id":588},"after-the-tool-returns",[590],{"type":44,"value":591},"After the tool returns",{"type":39,"tag":47,"props":593,"children":594},{},[595],{"type":44,"value":596},"Response shape:",{"type":39,"tag":60,"props":598,"children":599},{},[600,611,665,691,709],{"type":39,"tag":64,"props":601,"children":602},{},[603,609],{"type":39,"tag":76,"props":604,"children":606},{"className":605},[],[607],{"type":44,"value":608},"services",{"type":44,"value":610},": list of nodes with optional language\u002Fdeployment\u002Fnamespace metadata and health stats.",{"type":39,"tag":64,"props":612,"children":613},{},[614,620,622,628,629,635,636,642,643,649,650,656,657,663],{"type":39,"tag":76,"props":615,"children":617},{"className":616},[],[618],{"type":44,"value":619},"edges",{"type":44,"value":621},": directed edges with ",{"type":39,"tag":76,"props":623,"children":625},{"className":624},[],[626],{"type":44,"value":627},"source",{"type":44,"value":481},{"type":39,"tag":76,"props":630,"children":632},{"className":631},[],[633],{"type":44,"value":634},"target",{"type":44,"value":481},{"type":39,"tag":76,"props":637,"children":639},{"className":638},[],[640],{"type":44,"value":641},"protocol",{"type":44,"value":481},{"type":39,"tag":76,"props":644,"children":646},{"className":645},[],[647],{"type":44,"value":648},"port",{"type":44,"value":481},{"type":39,"tag":76,"props":651,"children":653},{"className":652},[],[654],{"type":44,"value":655},"call_count",{"type":44,"value":481},{"type":39,"tag":76,"props":658,"children":660},{"className":659},[],[661],{"type":44,"value":662},"avg_latency_us",{"type":44,"value":664},".",{"type":39,"tag":64,"props":666,"children":667},{},[668,674,676,682,683,689],{"type":39,"tag":76,"props":669,"children":671},{"className":670},[],[672],{"type":44,"value":673},"focal_service",{"type":44,"value":675}," + ",{"type":39,"tag":76,"props":677,"children":679},{"className":678},[],[680],{"type":44,"value":681},"upstream",{"type":44,"value":675},{"type":39,"tag":76,"props":684,"children":686},{"className":685},[],[687],{"type":44,"value":688},"downstream",{"type":44,"value":690}," (focal mode only).",{"type":39,"tag":64,"props":692,"children":693},{},[694,700,702,708],{"type":39,"tag":76,"props":695,"children":697},{"className":696},[],[698],{"type":44,"value":699},"service_count",{"type":44,"value":701}," \u002F ",{"type":39,"tag":76,"props":703,"children":705},{"className":704},[],[706],{"type":44,"value":707},"edge_count",{"type":44,"value":664},{"type":39,"tag":64,"props":710,"children":711},{},[712,718,720,726],{"type":39,"tag":76,"props":713,"children":715},{"className":714},[],[716],{"type":44,"value":717},"data_coverage_note",{"type":44,"value":719}," (only on focal mode when the focal service has inbound but zero outbound\nedges): flags a likely instrumentation gap — don't claim the service is a ",{"type":39,"tag":76,"props":721,"children":723},{"className":722},[],[724],{"type":44,"value":725},"leaf",{"type":44,"value":727},"; relay the note\nto the user as an advisory.",{"type":39,"tag":47,"props":729,"children":730},{},[731,733,739],{"type":44,"value":732},"Ignore ",{"type":39,"tag":76,"props":734,"children":736},{"className":735},[],[737],{"type":44,"value":738},"_setup_notice",{"type":44,"value":740}," if present — it's view-side chrome (welcome banner) that the UI handles. Don't\necho or summarize it in chat.",{"type":39,"tag":47,"props":742,"children":743},{},[744],{"type":44,"value":745},"Lead your narrative with:",{"type":39,"tag":747,"props":748,"children":749},"ol",{},[750,760,770,780,790],{"type":39,"tag":64,"props":751,"children":752},{},[753,758],{"type":39,"tag":68,"props":754,"children":755},{},[756],{"type":44,"value":757},"Focal service",{"type":44,"value":759},": \"checkoutservice has 3 upstream callers and 5 downstream dependencies.\"",{"type":39,"tag":64,"props":761,"children":762},{},[763,768],{"type":39,"tag":68,"props":764,"children":765},{},[766],{"type":44,"value":767},"Upstream callers",{"type":44,"value":769}," (who depends on this service): name them, note call volumes. Outage here cascades up.",{"type":39,"tag":64,"props":771,"children":772},{},[773,778],{"type":39,"tag":68,"props":774,"children":775},{},[776],{"type":44,"value":777},"Downstream dependencies",{"type":44,"value":779}," (what this service relies on): name them. Problems here cascade in.",{"type":39,"tag":64,"props":781,"children":782},{},[783,788],{"type":39,"tag":68,"props":784,"children":785},{},[786],{"type":44,"value":787},"Hot edges",{"type":44,"value":789},": highest call volume or latency — likely the load-bearing paths.",{"type":39,"tag":64,"props":791,"children":792},{},[793,798,800,805],{"type":39,"tag":68,"props":794,"children":795},{},[796],{"type":44,"value":797},"Follow-ups",{"type":44,"value":799},": suggest ",{"type":39,"tag":76,"props":801,"children":803},{"className":802},[],[804],{"type":44,"value":172},{"type":44,"value":806}," on a specific neighbor if its health shows errors or elevated latency.",{"type":39,"tag":53,"props":808,"children":810},{"id":809},"key-principles",[811],{"type":44,"value":812},"Key principles",{"type":39,"tag":60,"props":814,"children":815},{},[816,826,836,846],{"type":39,"tag":64,"props":817,"children":818},{},[819,824],{"type":39,"tag":68,"props":820,"children":821},{},[822],{"type":44,"value":823},"Prefer focal mode.",{"type":44,"value":825}," The full graph is hard to narrate; a focal subgraph is crisp.",{"type":39,"tag":64,"props":827,"children":828},{},[829,834],{"type":39,"tag":68,"props":830,"children":831},{},[832],{"type":44,"value":833},"Direction matters.",{"type":44,"value":835}," Upstream = who calls me (blast radius goes up). Downstream = what I call (problems\ncascade in). Don't mix them up in explanations.",{"type":39,"tag":64,"props":837,"children":838},{},[839,844],{"type":39,"tag":68,"props":840,"children":841},{},[842],{"type":44,"value":843},"Protocols and ports are clues.",{"type":44,"value":845}," A DNS edge tells you the callee is resolved by name (k8s service?). A\nhigh-port HTTP call to a specific target hints at a sidecar or proxy.",{"type":39,"tag":64,"props":847,"children":848},{},[849,854],{"type":39,"tag":68,"props":850,"children":851},{},[852],{"type":44,"value":853},"Empty or tiny graphs are a signal.",{"type":44,"value":855}," If the focal service has zero edges, either the lookback is too\nnarrow, the service isn't instrumented, or the name is wrong. Do not silently report \"no dependencies.\"",{"type":39,"tag":53,"props":857,"children":859},{"id":858},"investigation-discipline",[860],{"type":44,"value":861},"Investigation discipline",{"type":39,"tag":60,"props":863,"children":864},{},[865,883,900],{"type":39,"tag":64,"props":866,"children":867},{},[868,873,875,881],{"type":39,"tag":68,"props":869,"children":870},{},[871],{"type":44,"value":872},"One tool call per turn.",{"type":44,"value":874}," After this tool returns, narrate what the topology shows — root, leaves, edges with abnormal latency or error rates — ",{"type":39,"tag":876,"props":877,"children":878},"em",{},[879],{"type":44,"value":880},"before",{"type":44,"value":882}," firing another tool. Each call adds a widget to the chat; piling 3-4 in a row after a single \"yes\" looks like a runaway agent.",{"type":39,"tag":64,"props":884,"children":885},{},[886,891,893,898],{"type":39,"tag":68,"props":887,"children":888},{},[889],{"type":44,"value":890},"Sequential offers, not OR.",{"type":44,"value":892}," Don't ask \"Want me to check pod health ",{"type":39,"tag":876,"props":894,"children":895},{},[896],{"type":44,"value":897},"or",{"type":44,"value":899}," ML anomalies?\" — phrase as a chain: \"Want me to start with X? If that doesn't explain it, I can follow up with Y.\" The user's \"yes\" then maps to one call, not several.",{"type":39,"tag":64,"props":901,"children":902},{},[903,908],{"type":39,"tag":68,"props":904,"children":905},{},[906],{"type":44,"value":907},"Commit to a plan before \"yes.\"",{"type":44,"value":909}," When a follow-up needs multiple tools (e.g. flagd pod resources → flagd traces → upstream caller anomalies), lay out the chain first and execute one step at a time, narrating between each. Don't pre-fire the chain because the user agreed in principle.",{"type":39,"tag":911,"props":912,"children":913},"style",{},[914],{"type":44,"value":915},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":917,"total":991},[918,928,935,949,964,978],{"slug":155,"name":155,"fn":919,"description":920,"org":921,"tags":922,"stars":23,"repoUrl":24,"updatedAt":927},"summarize Elastic APM service health","Get a cluster-level rollup of service health from APM telemetry — the \"how's my environment right now?\" entry point for observability investigations. Use whenever the user asks about HEALTH, STATUS, or general wellbeing of an environment \u002F cluster \u002F namespace (\"how's my cluster\", \"status of the X env\", \"what's broken\", \"any issues\", \"show me the health of …\", \"give me a status report\", \"what should I look at\", \"things feel slow\"). This applies regardless of any time qualifier — \"show me the health of X over the past hour\" still routes here (with lookback=\"1h\"), NOT to observe. observe is for raw-metric queries; this tool is for the rollup. Gracefully degrades: layers in Kubernetes pod data and ML anomaly context when those backends are present, but still returns useful APM-only output if they aren't. Do not use for log-only or metrics-only customers — this tool requires Elastic APM.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[923,924,925,926],{"name":20,"slug":21,"type":15},{"name":9,"slug":8,"type":15},{"name":17,"slug":18,"type":15},{"name":13,"slug":14,"type":15},"2026-07-12T07:49:24.405551",{"slug":4,"name":4,"fn":5,"description":6,"org":929,"tags":930,"stars":23,"repoUrl":24,"updatedAt":25},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[931,932,933,934],{"name":20,"slug":21,"type":15},{"name":9,"slug":8,"type":15},{"name":17,"slug":18,"type":15},{"name":13,"slug":14,"type":15},{"slug":189,"name":189,"fn":936,"description":937,"org":938,"tags":939,"stars":23,"repoUrl":24,"updatedAt":948},"assess Kubernetes node failure impact","Assess the impact of a Kubernetes node going offline — which deployments lose all replicas (full outage), which lose partial capacity (degraded), which are unaffected, and whether the cluster has enough spare capacity to reschedule the lost pods. Use when the user asks \"what happens if node X goes down\", \"what's the blast radius of draining this node\", \"can I safely maintain node Y\", \"what's running on this node\", \"if I evict this node what breaks\", or is planning node maintenance, a cluster upgrade, or investigating an actual node failure. Requires Kubernetes (kubeletstats metrics) and Elastic APM for downstream service impact — do not trigger for non-K8s deployments.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[940,941,944,945],{"name":9,"slug":8,"type":15},{"name":942,"slug":943,"type":15},"Kubernetes","kubernetes",{"name":13,"slug":14,"type":15},{"name":946,"slug":947,"type":15},"Risk Assessment","risk-assessment","2026-07-12T07:49:25.645103",{"slug":950,"name":950,"fn":951,"description":952,"org":953,"tags":954,"stars":23,"repoUrl":24,"updatedAt":963},"manage-alerts","manage Kibana alerting rules","CRUD for Kibana alerting rules — create, list, get, or delete custom-threshold rules. Use when the user says \"alert me when\", \"create a rule for\", \"page me if\", \"set up an alert\", \"show me my rules\", \"what alerts do I have\", \"delete that alert\", \"remove the rule\". Backend-agnostic — works on any metric field in any index pattern (metrics-*, logs-*, traces-apm*, custom). For transient session-scoped monitoring use `observe` instead. Requires Kibana with the Alerting feature enabled — the tool is auto-disabled when no Kibana URL is configured.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[955,958,959,962],{"name":956,"slug":957,"type":15},"Alerting","alerting",{"name":9,"slug":8,"type":15},{"name":960,"slug":961,"type":15},"Kibana","kibana",{"name":17,"slug":18,"type":15},"2026-07-12T07:49:21.846108",{"slug":172,"name":172,"fn":965,"description":966,"org":967,"tags":968,"stars":23,"repoUrl":24,"updatedAt":977},"query Elastic ML anomaly detection results","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\u002Fspiking\", \"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.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[969,972,973,976],{"name":970,"slug":971,"type":15},"Anomaly Detection","anomaly-detection",{"name":9,"slug":8,"type":15},{"name":974,"slug":975,"type":15},"Machine Learning","machine-learning",{"name":13,"slug":14,"type":15},"2026-07-12T07:49:26.869446",{"slug":979,"name":979,"fn":980,"description":981,"org":982,"tags":983,"stars":23,"repoUrl":24,"updatedAt":990},"observe","monitor Elastic observability telemetry","The agent's Elastic-access primitive. Four modes: wait for an ML anomaly to fire, poll an ES|QL metric (live-sample or wait for a threshold), read a single-instance scalar value, or return a full ES|QL table. Use when the user says \"tell me when...\", \"let me know if...\", \"wait until X drops below Y\", \"watch for anything unusual\", \"monitor for the next N minutes\", \"poll until stable\", \"what is X right now\", \"list …\", \"which … are …\", or wants transient (session-scoped) monitoring or ad-hoc querying without creating a persistent Kibana rule. Also trigger for \"keep an eye on\" and post-remediation validation.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[984,985,988,989],{"name":9,"slug":8,"type":15},{"name":986,"slug":987,"type":15},"Metrics","metrics",{"name":17,"slug":18,"type":15},{"name":13,"slug":14,"type":15},"2026-07-12T07:49:28.114697",6,{"items":993,"total":1165},[994,1013,1030,1045,1064,1076,1086,1101,1113,1128,1139,1152],{"slug":995,"name":995,"fn":996,"description":997,"org":998,"tags":999,"stars":1010,"repoUrl":1011,"updatedAt":1012},"accessing-benchmark-results","retrieve and analyze Rally benchmark results","Retrieve Rally benchmark results from an external Elasticsearch metrics store. Use to list past races, get a single race's overall (per-task) results, chart a metric's trend across multiple runs, compare two races, or check whether a run converged — e.g. \"show me recent geonames races\", \"what's the service_time trend for nyc_taxis over the last 30 days?\", \"compare these two race-ids\". Applies when datastore.type = elasticsearch is set in ~\u002F.rally\u002Frally.ini.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1000,1003,1006,1007],{"name":1001,"slug":1002,"type":15},"Analytics","analytics",{"name":1004,"slug":1005,"type":15},"Data Analysis","data-analysis",{"name":9,"slug":8,"type":15},{"name":1008,"slug":1009,"type":15},"Performance","performance",2027,"https:\u002F\u002Fgithub.com\u002Felastic\u002Frally","2026-07-12T07:46:38.54144",{"slug":1014,"name":1014,"fn":1015,"description":1016,"org":1017,"tags":1018,"stars":1010,"repoUrl":1011,"updatedAt":1029},"developing-rally","develop and debug Rally source code","Work on Rally's own codebase, not running benchmarks with it. Use when setting up the dev environment, running Rally's tests or linters, navigating its source, debugging Rally's own code, or making changes to Rally itself.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1019,1022,1023,1026],{"name":1020,"slug":1021,"type":15},"Debugging","debugging",{"name":9,"slug":8,"type":15},{"name":1024,"slug":1025,"type":15},"Engineering","engineering",{"name":1027,"slug":1028,"type":15},"Local Development","local-development","2026-07-12T07:46:35.976807",{"slug":1031,"name":1031,"fn":1032,"description":1033,"org":1034,"tags":1035,"stars":1010,"repoUrl":1011,"updatedAt":1044},"running-benchmarks","run Rally benchmarks against Elasticsearch","Run Rally benchmarks (races) against Elasticsearch — an existing\u002Fexternal cluster or a Rally-provisioned distribution — and read the summary report. Use when running a race (any pipeline, track, challenge, target-hosts, or auth) or when interpreting throughput, latency, and service_time results.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1036,1037,1040,1041],{"name":9,"slug":8,"type":15},{"name":1038,"slug":1039,"type":15},"Elasticsearch","elasticsearch",{"name":1008,"slug":1009,"type":15},{"name":1042,"slug":1043,"type":15},"Testing","testing","2026-07-12T07:46:37.277964",{"slug":1046,"name":1046,"fn":1047,"description":1048,"org":1049,"tags":1050,"stars":1061,"repoUrl":1062,"updatedAt":1063},"cloud-access-management","manage Elastic Cloud organization access","Manage Elastic Cloud organization access: invite users, assign roles to Serverless projects, and create or revoke Cloud API keys. Use when granting, modifying, or auditing user access.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1051,1054,1055,1058],{"name":1052,"slug":1053,"type":15},"Cloud","cloud",{"name":9,"slug":8,"type":15},{"name":1056,"slug":1057,"type":15},"Operations","operations",{"name":1059,"slug":1060,"type":15},"Permissions","permissions",531,"https:\u002F\u002Fgithub.com\u002Felastic\u002Fagent-skills","2026-07-12T07:46:44.946285",{"slug":1065,"name":1065,"fn":1066,"description":1067,"org":1068,"tags":1069,"stars":1061,"repoUrl":1062,"updatedAt":1075},"cloud-create-project","create Elastic Cloud Serverless projects","Creates Elastic Cloud Serverless projects (Elasticsearch, Observability, or Security) via the REST API, saves credentials to file, and bootstraps a scoped Elasticsearch API key. Use when creating a new serverless project, provisioning a search or observability environment, or spinning up a new Elastic Cloud project.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1070,1071,1074],{"name":1052,"slug":1053,"type":15},{"name":1072,"slug":1073,"type":15},"Deployment","deployment",{"name":1038,"slug":1039,"type":15},"2026-07-12T07:46:42.353362",{"slug":1077,"name":1077,"fn":1078,"description":1079,"org":1080,"tags":1081,"stars":1061,"repoUrl":1062,"updatedAt":1085},"cloud-manage-project","manage Elastic Cloud Serverless projects","Manages existing Elastic Cloud Serverless projects: list, get, update, delete, reset credentials, resume, and load saved credentials. Connects to existing projects by resolving endpoints and acquiring scoped Elasticsearch API keys. Use when performing day-2 operations on serverless projects, connecting to an existing project, loading or resetting project credentials, or looking up project details.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1082,1083,1084],{"name":1052,"slug":1053,"type":15},{"name":1038,"slug":1039,"type":15},{"name":1056,"slug":1057,"type":15},"2026-07-12T07:46:41.097412",{"slug":1087,"name":1087,"fn":1088,"description":1089,"org":1090,"tags":1091,"stars":1061,"repoUrl":1062,"updatedAt":1100},"cloud-network-security","manage Elastic Cloud network security","Manage Serverless network security (traffic filters): create, update, and delete IP filters and AWS PrivateLink VPC filters. Use when restricting network access or configuring private connectivity.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1092,1093,1094,1097],{"name":1052,"slug":1053,"type":15},{"name":1038,"slug":1039,"type":15},{"name":1095,"slug":1096,"type":15},"Networking","networking",{"name":1098,"slug":1099,"type":15},"Security","security","2026-07-12T07:46:43.675992",{"slug":1102,"name":1102,"fn":1103,"description":1104,"org":1105,"tags":1106,"stars":1061,"repoUrl":1062,"updatedAt":1112},"cloud-setup","configure Elastic Cloud authentication","Configures Elastic Cloud authentication and environment defaults. Use when setting up EC_API_KEY, configuring Cloud API access, or when another cloud skill requires credentials.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1107,1110,1111],{"name":1108,"slug":1109,"type":15},"Authentication","authentication",{"name":1052,"slug":1053,"type":15},{"name":1038,"slug":1039,"type":15},"2026-07-12T07:46:39.783105",{"slug":1114,"name":1114,"fn":1115,"description":1116,"org":1117,"tags":1118,"stars":1061,"repoUrl":1062,"updatedAt":1127},"elasticsearch-audit","configure Elasticsearch security audit logs","Enable, configure, and query Elasticsearch security audit logs. Use when the task involves audit logging setup, event filtering, or investigating security incidents like failed logins.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1119,1122,1123,1126],{"name":1120,"slug":1121,"type":15},"Audit","audit",{"name":1038,"slug":1039,"type":15},{"name":1124,"slug":1125,"type":15},"Logs","logs",{"name":1098,"slug":1099,"type":15},"2026-07-12T07:47:35.092599",{"slug":1129,"name":1129,"fn":1130,"description":1131,"org":1132,"tags":1133,"stars":1061,"repoUrl":1062,"updatedAt":1138},"elasticsearch-authn","configure Elasticsearch authentication realms","Authenticate to Elasticsearch using native, file-based, LDAP\u002FAD, SAML, OIDC, Kerberos, JWT, or certificate realms. Use when connecting with credentials, choosing a realm, or managing API keys. Assumes the target realms are already configured.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1134,1135,1136,1137],{"name":1108,"slug":1109,"type":15},{"name":9,"slug":8,"type":15},{"name":1038,"slug":1039,"type":15},{"name":1098,"slug":1099,"type":15},"2026-07-12T07:47:41.474547",{"slug":1140,"name":1140,"fn":1141,"description":1142,"org":1143,"tags":1144,"stars":1061,"repoUrl":1062,"updatedAt":1151},"elasticsearch-authz","manage Elasticsearch RBAC and security roles","Manage Elasticsearch RBAC: native users, roles, role mappings, document- and field-level security. Use when creating users or roles, assigning privileges, or mapping external realms like LDAP\u002FSAML.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1145,1146,1147,1150],{"name":9,"slug":8,"type":15},{"name":1038,"slug":1039,"type":15},{"name":1148,"slug":1149,"type":15},"RBAC","rbac",{"name":1098,"slug":1099,"type":15},"2026-07-12T07:47:36.394177",{"slug":1153,"name":1153,"fn":1154,"description":1155,"org":1156,"tags":1157,"stars":1061,"repoUrl":1062,"updatedAt":1164},"elasticsearch-esql","query Elasticsearch data with ES|QL","Execute ES|QL (Elasticsearch Query Language) queries, use when the user wants to query Elasticsearch data, analyze logs, aggregate metrics, explore data, or create charts and dashboards from ES|QL results.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1158,1159,1160,1161],{"name":1001,"slug":1002,"type":15},{"name":1004,"slug":1005,"type":15},{"name":1038,"slug":1039,"type":15},{"name":1162,"slug":1163,"type":15},"SQL","sql","2026-07-12T07:47:40.249533",86]